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,31 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ class DynamicAssets < Middleware
5
+
6
+ def call(env)
7
+ self.set_accessors(env)
8
+
9
+ path = env['PATH_INFO']
10
+
11
+ if path =~ /^\/(stylesheets|javascripts)\//
12
+
13
+ mime_type = MIME::Types.type_for(path).first.try(:to_s) || 'text/plain'
14
+ asset = self.mounting_point.theme_assets.detect do |_asset|
15
+ _asset.path == path
16
+ end
17
+
18
+ if asset
19
+ [200, { 'Content-Type' => mime_type }, [asset.content!]]
20
+ else
21
+ [404, { 'Content-Type' => mime_type }, ['Asset not found']]
22
+ end
23
+ else
24
+ app.call(env)
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,116 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ # Mimic the submission of a content entry
5
+ #
6
+ class EntrySubmission < Middleware
7
+
8
+ def call(env)
9
+ self.set_accessors(env)
10
+
11
+ if self.request.post? && env['PATH_INFO'] =~ /^\/entry_submissions\/(.*)/
12
+ self.process_form($1)
13
+
14
+ if @entry.valid?
15
+ if self.html?
16
+ self.record_submitted_entry
17
+ self.redirect_to self.callback_url
18
+ elsif self.json?
19
+ self.json_response
20
+ end
21
+ else
22
+ if self.html?
23
+ if self.callback_url =~ /^http:\/\//
24
+ self.redirect_to self.callback_url
25
+ else
26
+ env['PATH_INFO'] = self.callback_url
27
+ self.liquid_assigns[@content_type.slug.singularize] = @entry
28
+ app.call(env)
29
+ end
30
+ elsif self.json?
31
+ self.json_response(422)
32
+ end
33
+ end
34
+ else
35
+ self.fetch_submitted_entry
36
+
37
+ app.call(env)
38
+ end
39
+ end
40
+
41
+ protected
42
+
43
+ def record_submitted_entry
44
+ self.request.session[:now] ||= {}
45
+ self.request.session[:now][:submitted_entry] = [@content_type.slug, @entry._slug]
46
+ end
47
+
48
+ def fetch_submitted_entry
49
+ if data = self.request.session[:now].try(:delete, :submitted_entry)
50
+ content_type = self.mounting_point.content_types[data.first.to_s]
51
+
52
+ entry = (content_type.entries || []).detect { |e| e._slug == data.last }
53
+
54
+ # do not keep track of the entry
55
+ content_type.entries.delete(entry) if entry
56
+
57
+ # add it to the additional liquid assigns for the next liquid rendering
58
+ if entry
59
+ self.liquid_assigns[content_type.slug.singularize] = entry
60
+ end
61
+ end
62
+ end
63
+
64
+ # Mimic the creation of a content entry with a minimal validation.
65
+ #
66
+ # @param [ String ] permalink The permalink (or slug) of the content type
67
+ #
68
+ #
69
+ def process_form(permalink)
70
+ permalink = permalink.split('.').first
71
+
72
+ @content_type = self.mounting_point.content_types[permalink]
73
+
74
+ raise "Unknown content type '#{@content_type.inspect}'" if @content_type.nil?
75
+
76
+ @entry = @content_type.build_entry(self.params[:entry] || self.params[:content])
77
+
78
+ # if not valid, we do not need to keep track of the entry
79
+ @content_type.entries.delete(@entry) if !@entry.valid?
80
+ end
81
+
82
+ def callback_url
83
+ (@entry.valid? ? params[:success_callback] : params[:error_callback]) || '/'
84
+ end
85
+
86
+ # Build the JSON response
87
+ #
88
+ # @param [ Integer ] status The HTTP return code
89
+ #
90
+ # @return [ Array ] The rack response depending on the validation status and the requested format
91
+ #
92
+ def json_response(status = 200)
93
+ locale = self.mounting_point.default_locale
94
+
95
+ if self.request.path =~ /^\/(#{self.mounting_point.locales.join('|')})+(\/|$)/
96
+ locale = $1
97
+ end
98
+
99
+ hash = @entry.to_hash(false).tap do |_hash|
100
+ if !@entry.valid?
101
+ _hash['errors'] = @entry.errors.inject({}) do |memo, name|
102
+ memo[name] = ::I18n.t('errors.messages.blank', locale: locale)
103
+ memo
104
+ end
105
+ end
106
+ end
107
+
108
+ [status, { 'Content-Type' => 'application/json' }, [
109
+ { @content_type.slug.singularize => hash }.to_json
110
+ ]]
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+ end
@@ -0,0 +1,17 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ class Favicon < Middleware
5
+
6
+ def call(env)
7
+ if env['PATH_INFO'] == '/favicon.ico'
8
+ [200, { 'Content-Type' => 'image/vnd.microsoft.icon' }, ['']]
9
+ else
10
+ app.call(env)
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ # Set the locale from the path if possible or use the default one
5
+ # Examples:
6
+ # /fr/index => locale = :fr
7
+ # /fr/ => locale = :fr
8
+ # /index => locale = :en (default one)
9
+ #
10
+ class Locale < Middleware
11
+
12
+ def call(env)
13
+ self.set_accessors(env)
14
+
15
+ self.set_locale!(env)
16
+
17
+ app.call(env)
18
+ end
19
+
20
+ protected
21
+
22
+ def set_locale!(env)
23
+ locale = self.mounting_point.default_locale
24
+
25
+ if self.path =~ /^(#{self.mounting_point.locales.join('|')})+(\/|$)/
26
+ locale = $1
27
+ self.path = self.path.gsub($1 + $2, '')
28
+ self.path = 'index' if self.path.blank?
29
+ end
30
+
31
+ Locomotive::Mounter.locale = locale
32
+ ::I18n.locale = locale
33
+
34
+ puts "[Builder|Locale] path = #{self.path.inspect}, locale = #{locale.inspect}"
35
+
36
+ env['builder.locale'] = locale
37
+ env['builder.path'] = self.path
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,54 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ class Middleware
5
+
6
+ attr_accessor :app, :request, :path, :liquid_assigns
7
+
8
+ attr_accessor :mounting_point, :page, :content_entry
9
+
10
+ def initialize(app = nil)
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ app.call(env)
16
+ end
17
+
18
+ protected
19
+
20
+ def set_accessors(env)
21
+ self.path = env['builder.path']
22
+ self.request = Rack::Request.new(env)
23
+ self.mounting_point = env['builder.mounting_point']
24
+ self.page = env['builder.page']
25
+ self.content_entry = env['builder.content_entry']
26
+
27
+ env['builder.liquid_assigns'] ||= {}
28
+ self.liquid_assigns = env['builder.liquid_assigns']
29
+ end
30
+
31
+ def site
32
+ self.mounting_point.site
33
+ end
34
+
35
+ def params
36
+ self.request.params.deep_symbolize_keys
37
+ end
38
+
39
+ def html?
40
+ self.request.media_type == 'text/html' || !self.request.xhr?
41
+ end
42
+
43
+ def json?
44
+ self.request.content_type == 'application/json' || File.extname(self.request.path) == '.json'
45
+ end
46
+
47
+ def redirect_to(location)
48
+ [301, { 'Content-Type' => 'text/html', 'Location' => location }, []]
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,18 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ class NotFound < Middleware
5
+
6
+ def call(env)
7
+ self.set_accessors(env)
8
+
9
+ if self.page.nil?
10
+ env['builder.page'] = self.mounting_point.pages['404']
11
+ end
12
+
13
+ app.call(env)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,59 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ # Sanitize the path from the previous middleware in order
5
+ # to make it work for the renderer.
6
+ #
7
+ class Page < Middleware
8
+
9
+ def call(env)
10
+ self.set_accessors(env)
11
+
12
+ self.set_page!(env)
13
+
14
+ app.call(env)
15
+ end
16
+
17
+ protected
18
+
19
+ def set_page!(env)
20
+ page = self.fetch_page
21
+
22
+ puts "[Builder|Page] #{page.inspect}"
23
+
24
+ env['builder.page'] = page
25
+ end
26
+
27
+ def fetch_page
28
+ matchers = self.path_combinations(self.path)
29
+
30
+ self.mounting_point.pages.values.detect do |_page|
31
+ matchers.include?(_page.safe_fullpath) ||
32
+ matchers.include?(_page.safe_fullpath.try(:underscore))
33
+ end
34
+ end
35
+
36
+ def path_combinations(path)
37
+ self._path_combinations(path.split('/'))
38
+ end
39
+
40
+ def _path_combinations(segments, can_include_template = true)
41
+ return nil if segments.empty?
42
+
43
+ segment = segments.shift
44
+
45
+ (can_include_template ? [segment, '*'] : [segment]).map do |_segment|
46
+ if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != '*'))
47
+ [*_combinations].map do |_combination|
48
+ File.join(_segment, _combination)
49
+ end
50
+ else
51
+ [_segment]
52
+ end
53
+ end.flatten
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,34 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ # Sanitize the path from the previous middleware in order
5
+ # to make it work for the renderer.
6
+ #
7
+ class Path < Middleware
8
+
9
+ def call(env)
10
+ self.set_accessors(env)
11
+
12
+ self.set_path!(env)
13
+
14
+ app.call(env)
15
+ end
16
+
17
+ protected
18
+
19
+ def set_path!(env)
20
+ path = env['PATH_INFO'].clone
21
+
22
+ path.gsub!(/\.[a-zA-Z][a-zA-Z0-9]{2,}$/, '')
23
+ path.gsub!(/^\//, '')
24
+ path.gsub!(/^[A-Z]:\//, '')
25
+
26
+ path = 'index' if path.blank?
27
+
28
+ env['builder.path'] = path
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,105 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ class Renderer < Middleware
5
+
6
+ def call(env)
7
+ self.set_accessors(env)
8
+
9
+ puts "[Builder|Renderer] page = #{page.inspect}"
10
+
11
+ if self.page
12
+ if self.page.redirect?
13
+ [self.page.redirect_type, { 'Location' => self.page.redirect_url, 'Content-Type' => 'text/html' }, []]
14
+ else
15
+ type = self.page.response_type || 'text/html'
16
+ html = self.render
17
+
18
+ [200, { 'Content-Type' => type }, [html]]
19
+ end
20
+ else
21
+ # no page at all, even not the 404 page
22
+ [404, { 'Content-Type' => 'text/html' }, ['Page not found']]
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ def render
29
+ context = self.locomotive_context
30
+
31
+ template = ::Liquid::Template.parse(self.page.source, {
32
+ page: self.page,
33
+ mounting_point: self.mounting_point
34
+ })
35
+
36
+ template.render(context)
37
+ end
38
+
39
+ # Build the Liquid context used to render the Locomotive page. It
40
+ # stores both assigns and registers.
41
+ #
42
+ # @param [ Hash ] other_assigns Assigns coming for instance from the controler (optional)
43
+ #
44
+ # @return [ Object ] A new instance of the Liquid::Context class.
45
+ #
46
+ def locomotive_context(other_assigns = {})
47
+ assigns = self.locomotive_default_assigns
48
+
49
+ # assigns from other middlewares
50
+ assigns.merge!(self.liquid_assigns)
51
+
52
+ assigns.merge!(other_assigns)
53
+
54
+ # templatized page
55
+ if self.page && self.content_entry
56
+ ['content_entry', 'entry', self.page.content_type.slug.singularize].each do |key|
57
+ assigns[key] = self.content_entry
58
+ end
59
+ end
60
+
61
+ # Tip: switch from false to true to enable the re-thrown exception flag
62
+ ::Liquid::Context.new({}, assigns, self.locomotive_default_registers, true)
63
+ end
64
+
65
+ # Return the default Liquid assigns used inside the Locomotive Liquid context
66
+ #
67
+ # @return [ Hash ] The default liquid assigns object
68
+ #
69
+ def locomotive_default_assigns
70
+ {
71
+ 'site' => self.site.to_liquid,
72
+ 'page' => self.page,
73
+ 'models' => Locomotive::Builder::Liquid::Drops::ContentTypes.new,
74
+ 'contents' => Locomotive::Builder::Liquid::Drops::ContentTypes.new,
75
+ 'current_page' => self.params[:page],
76
+ 'params' => self.params,
77
+ 'path' => self.request.path,
78
+ 'fullpath' => self.request.fullpath,
79
+ 'url' => self.request.url,
80
+ 'now' => Time.now.utc,
81
+ 'today' => Date.today,
82
+ 'locale' => I18n.locale.to_s,
83
+ 'default_locale' => self.mounting_point.default_locale.to_s,
84
+ 'locales' => self.mounting_point.locales.map(&:to_s),
85
+ 'current_user' => {}
86
+ }
87
+ end
88
+
89
+ # Return the default Liquid registers used inside the Locomotive Liquid context
90
+ #
91
+ # @return [ Hash ] The default liquid registers object
92
+ #
93
+ def locomotive_default_registers
94
+ {
95
+ site: self.site,
96
+ page: self.page,
97
+ mounting_point: self.mounting_point,
98
+ inline_editor: false
99
+ }
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+ end
@@ -0,0 +1,32 @@
1
+ module Locomotive::Builder
2
+ class Server
3
+
4
+ class TemplatizedPage < Middleware
5
+
6
+ def call(env)
7
+ self.set_accessors(env)
8
+
9
+ if self.page && self.page.templatized?
10
+ self.set_content_entry!(env)
11
+ end
12
+
13
+ app.call(env)
14
+ end
15
+
16
+ protected
17
+
18
+ def set_content_entry!(env)
19
+ %r(^#{self.page.safe_fullpath.gsub('*', '([^\/]+)')}$) =~ self.path
20
+
21
+ permalink = $1
22
+
23
+ if content_entry = self.page.content_type.find_entry(permalink)
24
+ env['builder.content_entry'] = content_entry
25
+ else
26
+ env['builder.page'] = nil
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,78 @@
1
+ require 'rack/showexceptions'
2
+ require 'coffee_script'
3
+
4
+ require 'locomotive/builder/listen'
5
+ require 'locomotive/builder/server/middleware'
6
+ require 'locomotive/builder/server/favicon'
7
+ require 'locomotive/builder/server/dynamic_assets'
8
+ require 'locomotive/builder/server/entry_submission'
9
+ require 'locomotive/builder/server/path'
10
+ require 'locomotive/builder/server/locale'
11
+ require 'locomotive/builder/server/page'
12
+ require 'locomotive/builder/server/templatized_page'
13
+ require 'locomotive/builder/server/not_found'
14
+ require 'locomotive/builder/server/renderer'
15
+
16
+ require 'locomotive/builder/liquid'
17
+ require 'locomotive/builder/misc'
18
+
19
+ module Locomotive::Builder
20
+ class Server
21
+
22
+ def initialize(reader, options = {})
23
+ Locomotive::Builder::Dragonfly.setup!(reader.mounting_point.path)
24
+
25
+ @reader = reader
26
+ @app = self.create_rack_app(@reader)
27
+
28
+ unless options[:disable_listen]
29
+ Locomotive::Builder::Listen.instance.start(@reader)
30
+ end
31
+ end
32
+
33
+ def call(env)
34
+ env['builder.mounting_point'] = @reader.mounting_point
35
+ @app.call(env)
36
+ end
37
+
38
+ protected
39
+
40
+ def create_rack_app(reader)
41
+ Rack::Builder.new do
42
+ use Rack::ShowExceptions
43
+ use Rack::Lint
44
+
45
+ use Rack::Session::Cookie, {
46
+ key: 'rack.session',
47
+ domain: '0.0.0.0',
48
+ path: '/',
49
+ expire_after: 2592000,
50
+ secret: 'uselessinlocal'
51
+ }
52
+
53
+ use ::Dragonfly::Middleware, :images
54
+
55
+ use Rack::Static, {
56
+ urls: ['/images', '/fonts', '/samples'],
57
+ root: File.join(reader.mounting_point.path, 'public')
58
+ }
59
+
60
+ use Favicon
61
+ use DynamicAssets
62
+
63
+ use EntrySubmission
64
+
65
+ use Path
66
+ use Locale
67
+
68
+ use Page
69
+ use TemplatizedPage
70
+ use NotFound
71
+ use Renderer
72
+
73
+ run Renderer.new
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,33 @@
1
+ require "locomotive/builder/server"
2
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../..'))
3
+
4
+ require 'locomotive/builder/version'
5
+ require 'locomotive/builder/exceptions'
6
+ require 'locomotive/mounter'
7
+
8
+ module Locomotive
9
+ module Builder
10
+ class StandaloneServer < Server
11
+
12
+ def initialize(path)
13
+ # setting the logger
14
+ logfile = File.join(path, 'log', 'mounter.log')
15
+ FileUtils.mkdir_p(File.dirname(logfile))
16
+
17
+ Locomotive::Mounter.logger = ::Logger.new(logfile).tap do |log|
18
+ log.level = Logger::DEBUG
19
+ end
20
+
21
+ # get the reader
22
+ reader = Locomotive::Mounter::Reader::FileSystem.instance
23
+ reader.run!(path: path)
24
+ reader
25
+
26
+ # run the rack app
27
+ Bundler.require 'misc'
28
+
29
+ super(reader, disable_listen: true)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Locomotive
2
+ module Builder
3
+ VERSION = '1.0.0.alpha1'
4
+ end
5
+ end