locomotivecms_builder 1.0.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. data/.gitignore +31 -0
  2. data/Gemfile +8 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +68 -0
  5. data/Rakefile +47 -0
  6. data/TODO +57 -0
  7. data/bin/builder +9 -0
  8. data/generators/blank/Gemfile.tt +20 -0
  9. data/generators/blank/app/content_types/.empty_directory +1 -0
  10. data/generators/blank/app/views/pages/404.liquid +11 -0
  11. data/generators/blank/app/views/pages/index.liquid +19 -0
  12. data/generators/blank/app/views/snippets/.empty_directory +1 -0
  13. data/generators/blank/config/deploy.yml +12 -0
  14. data/generators/blank/config/site.yml.tt +16 -0
  15. data/generators/blank/config/translations.yml +8 -0
  16. data/generators/blank/config.ru +3 -0
  17. data/generators/blank/data/.empty_directory +1 -0
  18. data/generators/blank/public/fonts/.empty_directory +1 -0
  19. data/generators/blank/public/images/.empty_directory +1 -0
  20. data/generators/blank/public/javascripts/.empty_directory +1 -0
  21. data/generators/blank/public/samples/.empty_directory +1 -0
  22. data/generators/blank/public/stylesheets/.empty_directory +1 -0
  23. data/generators/bootstrap/Gemfile.tt +20 -0
  24. data/generators/bootstrap/app/content_types/.empty_directory +1 -0
  25. data/generators/bootstrap/app/views/pages/404.liquid +13 -0
  26. data/generators/bootstrap/app/views/pages/404.liquid.haml +10 -0
  27. data/generators/bootstrap/app/views/pages/index.liquid +85 -0
  28. data/generators/bootstrap/app/views/pages/index.liquid.haml +72 -0
  29. data/generators/bootstrap/app/views/snippets/footer.liquid +3 -0
  30. data/generators/bootstrap/app/views/snippets/footer.liquid.haml +2 -0
  31. data/generators/bootstrap/config/deploy.yml +12 -0
  32. data/generators/bootstrap/config/site.yml.tt +16 -0
  33. data/generators/bootstrap/config/translations.yml +8 -0
  34. data/generators/bootstrap/config.ru +3 -0
  35. data/generators/bootstrap/data/.empty_directory +1 -0
  36. data/generators/bootstrap/public/fonts/FontAwesome.otf +0 -0
  37. data/generators/bootstrap/public/fonts/font-awesome-ie7.min.css +23 -0
  38. data/generators/bootstrap/public/fonts/font-awesome.css +469 -0
  39. data/generators/bootstrap/public/fonts/font-awesome.min.css +34 -0
  40. data/generators/bootstrap/public/fonts/fontawesome-webfont.eot +0 -0
  41. data/generators/bootstrap/public/fonts/fontawesome-webfont.ttf +0 -0
  42. data/generators/bootstrap/public/fonts/fontawesome-webfont.woff +0 -0
  43. data/generators/bootstrap/public/javascripts/bootstrap.js +2159 -0
  44. data/generators/bootstrap/public/javascripts/bootstrap.min.js +6 -0
  45. data/generators/bootstrap/public/samples/.empty_directory +1 -0
  46. data/generators/bootstrap/public/stylesheets/application.css.scss +39 -0
  47. data/generators/bootstrap/public/stylesheets/bootstrap-responsive.css +1092 -0
  48. data/generators/bootstrap/public/stylesheets/bootstrap-responsive.min.css +9 -0
  49. data/generators/bootstrap/public/stylesheets/bootstrap.css +5652 -0
  50. data/generators/bootstrap/public/stylesheets/bootstrap.min.css +726 -0
  51. data/generators/content_type/app/content_types/%name%.yml.tt +58 -0
  52. data/generators/content_type/data/%name%.yml.tt +24 -0
  53. data/generators/page/template.liquid.haml.tt +35 -0
  54. data/generators/page/template.liquid.tt +1 -0
  55. data/generators/snippet/template.liquid.haml.tt +4 -0
  56. data/generators/snippet/template.liquid.tt +4 -0
  57. data/lib/locomotive/builder/cli.rb +225 -0
  58. data/lib/locomotive/builder/exceptions.rb +17 -0
  59. data/lib/locomotive/builder/generators/content_type.rb +47 -0
  60. data/lib/locomotive/builder/generators/page.rb +57 -0
  61. data/lib/locomotive/builder/generators/site/base.rb +30 -0
  62. data/lib/locomotive/builder/generators/site/blank.rb +23 -0
  63. data/lib/locomotive/builder/generators/site/bootstrap.rb +35 -0
  64. data/lib/locomotive/builder/generators/site.rb +97 -0
  65. data/lib/locomotive/builder/generators/snippet.rb +54 -0
  66. data/lib/locomotive/builder/liquid/drops/base.rb +44 -0
  67. data/lib/locomotive/builder/liquid/drops/content_entry.rb +48 -0
  68. data/lib/locomotive/builder/liquid/drops/content_types.rb +121 -0
  69. data/lib/locomotive/builder/liquid/drops/page.rb +36 -0
  70. data/lib/locomotive/builder/liquid/drops/site.rb +21 -0
  71. data/lib/locomotive/builder/liquid/errors.rb +7 -0
  72. data/lib/locomotive/builder/liquid/filters/date.rb +98 -0
  73. data/lib/locomotive/builder/liquid/filters/html.rb +154 -0
  74. data/lib/locomotive/builder/liquid/filters/misc.rb +28 -0
  75. data/lib/locomotive/builder/liquid/filters/resize.rb +18 -0
  76. data/lib/locomotive/builder/liquid/filters/text.rb +50 -0
  77. data/lib/locomotive/builder/liquid/filters/translate.rb +24 -0
  78. data/lib/locomotive/builder/liquid/patches.rb +47 -0
  79. data/lib/locomotive/builder/liquid/tags/consume.rb +58 -0
  80. data/lib/locomotive/builder/liquid/tags/csrf.rb +34 -0
  81. data/lib/locomotive/builder/liquid/tags/editable/base.rb +46 -0
  82. data/lib/locomotive/builder/liquid/tags/editable/control.rb +19 -0
  83. data/lib/locomotive/builder/liquid/tags/editable/file.rb +15 -0
  84. data/lib/locomotive/builder/liquid/tags/editable/long_text.rb +15 -0
  85. data/lib/locomotive/builder/liquid/tags/editable/short_text.rb +15 -0
  86. data/lib/locomotive/builder/liquid/tags/editable.rb +5 -0
  87. data/lib/locomotive/builder/liquid/tags/extends.rb +25 -0
  88. data/lib/locomotive/builder/liquid/tags/google_analytics.rb +28 -0
  89. data/lib/locomotive/builder/liquid/tags/inline_editor.rb +16 -0
  90. data/lib/locomotive/builder/liquid/tags/locale_switcher.rb +180 -0
  91. data/lib/locomotive/builder/liquid/tags/nav.rb +167 -0
  92. data/lib/locomotive/builder/liquid/tags/paginate.rb +105 -0
  93. data/lib/locomotive/builder/liquid/tags/seo.rb +74 -0
  94. data/lib/locomotive/builder/liquid/tags/snippet.rb +42 -0
  95. data/lib/locomotive/builder/liquid/tags/with_scope.rb +43 -0
  96. data/lib/locomotive/builder/liquid.rb +19 -0
  97. data/lib/locomotive/builder/listen.rb +48 -0
  98. data/lib/locomotive/builder/misc/core_ext.rb +29 -0
  99. data/lib/locomotive/builder/misc/dragonfly.rb +82 -0
  100. data/lib/locomotive/builder/misc/httparty.rb +47 -0
  101. data/lib/locomotive/builder/misc/i18n.rb +2 -0
  102. data/lib/locomotive/builder/misc/will_paginate.rb +16 -0
  103. data/lib/locomotive/builder/misc.rb +5 -0
  104. data/lib/locomotive/builder/server/dynamic_assets.rb +31 -0
  105. data/lib/locomotive/builder/server/entry_submission.rb +116 -0
  106. data/lib/locomotive/builder/server/favicon.rb +17 -0
  107. data/lib/locomotive/builder/server/locale.rb +42 -0
  108. data/lib/locomotive/builder/server/middleware.rb +54 -0
  109. data/lib/locomotive/builder/server/not_found.rb +18 -0
  110. data/lib/locomotive/builder/server/page.rb +59 -0
  111. data/lib/locomotive/builder/server/path.rb +34 -0
  112. data/lib/locomotive/builder/server/renderer.rb +105 -0
  113. data/lib/locomotive/builder/server/templatized_page.rb +32 -0
  114. data/lib/locomotive/builder/server.rb +78 -0
  115. data/lib/locomotive/builder/standalone_server.rb +33 -0
  116. data/lib/locomotive/builder/version.rb +5 -0
  117. data/lib/locomotive/builder.rb +167 -0
  118. data/locales/de.yml +143 -0
  119. data/locales/en.yml +164 -0
  120. data/locales/es.yml +119 -0
  121. data/locales/et.yml +140 -0
  122. data/locales/fr.yml +133 -0
  123. data/locales/it.yml +141 -0
  124. data/locales/nb.yml +177 -0
  125. data/locales/nl.yml +148 -0
  126. data/locales/pl.yml +189 -0
  127. data/locales/pt-BR.yml +125 -0
  128. data/locales/ru.yml +210 -0
  129. data/locomotivecms_builder.gemspec +42 -0
  130. data/spec/integration/cassettes/pull.yml +590 -0
  131. data/spec/integration/cassettes/push.yml +775 -0
  132. data/spec/integration/integration_helper.rb +15 -0
  133. data/spec/integration/server_spec.rb +37 -0
  134. data/spec/integration/sites_spec.rb +27 -0
  135. data/spec/spec_helper.rb +12 -0
  136. data/spec/support/helpers.rb +13 -0
  137. metadata +468 -0
@@ -0,0 +1,167 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Tags
5
+ # Display the children pages of the site, current page or the parent page. If not precised, nav is applied on the current page.
6
+ # The html output is based on the ul/li tags.
7
+ #
8
+ # Usage:
9
+ #
10
+ # {% nav site %} => <ul class="nav"><li class="on"><a href="/features">Features</a></li></ul>
11
+ #
12
+ # {% nav site, no_wrapper: true, exclude: 'contact|about', id: 'main-nav', class: 'nav', active_class: 'on' }
13
+ #
14
+ class Nav < ::Liquid::Tag
15
+
16
+ Syntax = /(#{::Liquid::Expression}+)?/
17
+
18
+ attr_accessor :current_page, :mounting_point
19
+
20
+ def initialize(tag_name, markup, tokens, context)
21
+ if markup =~ Syntax
22
+ @source = ($1 || 'page').gsub(/"|'/, '')
23
+ @options = { :id => 'nav', :class => '', :active_class => 'on', :bootstrap => false }
24
+ markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/"|'/, '') }
25
+
26
+ @options[:exclude] = Regexp.new(@options[:exclude]) if @options[:exclude]
27
+
28
+ if @options[:snippet]
29
+ if template = self.parse_snippet_template(context, @options[:snippet])
30
+ @options[:liquid_render] = template
31
+ end
32
+ end
33
+ else
34
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'nav' - Valid syntax: nav <site|parent|page|<path to a page>> <options>")
35
+ end
36
+
37
+ super
38
+ end
39
+
40
+ def render(context)
41
+ self.set_accessors_from_context(context)
42
+
43
+ children_output = []
44
+
45
+ entries = self.fetch_entries
46
+
47
+ entries.each_with_index do |p, index|
48
+ css = []
49
+ css << 'first' if index == 0
50
+ css << 'last' if index == entries.size - 1
51
+
52
+ children_output << render_entry_link(p, css.join(' '), 1)
53
+ end
54
+
55
+ output = children_output.join("\n")
56
+
57
+ if @options[:no_wrapper] != 'true'
58
+ output = %{<ul id="#{@options[:id]}" class="#{@options[:class]}">\n#{output}</ul>}
59
+ end
60
+
61
+ output
62
+ end
63
+
64
+ protected
65
+
66
+ def set_accessors_from_context(context)
67
+ self.current_page = context.registers[:page]
68
+ self.mounting_point = context.registers[:mounting_point]
69
+ end
70
+
71
+ def parse_snippet_template(context, template_name)
72
+ source = if template_name.include?('{')
73
+ template_name
74
+ else
75
+ context[:mounting_point].snippets[template_name].try(:source)
76
+ end
77
+
78
+ source ? ::Liquid::Template.parse(source) : nil
79
+ end
80
+
81
+ def fetch_entries
82
+ children = (case @source
83
+ when 'site' then self.mounting_point.pages['index']
84
+ when 'parent' then self.current_page.parent || self.current_page
85
+ when 'page' then self.current_page
86
+ else
87
+ self.mounting_point.pages[@source]
88
+ end).children.clone
89
+
90
+ children.delete_if { |p| !include_page?(p) }
91
+ end
92
+
93
+ # Determines whether or not a page should be a part of the menu
94
+ def include_page?(page)
95
+ if !page.listed? || page.templatized? || !page.published?
96
+ false
97
+ elsif @options[:exclude]
98
+ (page.fullpath =~ @options[:exclude]).nil?
99
+ else
100
+ true
101
+ end
102
+ end
103
+
104
+ # Returns a list element, a link to the page and its children
105
+ def render_entry_link(page, css, depth)
106
+ selected = self.current_page.fullpath =~ /^#{page.fullpath}/ ? " #{@options[:active_class]}" : ''
107
+
108
+ icon = @options[:icon] ? '<span></span>' : ''
109
+
110
+ title = @options[:liquid_render] ? @options[:liquid_render].render('page' => page) : page.title
111
+
112
+ label = %{#{icon if @options[:icon] != 'after' }#{title}#{icon if @options[:icon] == 'after' }}
113
+
114
+ dropdow = ""
115
+ link_options = ""
116
+ href = ::I18n.locale.to_s == self.mounting_point.default_locale.to_s ? "/#{page.fullpath}" : "/#{::I18n.locale}/#{page.fullpath}"
117
+ caret = ""
118
+
119
+ if render_children_for_page?(page, depth) && bootstrap?
120
+ dropdow = "dropdown"
121
+ link_options = %{class="dropdown-toggle" data-toggle="dropdown"}
122
+ href = "#"
123
+ caret = %{<b class="caret"></b>}
124
+ end
125
+
126
+ output = %{<li id="#{page.slug.to_s.dasherize}-link" class="link#{selected} #{css} #{dropdow}">}
127
+ output << %{<a href="#{href}" #{link_options}>#{label} #{caret}</a>}
128
+ output << render_entry_children(page, depth.succ) if (depth.succ <= @options[:depth].to_i)
129
+ output << %{</li>}
130
+
131
+ output.strip
132
+ end
133
+
134
+ def render_children_for_page?(page, depth)
135
+ depth.succ <= @options[:depth].to_i && page.children.reject { |c| !include_page?(c) }.any?
136
+ end
137
+
138
+ # Recursively creates a nested unordered list for the depth specified
139
+ def render_entry_children(page, depth)
140
+ output = %{}
141
+
142
+ children = page.children.reject { |c| !include_page?(c) }
143
+ if children.present?
144
+ output = %{<ul id="#{@options[:id]}-#{page.slug.to_s.dasherize}" class="#{bootstrap? ? "dropdown-menu" : ""}">}
145
+ children.each do |c, page|
146
+ css = []
147
+ css << 'first' if children.first == c
148
+ css << 'last' if children.last == c
149
+
150
+ output << render_entry_link(c, css.join(' '),depth)
151
+ end
152
+ output << %{</ul>}
153
+ end
154
+
155
+ output
156
+ end
157
+
158
+ def bootstrap?
159
+ @options[:bootstrap] == 'true' || @options[:bootstrap] == true
160
+ end
161
+
162
+ ::Liquid::Template.register_tag('nav', Nav)
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,105 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Tags
5
+
6
+ # Paginate a collection
7
+ #
8
+ # Usage:
9
+ #
10
+ # {% paginate contents.projects by 5 %}
11
+ # {% for project in paginate.collection %}
12
+ # {{ project.name }}
13
+ # {% endfor %}
14
+ # {% endpaginate %}
15
+ #
16
+
17
+ class Paginate < ::Liquid::Block
18
+
19
+ Syntax = /(#{::Liquid::Expression}+)\s+by\s+([0-9]+)/
20
+
21
+ def initialize(tag_name, markup, tokens, context)
22
+ if markup =~ Syntax
23
+ @collection_name = $1
24
+ @per_page = $2.to_i
25
+ else
26
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'paginate' - Valid syntax: paginate <collection> by <number>")
27
+ end
28
+
29
+ super
30
+ end
31
+
32
+ def render(context)
33
+ context.stack do
34
+ collection = context[@collection_name]
35
+
36
+ raise ::Liquid::ArgumentError.new("Cannot paginate array '#{@collection_name}'. Not found.") if collection.nil?
37
+
38
+ pagination = collection.send(:paginate, {
39
+ :page => context['current_page'],
40
+ :per_page => @per_page }).stringify_keys!
41
+
42
+ page_count, current_page = pagination['total_pages'], pagination['current_page']
43
+
44
+ path = sanitize_path(context['fullpath'])
45
+
46
+ pagination['previous'] = link(I18n.t('pagination.previous'), current_page - 1, path) if pagination['previous_page']
47
+ pagination['next'] = link(I18n.t('pagination.next'), current_page + 1, path) if pagination['next_page']
48
+ pagination['parts'] = []
49
+
50
+ hellip_break = false
51
+
52
+ if page_count > 1
53
+ 1.upto(page_count) do |page|
54
+ if current_page == page
55
+ pagination['parts'] << no_link(page)
56
+ elsif page == 1
57
+ pagination['parts'] << link(page, page, path)
58
+ elsif page == page_count - 1
59
+ pagination['parts'] << link(page, page, path)
60
+ elsif page <= current_page - window_size or page >= current_page + window_size
61
+ next if hellip_break
62
+ pagination['parts'] << no_link('&hellip;')
63
+ hellip_break = true
64
+ next
65
+ else
66
+ pagination['parts'] << link(page, page, path)
67
+ end
68
+
69
+ hellip_break = false
70
+ end
71
+ end
72
+
73
+ context['paginate'] = pagination
74
+
75
+ render_all(@nodelist, context)
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def sanitize_path(path)
82
+ _path = path.gsub(/page=[0-9]+&?/, '').gsub(/_pjax=true&?/, '')
83
+ _path = _path.slice(0..-2) if _path.last == '?' || _path.last == '&'
84
+ _path
85
+ end
86
+
87
+ def window_size
88
+ 3
89
+ end
90
+
91
+ def no_link(title)
92
+ { 'title' => title, 'is_link' => false, 'hellip_break' => title == '&hellip;' }
93
+ end
94
+
95
+ def link(title, page, path)
96
+ _path = %(#{path}#{path.include?('?') ? '&' : '?'}page=#{page})
97
+ { 'title' => title, 'url' => _path, 'is_link' => true }
98
+ end
99
+ end
100
+
101
+ ::Liquid::Template.register_tag('paginate', Paginate)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,74 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Tags
5
+ module SEO
6
+
7
+ class Base < ::Liquid::Tag
8
+
9
+ def render(context)
10
+ %{
11
+ #{self.render_title(context)}
12
+ #{self.render_metadata(context)}
13
+ }
14
+ end
15
+
16
+ protected
17
+
18
+ def render_title(context)
19
+ title = self.value_for(:seo_title, context)
20
+ title = context.registers[:site].name if title.blank?
21
+
22
+ %{
23
+ <title>#{title}</title>
24
+ }
25
+ end
26
+
27
+ def render_metadata(context)
28
+ %{
29
+ <meta name="description" content="#{self.value_for(:meta_description, context)}" />
30
+ <meta name="keywords" content="#{self.value_for(:meta_keywords, context)}" />
31
+ }
32
+ end
33
+
34
+ # Removes whitespace and quote characters from the input
35
+ def sanitized_string(string)
36
+ string ? string.strip.gsub(/"/, '') : ''
37
+ end
38
+
39
+ def value_for(attribute, context)
40
+ object = self.metadata_object(context)
41
+ value = object.try(attribute.to_sym).blank? ? context.registers[:site].send(attribute.to_sym) : object.send(attribute.to_sym)
42
+ self.sanitized_string(value)
43
+ end
44
+
45
+ def metadata_object(context)
46
+ context['content_instance'] || context['page']
47
+ end
48
+ end
49
+
50
+ class Title < Base
51
+
52
+ def render(context)
53
+ self.render_title(context)
54
+ end
55
+
56
+ end
57
+
58
+ class Metadata < Base
59
+
60
+ def render(context)
61
+ self.render_metadata(context)
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ ::Liquid::Template.register_tag('seo', SEO::Base)
69
+ ::Liquid::Template.register_tag('seo_title', SEO::Title)
70
+ ::Liquid::Template.register_tag('seo_metadata', SEO::Metadata)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,42 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Tags
5
+
6
+ class Snippet < ::Liquid::Include
7
+
8
+ def render(context)
9
+ name = @template_name.gsub(/[\"\']/, '')
10
+
11
+ source = context.registers[:mounting_point].snippets[name].try(:source)
12
+
13
+ partial = ::Liquid::Template.parse(source)
14
+
15
+ variable = context[@variable_name || @template_name[1..-2]]
16
+
17
+ context.stack do
18
+ @attributes.each do |key, value|
19
+ context[key] = context[value]
20
+ end
21
+
22
+ output = (if variable.is_a?(Array)
23
+ variable.collect do |variable|
24
+ context[@template_name[1..-2]] = variable
25
+ partial.render(context)
26
+ end
27
+ else
28
+ context[@template_name[1..-2]] = variable
29
+ partial.render(context)
30
+ end)
31
+
32
+ output
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ ::Liquid::Template.register_tag('include', Snippet)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Tags
5
+ class WithScope < ::Liquid::Block
6
+
7
+ def initialize(tag_name, markup, tokens, context)
8
+ @options = {}
9
+
10
+ markup.scan(::Liquid::TagAttributes) do |key, value|
11
+ @options[key] = value
12
+ end
13
+
14
+ super
15
+ end
16
+
17
+ def render(context)
18
+ context.stack do
19
+ context['with_scope'] = decode(@options, context)
20
+ render_all(@nodelist, context)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def decode(attributes, context)
27
+ attributes.each_pair do |key, value|
28
+ attributes[key] = (case value
29
+ when /^true|false$/i then value == 'true'
30
+ when /^[0-9]+$/ then value.to_i
31
+ when /^["|'](.+)["|']$/ then $1.gsub(/^["|']/, '').gsub(/["|']$/, '')
32
+ else
33
+ context[value] || value
34
+ end)
35
+ end
36
+ end
37
+ end
38
+
39
+ ::Liquid::Template.register_tag('with_scope', WithScope)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ require "locomotive/mounter"
2
+ require 'liquid'
3
+ require 'locomotive/builder/liquid/drops/base'
4
+
5
+ %w{. drops tags filters}.each do |dir|
6
+ Dir[File.join(File.dirname(__FILE__), 'liquid', dir, '*.rb')].each { |lib| require lib }
7
+ end
8
+
9
+
10
+ # add to_liquid methods to main models from the mounter
11
+ %w{site page content_entry}.each do |name|
12
+ klass = "Locomotive::Mounter::Models::#{name.classify}".constantize
13
+
14
+ klass.class_eval <<-EOV
15
+ def to_liquid
16
+ ::Locomotive::Builder::Liquid::Drops::#{name.classify}.new(self)
17
+ end
18
+ EOV
19
+ end
@@ -0,0 +1,48 @@
1
+ require 'listen'
2
+
3
+ module Locomotive::Builder
4
+ class Listen
5
+
6
+ attr_accessor :reader
7
+
8
+ def self.instance
9
+ @@instance = new
10
+ end
11
+
12
+ def start(reader)
13
+ self.reader = reader
14
+
15
+ self.definitions.each do |definition|
16
+ self.apply(definition)
17
+ end
18
+ end
19
+
20
+ def definitions
21
+ [
22
+ ['config', /\.yml/, [:site, :content_types, :pages, :snippets, :content_entries, :translations]],
23
+ ['app/views', /\.liquid/, [:pages, :snippets]],
24
+ ['app/content_types', /\.yml/, [:content_types, :content_entries]],
25
+ ['data', /\.yml/, :content_entries]
26
+ ]
27
+ end
28
+
29
+ protected
30
+
31
+ def apply(definition)
32
+ reloader = Proc.new do |modified, added, removed|
33
+ reader.reload(definition.last)
34
+ end
35
+
36
+ filter = definition[1]
37
+ path = File.join(self.reader.mounting_point.path, definition.first)
38
+ path = File.expand_path(path)
39
+
40
+ listener = ::Listen.to(path).filter(filter).change(&reloader)
41
+
42
+ # non blocking listener
43
+ listener.start(false)
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,29 @@
1
+ unless Hash.instance_methods.include?(:underscore_keys)
2
+ class Hash
3
+
4
+ def underscore_keys
5
+ new_hash = {}
6
+
7
+ self.each_pair do |key, value|
8
+ if value.respond_to?(:collect!) # Array
9
+ value.collect do |item|
10
+ if item.respond_to?(:each_pair) # Hash item within
11
+ item.underscore_keys
12
+ else
13
+ item
14
+ end
15
+ end
16
+ elsif value.respond_to?(:each_pair) # Hash
17
+ value = value.underscore_keys
18
+ end
19
+
20
+ new_key = key.is_a?(String) ? key.underscore : key # only String keys
21
+
22
+ new_hash[new_key] = value
23
+ end
24
+
25
+ self.replace(new_hash)
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,82 @@
1
+ module Locomotive
2
+ module Builder
3
+ class Dragonfly
4
+
5
+ attr_accessor :path, :enabled
6
+
7
+ def enabled?
8
+ !!self.enabled
9
+ end
10
+
11
+ def resize_url(source, resize_string)
12
+ _source = (case source
13
+ when String then source
14
+ when Hash then source['url'] || source[:url]
15
+ else
16
+ source.try(:url)
17
+ end)
18
+
19
+ if _source.blank?
20
+ LocomotiveEditor::Logger.error "Unable to resize on the fly: #{source.inspect}"
21
+ return
22
+ end
23
+
24
+ return _source unless self.enabled?
25
+
26
+ if _source =~ /^http/
27
+ file = self.class.app.fetch_url(_source)
28
+ else
29
+ file = self.class.app.fetch_file(File.join(self.path, 'public', _source))
30
+ end
31
+
32
+ file.process(:thumb, resize_string).url
33
+ end
34
+
35
+ def self.app
36
+ ::Dragonfly[:images]
37
+ end
38
+
39
+
40
+ def self.instance
41
+ @@instance ||= new
42
+ end
43
+
44
+ def self.setup!(path)
45
+ self.instance.path = path
46
+ self.instance.enabled = false
47
+
48
+ begin
49
+ require 'rack/cache'
50
+ require 'RMagick'
51
+ require 'dragonfly'
52
+
53
+ ## initialize Dragonfly ##
54
+ app = ::Dragonfly[:images].configure_with(:imagemagick)
55
+
56
+ ## configure it ##
57
+ ::Dragonfly[:images].configure do |c|
58
+ convert = `which convert`.strip.presence || '/usr/local/bin/convert'
59
+ c.convert_command = convert
60
+ c.identify_command = convert
61
+
62
+ c.allow_fetch_url = true
63
+ c.allow_fetch_file = true
64
+
65
+ c.url_format = '/images/dynamic/:job/:basename.:format'
66
+ end
67
+
68
+ puts 'Dragonfly enabled'
69
+
70
+ self.instance.enabled = true
71
+ rescue Exception => e
72
+ puts %{
73
+ \tIf you want to take full benefits of all the features in the LocomotiveEditor, we recommend you to install ImageMagick and RMagick.
74
+ \tCheck out the documentation here: http://doc.locomotivecms.com/editor/installation.}
75
+
76
+ puts 'Dragonfly disabled'
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,47 @@
1
+ require 'uri'
2
+
3
+ module Locomotive
4
+ module Builder
5
+ module Httparty
6
+ class Webservice
7
+
8
+ include ::HTTParty
9
+
10
+ def self.consume(url, options = {})
11
+ url = ::HTTParty.normalize_base_uri(url)
12
+
13
+ uri = URI.parse(url)
14
+ options[:base_uri] = "#{uri.scheme}://#{uri.host}"
15
+ options[:base_uri] += ":#{uri.port}" if uri.port != 80
16
+ path = uri.request_uri
17
+
18
+ options.delete(:format) if options[:format] == 'default'
19
+
20
+ username, password = options.delete(:username), options.delete(:password)
21
+ options[:basic_auth] = { username: username, password: password } if username
22
+
23
+ path ||= '/'
24
+
25
+ # puts "[WebService] consuming #{path}, #{options.inspect}"
26
+
27
+ response = self.get(path, options)
28
+
29
+ if response.code == 200
30
+ _response = response.parsed_response
31
+ if _response.respond_to?(:underscore_keys)
32
+ _response.underscore_keys
33
+ else
34
+ _response.collect(&:underscore_keys)
35
+ end
36
+ else
37
+ # TODO: handle errors
38
+ puts "[Locomotive][Builder][Error] consuming #{path}, #{options.inspect}, response = #{response.inspect}"
39
+ nil
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,2 @@
1
+ I18n.load_path = Dir[File.join(File.dirname(__FILE__), "/../../../../locales/*.yml")]
2
+ I18n.backend.reload!
@@ -0,0 +1,16 @@
1
+ require 'will_paginate'
2
+ require 'will_paginate/collection'
3
+
4
+ Array.class_eval do
5
+ def paginate(options = {})
6
+ raise ArgumentError, "parameter hash expected (got #{options.inspect})" unless Hash === options
7
+
8
+ WillPaginate::Collection.create(
9
+ options[:page] || 1,
10
+ options[:per_page] || 30,
11
+ options[:total_entries] || self.length
12
+ ) { |pager|
13
+ pager.replace self[pager.offset, pager.per_page].to_a
14
+ }
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ require 'locomotive/builder/misc/core_ext.rb'
2
+ require 'locomotive/builder/misc/will_paginate.rb'
3
+ require 'locomotive/builder/misc/httparty.rb'
4
+ require 'locomotive/builder/misc/dragonfly.rb'
5
+ require 'locomotive/builder/misc/i18n.rb'