locomotivecms_wagon 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +68 -0
- data/Rakefile +57 -0
- data/TODO +57 -0
- data/bin/wagon +9 -0
- data/generators/blank/Gemfile.tt +20 -0
- data/generators/blank/app/content_types/.empty_directory +1 -0
- data/generators/blank/app/views/pages/404.liquid +11 -0
- data/generators/blank/app/views/pages/index.liquid +19 -0
- data/generators/blank/app/views/snippets/.empty_directory +1 -0
- data/generators/blank/config/deploy.yml +12 -0
- data/generators/blank/config/site.yml.tt +16 -0
- data/generators/blank/config/translations.yml +8 -0
- data/generators/blank/config.ru +3 -0
- data/generators/blank/data/.empty_directory +1 -0
- data/generators/blank/public/fonts/.empty_directory +1 -0
- data/generators/blank/public/images/.empty_directory +1 -0
- data/generators/blank/public/javascripts/.empty_directory +1 -0
- data/generators/blank/public/samples/.empty_directory +1 -0
- data/generators/blank/public/stylesheets/.empty_directory +1 -0
- data/generators/bootstrap/Gemfile.tt +20 -0
- data/generators/bootstrap/app/content_types/.empty_directory +1 -0
- data/generators/bootstrap/app/views/pages/404.liquid +13 -0
- data/generators/bootstrap/app/views/pages/404.liquid.haml +10 -0
- data/generators/bootstrap/app/views/pages/index.liquid +89 -0
- data/generators/bootstrap/app/views/pages/index.liquid.haml +72 -0
- data/generators/bootstrap/app/views/snippets/footer.liquid +3 -0
- data/generators/bootstrap/app/views/snippets/footer.liquid.haml +2 -0
- data/generators/bootstrap/config/deploy.yml +12 -0
- data/generators/bootstrap/config/site.yml.tt +16 -0
- data/generators/bootstrap/config/translations.yml +8 -0
- data/generators/bootstrap/config.ru +3 -0
- data/generators/bootstrap/data/.empty_directory +1 -0
- data/generators/bootstrap/public/fonts/FontAwesome.otf +0 -0
- data/generators/bootstrap/public/fonts/font-awesome-ie7.min.css +23 -0
- data/generators/bootstrap/public/fonts/font-awesome.css +469 -0
- data/generators/bootstrap/public/fonts/font-awesome.min.css +34 -0
- data/generators/bootstrap/public/fonts/fontawesome-webfont.eot +0 -0
- data/generators/bootstrap/public/fonts/fontawesome-webfont.ttf +0 -0
- data/generators/bootstrap/public/fonts/fontawesome-webfont.woff +0 -0
- data/generators/bootstrap/public/javascripts/bootstrap.js +2159 -0
- data/generators/bootstrap/public/javascripts/bootstrap.min.js +6 -0
- data/generators/bootstrap/public/samples/.empty_directory +1 -0
- data/generators/bootstrap/public/stylesheets/application.css.scss +39 -0
- data/generators/bootstrap/public/stylesheets/bootstrap-responsive.css +1092 -0
- data/generators/bootstrap/public/stylesheets/bootstrap-responsive.min.css +9 -0
- data/generators/bootstrap/public/stylesheets/bootstrap.css +5652 -0
- data/generators/bootstrap/public/stylesheets/bootstrap.min.css +726 -0
- data/generators/content_type/app/content_types/%name%.yml.tt +58 -0
- data/generators/content_type/data/%name%.yml.tt +24 -0
- data/generators/foundation/Gemfile.tt +20 -0
- data/generators/foundation/app/content_types/.empty_directory +1 -0
- data/generators/foundation/app/views/pages/404.liquid +13 -0
- data/generators/foundation/app/views/pages/404.liquid.haml +10 -0
- data/generators/foundation/app/views/pages/index.liquid +152 -0
- data/generators/foundation/app/views/pages/index.liquid.haml +130 -0
- data/generators/foundation/app/views/snippets/footer.liquid +16 -0
- data/generators/foundation/app/views/snippets/footer.liquid.haml +23 -0
- data/generators/foundation/config/deploy.yml +12 -0
- data/generators/foundation/config/site.yml.tt +16 -0
- data/generators/foundation/config/translations.yml +8 -0
- data/generators/foundation/config.ru +3 -0
- data/generators/foundation/data/.empty_directory +1 -0
- data/generators/foundation/public/fonts/.empty_directory +1 -0
- data/generators/foundation/public/javascripts/foundation/foundation.alerts.js +50 -0
- data/generators/foundation/public/javascripts/foundation/foundation.clearing.js +480 -0
- data/generators/foundation/public/javascripts/foundation/foundation.cookie.js +74 -0
- data/generators/foundation/public/javascripts/foundation/foundation.dropdown.js +130 -0
- data/generators/foundation/public/javascripts/foundation/foundation.forms.js +395 -0
- data/generators/foundation/public/javascripts/foundation/foundation.joyride.js +612 -0
- data/generators/foundation/public/javascripts/foundation/foundation.js +372 -0
- data/generators/foundation/public/javascripts/foundation/foundation.magellan.js +130 -0
- data/generators/foundation/public/javascripts/foundation/foundation.orbit.js +365 -0
- data/generators/foundation/public/javascripts/foundation/foundation.placeholder.js +159 -0
- data/generators/foundation/public/javascripts/foundation/foundation.reveal.js +270 -0
- data/generators/foundation/public/javascripts/foundation/foundation.section.js +272 -0
- data/generators/foundation/public/javascripts/foundation/foundation.tooltips.js +195 -0
- data/generators/foundation/public/javascripts/foundation/foundation.topbar.js +225 -0
- data/generators/foundation/public/javascripts/foundation.min.js +14 -0
- data/generators/foundation/public/javascripts/vendor/custom.modernizr.js +4 -0
- data/generators/foundation/public/javascripts/vendor/jquery.js +9597 -0
- data/generators/foundation/public/javascripts/vendor/zepto.js +1884 -0
- data/generators/foundation/public/samples/.empty_directory +1 -0
- data/generators/foundation/public/stylesheets/foundation.css +3818 -0
- data/generators/foundation/public/stylesheets/foundation.min.css +1 -0
- data/generators/foundation/public/stylesheets/normalize.css +396 -0
- data/generators/page/template.liquid.haml.tt +35 -0
- data/generators/page/template.liquid.tt +1 -0
- data/generators/snippet/template.liquid.haml.tt +4 -0
- data/generators/snippet/template.liquid.tt +4 -0
- data/lib/locomotive/wagon/cli.rb +238 -0
- data/lib/locomotive/wagon/exceptions.rb +35 -0
- data/lib/locomotive/wagon/generators/content_type.rb +47 -0
- data/lib/locomotive/wagon/generators/page.rb +63 -0
- data/lib/locomotive/wagon/generators/site/base.rb +30 -0
- data/lib/locomotive/wagon/generators/site/blank.rb +23 -0
- data/lib/locomotive/wagon/generators/site/bootstrap.rb +35 -0
- data/lib/locomotive/wagon/generators/site/foundation.rb +35 -0
- data/lib/locomotive/wagon/generators/site/unzip.rb +81 -0
- data/lib/locomotive/wagon/generators/site.rb +99 -0
- data/lib/locomotive/wagon/generators/snippet.rb +60 -0
- data/lib/locomotive/wagon/liquid/drops/base.rb +44 -0
- data/lib/locomotive/wagon/liquid/drops/content_entry.rb +48 -0
- data/lib/locomotive/wagon/liquid/drops/content_types.rb +121 -0
- data/lib/locomotive/wagon/liquid/drops/page.rb +36 -0
- data/lib/locomotive/wagon/liquid/drops/site.rb +21 -0
- data/lib/locomotive/wagon/liquid/errors.rb +7 -0
- data/lib/locomotive/wagon/liquid/filters/date.rb +98 -0
- data/lib/locomotive/wagon/liquid/filters/html.rb +154 -0
- data/lib/locomotive/wagon/liquid/filters/misc.rb +28 -0
- data/lib/locomotive/wagon/liquid/filters/resize.rb +18 -0
- data/lib/locomotive/wagon/liquid/filters/text.rb +50 -0
- data/lib/locomotive/wagon/liquid/filters/translate.rb +24 -0
- data/lib/locomotive/wagon/liquid/patches.rb +47 -0
- data/lib/locomotive/wagon/liquid/tags/consume.rb +58 -0
- data/lib/locomotive/wagon/liquid/tags/csrf.rb +34 -0
- data/lib/locomotive/wagon/liquid/tags/editable/base.rb +46 -0
- data/lib/locomotive/wagon/liquid/tags/editable/control.rb +19 -0
- data/lib/locomotive/wagon/liquid/tags/editable/file.rb +15 -0
- data/lib/locomotive/wagon/liquid/tags/editable/long_text.rb +15 -0
- data/lib/locomotive/wagon/liquid/tags/editable/short_text.rb +15 -0
- data/lib/locomotive/wagon/liquid/tags/editable.rb +5 -0
- data/lib/locomotive/wagon/liquid/tags/extends.rb +25 -0
- data/lib/locomotive/wagon/liquid/tags/google_analytics.rb +28 -0
- data/lib/locomotive/wagon/liquid/tags/inline_editor.rb +16 -0
- data/lib/locomotive/wagon/liquid/tags/locale_switcher.rb +106 -0
- data/lib/locomotive/wagon/liquid/tags/nav.rb +167 -0
- data/lib/locomotive/wagon/liquid/tags/paginate.rb +105 -0
- data/lib/locomotive/wagon/liquid/tags/seo.rb +74 -0
- data/lib/locomotive/wagon/liquid/tags/snippet.rb +44 -0
- data/lib/locomotive/wagon/liquid/tags/with_scope.rb +43 -0
- data/lib/locomotive/wagon/liquid.rb +19 -0
- data/lib/locomotive/wagon/listen.rb +57 -0
- data/lib/locomotive/wagon/logger.rb +54 -0
- data/lib/locomotive/wagon/misc/core_ext.rb +29 -0
- data/lib/locomotive/wagon/misc/dragonfly.rb +79 -0
- data/lib/locomotive/wagon/misc/httparty.rb +46 -0
- data/lib/locomotive/wagon/misc/i18n.rb +2 -0
- data/lib/locomotive/wagon/misc/will_paginate.rb +16 -0
- data/lib/locomotive/wagon/misc.rb +5 -0
- data/lib/locomotive/wagon/server/dynamic_assets.rb +31 -0
- data/lib/locomotive/wagon/server/entry_submission.rb +116 -0
- data/lib/locomotive/wagon/server/favicon.rb +17 -0
- data/lib/locomotive/wagon/server/locale.rb +42 -0
- data/lib/locomotive/wagon/server/logging.rb +32 -0
- data/lib/locomotive/wagon/server/middleware.rb +59 -0
- data/lib/locomotive/wagon/server/not_found.rb +19 -0
- data/lib/locomotive/wagon/server/page.rb +61 -0
- data/lib/locomotive/wagon/server/path.rb +34 -0
- data/lib/locomotive/wagon/server/renderer.rb +105 -0
- data/lib/locomotive/wagon/server/templatized_page.rb +32 -0
- data/lib/locomotive/wagon/server.rb +81 -0
- data/lib/locomotive/wagon/standalone_server.rb +28 -0
- data/lib/locomotive/wagon/version.rb +5 -0
- data/lib/locomotive/wagon.rb +163 -0
- data/locales/de.yml +156 -0
- data/locales/en.yml +177 -0
- data/locales/es.yml +132 -0
- data/locales/et.yml +153 -0
- data/locales/fr.yml +146 -0
- data/locales/it.yml +154 -0
- data/locales/nb.yml +190 -0
- data/locales/nl.yml +159 -0
- data/locales/pl.yml +202 -0
- data/locales/pt-BR.yml +138 -0
- data/locales/ru.yml +223 -0
- data/locomotivecms_wagon.gemspec +44 -0
- data/spec/integration/cassettes/pull.yml +590 -0
- data/spec/integration/cassettes/push.yml +810 -0
- data/spec/integration/integration_helper.rb +14 -0
- data/spec/integration/server_spec.rb +38 -0
- data/spec/integration/sites_spec.rb +29 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/helpers.rb +13 -0
- metadata +544 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
module Locomotive::Wagon
|
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::Wagon
|
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::Wagon
|
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
|
+
self.log "Detecting locale #{locale.upcase}"
|
35
|
+
|
36
|
+
env['wagon.locale'] = locale
|
37
|
+
env['wagon.path'] = self.path
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Locomotive::Wagon
|
2
|
+
class Server
|
3
|
+
|
4
|
+
# Track the request into the current logger
|
5
|
+
#
|
6
|
+
class Logging < Middleware
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
now = Time.now
|
10
|
+
|
11
|
+
log "Started #{env['REQUEST_METHOD'].upcase} \"#{env['PATH_INFO']}\" at #{now}"
|
12
|
+
|
13
|
+
app.call(env).tap do |response|
|
14
|
+
done_in_ms = (Time.now - now) * 1000
|
15
|
+
log "Completed #{code_to_human(response.first)} in #{done_in_ms}ms\n\n"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def code_to_human(code)
|
22
|
+
case code.to_i
|
23
|
+
when 200 then '200 OK'
|
24
|
+
when 301 then '301 Found'
|
25
|
+
when 302 then '302 Found'
|
26
|
+
when 404 then '404 Not Found'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Locomotive::Wagon
|
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['wagon.path']
|
22
|
+
self.request = Rack::Request.new(env)
|
23
|
+
self.mounting_point = env['wagon.mounting_point']
|
24
|
+
self.page = env['wagon.page']
|
25
|
+
self.content_entry = env['wagon.content_entry']
|
26
|
+
|
27
|
+
env['wagon.liquid_assigns'] ||= {}
|
28
|
+
self.liquid_assigns = env['wagon.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, type = 301)
|
48
|
+
self.log "Redirected to #{location}"
|
49
|
+
[type, { 'Content-Type' => 'text/html', 'Location' => location }, []]
|
50
|
+
end
|
51
|
+
|
52
|
+
def log(msg)
|
53
|
+
Locomotive::Wagon::Logger.info msg
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Locomotive::Wagon
|
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
|
+
self.log "Page not found"
|
11
|
+
env['wagon.page'] = self.mounting_point.pages['404']
|
12
|
+
end
|
13
|
+
|
14
|
+
app.call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Locomotive::Wagon
|
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
|
+
if page
|
23
|
+
self.log "Found page \"#{page.title}\" [/#{page.inspect}]"
|
24
|
+
end
|
25
|
+
|
26
|
+
env['wagon.page'] = page
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch_page
|
30
|
+
matchers = self.path_combinations(self.path)
|
31
|
+
|
32
|
+
self.mounting_point.pages.values.detect do |_page|
|
33
|
+
matchers.include?(_page.safe_fullpath) ||
|
34
|
+
matchers.include?(_page.safe_fullpath.try(:underscore))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def path_combinations(path)
|
39
|
+
self._path_combinations(path.split('/'))
|
40
|
+
end
|
41
|
+
|
42
|
+
def _path_combinations(segments, can_include_template = true)
|
43
|
+
return nil if segments.empty?
|
44
|
+
|
45
|
+
segment = segments.shift
|
46
|
+
|
47
|
+
(can_include_template ? [segment, '*'] : [segment]).map do |_segment|
|
48
|
+
if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != '*'))
|
49
|
+
[*_combinations].map do |_combination|
|
50
|
+
File.join(_segment, _combination)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
[_segment]
|
54
|
+
end
|
55
|
+
end.flatten
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Locomotive::Wagon
|
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['wagon.path'] = path
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Locomotive::Wagon
|
2
|
+
class Server
|
3
|
+
|
4
|
+
class Renderer < Middleware
|
5
|
+
|
6
|
+
def call(env)
|
7
|
+
self.set_accessors(env)
|
8
|
+
|
9
|
+
if self.page
|
10
|
+
if self.page.redirect?
|
11
|
+
self.redirect_to(self.page.redirect_url, self.page.redirect_type)
|
12
|
+
else
|
13
|
+
type = self.page.response_type || 'text/html'
|
14
|
+
html = self.render
|
15
|
+
|
16
|
+
self.log " Rendered liquid page template"
|
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::Wagon::Liquid::Drops::ContentTypes.new,
|
74
|
+
'contents' => Locomotive::Wagon::Liquid::Drops::ContentTypes.new,
|
75
|
+
'current_page' => self.params[:page],
|
76
|
+
'params' => self.params.stringify_keys,
|
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::Wagon
|
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['wagon.content_entry'] = content_entry
|
25
|
+
else
|
26
|
+
env['wagon.page'] = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rack/showexceptions'
|
2
|
+
require 'coffee_script'
|
3
|
+
|
4
|
+
require 'locomotive/wagon/listen'
|
5
|
+
require 'locomotive/wagon/server/middleware'
|
6
|
+
require 'locomotive/wagon/server/favicon'
|
7
|
+
require 'locomotive/wagon/server/dynamic_assets'
|
8
|
+
require 'locomotive/wagon/server/logging'
|
9
|
+
require 'locomotive/wagon/server/entry_submission'
|
10
|
+
require 'locomotive/wagon/server/path'
|
11
|
+
require 'locomotive/wagon/server/locale'
|
12
|
+
require 'locomotive/wagon/server/page'
|
13
|
+
require 'locomotive/wagon/server/templatized_page'
|
14
|
+
require 'locomotive/wagon/server/not_found'
|
15
|
+
require 'locomotive/wagon/server/renderer'
|
16
|
+
|
17
|
+
require 'locomotive/wagon/liquid'
|
18
|
+
require 'locomotive/wagon/misc'
|
19
|
+
|
20
|
+
module Locomotive::Wagon
|
21
|
+
class Server
|
22
|
+
|
23
|
+
def initialize(reader, options = {})
|
24
|
+
Locomotive::Wagon::Dragonfly.setup!(reader.mounting_point.path)
|
25
|
+
|
26
|
+
@reader = reader
|
27
|
+
@app = self.create_rack_app(@reader)
|
28
|
+
|
29
|
+
unless options[:disable_listen]
|
30
|
+
Locomotive::Wagon::Listen.instance.start(@reader)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def call(env)
|
35
|
+
env['wagon.mounting_point'] = @reader.mounting_point
|
36
|
+
@app.call(env)
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def create_rack_app(reader)
|
42
|
+
Rack::Builder.new do
|
43
|
+
use Rack::ShowExceptions
|
44
|
+
use Rack::Lint
|
45
|
+
|
46
|
+
use Rack::Session::Cookie, {
|
47
|
+
key: 'rack.session',
|
48
|
+
domain: '0.0.0.0',
|
49
|
+
path: '/',
|
50
|
+
expire_after: 2592000,
|
51
|
+
secret: 'uselessinlocal'
|
52
|
+
}
|
53
|
+
|
54
|
+
use ::Dragonfly::Middleware, :images
|
55
|
+
|
56
|
+
use Rack::Static, {
|
57
|
+
urls: ['/images', '/fonts', '/samples'],
|
58
|
+
root: File.join(reader.mounting_point.path, 'public')
|
59
|
+
}
|
60
|
+
|
61
|
+
use Favicon
|
62
|
+
use DynamicAssets
|
63
|
+
|
64
|
+
use Logging
|
65
|
+
|
66
|
+
use EntrySubmission
|
67
|
+
|
68
|
+
use Path
|
69
|
+
use Locale
|
70
|
+
|
71
|
+
use Page
|
72
|
+
use TemplatizedPage
|
73
|
+
use NotFound
|
74
|
+
use Renderer
|
75
|
+
|
76
|
+
run Renderer.new
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.dirname(__FILE__) + '/../..'))
|
2
|
+
|
3
|
+
require 'locomotive/wagon/logger'
|
4
|
+
require 'locomotive/wagon/version'
|
5
|
+
require 'locomotive/wagon/exceptions'
|
6
|
+
require 'locomotive/wagon/server'
|
7
|
+
require 'locomotive/mounter'
|
8
|
+
|
9
|
+
module Locomotive
|
10
|
+
module Wagon
|
11
|
+
class StandaloneServer < Server
|
12
|
+
|
13
|
+
def initialize(path)
|
14
|
+
Locomotive::Wagon::Logger.setup(path, false)
|
15
|
+
|
16
|
+
# get the reader
|
17
|
+
reader = Locomotive::Mounter::Reader::FileSystem.instance
|
18
|
+
reader.run!(path: path)
|
19
|
+
reader
|
20
|
+
|
21
|
+
Bundler.require 'misc'
|
22
|
+
|
23
|
+
# run the rack app
|
24
|
+
super(reader, disable_listen: true)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|