locomotivecms_wagon 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/generators/blank/app/views/pages/404.liquid.haml +11 -0
- data/generators/blank/app/views/pages/index.liquid.haml +12 -0
- data/generators/blank/config/site.yml.tt +3 -0
- data/generators/bootstrap/config/site.yml.tt +3 -0
- data/generators/content_type/data/%name%.yml.tt +2 -2
- data/generators/foundation/config/site.yml.tt +3 -0
- data/lib/locomotive/wagon.rb +10 -2
- data/lib/locomotive/wagon/cli.rb +1 -1
- data/lib/locomotive/wagon/exceptions.rb +27 -0
- data/lib/locomotive/wagon/generators/site/blank.rb +10 -1
- data/lib/locomotive/wagon/liquid.rb +1 -1
- data/lib/locomotive/wagon/liquid/drops/content_types.rb +5 -0
- data/lib/locomotive/wagon/liquid/drops/session_proxy.rb +18 -0
- data/lib/locomotive/wagon/liquid/drops/site.rb +4 -0
- data/lib/locomotive/wagon/liquid/errors.rb +10 -0
- data/lib/locomotive/wagon/liquid/filters/date.rb +62 -24
- data/lib/locomotive/wagon/liquid/filters/html.rb +7 -5
- data/lib/locomotive/wagon/liquid/filters/misc.rb +17 -0
- data/lib/locomotive/wagon/liquid/filters/text.rb +8 -2
- data/lib/locomotive/wagon/liquid/patches.rb +1 -1
- data/lib/locomotive/wagon/liquid/scopeable.rb +128 -11
- data/lib/locomotive/wagon/liquid/tags/consume.rb +60 -18
- data/lib/locomotive/wagon/liquid/tags/editable/base.rb +4 -4
- data/lib/locomotive/wagon/liquid/tags/extends.rb +2 -2
- data/lib/locomotive/wagon/liquid/tags/google_analytics.rb +2 -2
- data/lib/locomotive/wagon/liquid/tags/link_to.rb +20 -9
- data/lib/locomotive/wagon/liquid/tags/locale_switcher.rb +7 -7
- data/lib/locomotive/wagon/liquid/tags/nav.rb +22 -22
- data/lib/locomotive/wagon/liquid/tags/paginate.rb +2 -2
- data/lib/locomotive/wagon/liquid/tags/session_assign.rb +41 -0
- data/lib/locomotive/wagon/liquid/tags/snippet.rb +25 -6
- data/lib/locomotive/wagon/liquid/tags/with_scope.rb +9 -8
- data/lib/locomotive/wagon/misc.rb +5 -1
- data/lib/locomotive/wagon/misc/better_errors.rb +70 -0
- data/lib/locomotive/wagon/misc/core_ext.rb +8 -1
- data/lib/locomotive/wagon/misc/haml.rb +15 -0
- data/lib/locomotive/wagon/misc/markdown.rb +27 -0
- data/lib/locomotive/wagon/misc/mounter.rb +32 -0
- data/lib/locomotive/wagon/server.rb +6 -4
- data/lib/locomotive/wagon/server/dynamic_assets.rb +3 -8
- data/lib/locomotive/wagon/server/logging.rb +2 -2
- data/lib/locomotive/wagon/server/renderer.rb +17 -12
- data/lib/locomotive/wagon/server/timezone.rb +18 -0
- data/lib/locomotive/wagon/version.rb +1 -1
- data/locales/en.yml +11 -0
- data/locomotivecms_wagon.gemspec +6 -5
- data/spec/fixtures/default/app/content_types/events.yml +7 -1
- data/spec/fixtures/default/app/views/pages/contest.liquid.haml +18 -0
- data/spec/fixtures/default/app/views/pages/filtered.liquid.haml +10 -0
- data/spec/fixtures/default/app/views/pages/index.liquid.haml +2 -6
- data/spec/fixtures/default/app/views/pages/music.fr.liquid.haml +4 -0
- data/spec/fixtures/default/app/views/pages/songs/template.fr.liquid.haml +16 -0
- data/spec/fixtures/default/app/views/pages/songs/template/band.liquid.haml +16 -0
- data/spec/fixtures/default/app/views/snippets/footer.liquid.haml +6 -0
- data/spec/fixtures/default/app/views/snippets/song.fr.liquid.haml +1 -1
- data/spec/fixtures/default/data/events.yml +4 -0
- data/spec/integration/cassettes/pull.yml +308 -450
- data/spec/integration/cassettes/push.yml +446 -492
- data/spec/integration/cassettes/staging.yml +360 -500
- data/spec/integration/cli_spec.rb +2 -2
- data/spec/integration/server/basic_spec.rb +30 -0
- data/spec/integration/server/liquid_spec.rb +7 -0
- data/spec/integration/server/with_scope_spec.rb +20 -0
- data/spec/integration/sites_spec.rb +8 -7
- data/spec/support/helpers.rb +1 -1
- metadata +65 -78
@@ -18,13 +18,13 @@ module Locomotive
|
|
18
18
|
|
19
19
|
attr_accessor :current_page, :mounting_point
|
20
20
|
|
21
|
-
def initialize(tag_name, markup, tokens,
|
21
|
+
def initialize(tag_name, markup, tokens, options)
|
22
22
|
if markup =~ Syntax
|
23
23
|
@source = ($1 || 'page').gsub(/"|'/, '')
|
24
24
|
|
25
|
-
self.set_options(markup,
|
25
|
+
self.set_options(markup, options)
|
26
26
|
else
|
27
|
-
raise ::Liquid::SyntaxError.new("
|
27
|
+
raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.nav"), options[:line])
|
28
28
|
end
|
29
29
|
|
30
30
|
super
|
@@ -39,7 +39,7 @@ module Locomotive
|
|
39
39
|
if self.no_wrapper?
|
40
40
|
output
|
41
41
|
else
|
42
|
-
self.render_tag(:nav, id: @
|
42
|
+
self.render_tag(:nav, id: @_options[:id], css: @_options[:class]) do
|
43
43
|
self.render_tag(:ul) { output }
|
44
44
|
end
|
45
45
|
end
|
@@ -92,8 +92,8 @@ module Locomotive
|
|
92
92
|
def include_page?(page)
|
93
93
|
if !page.listed? || page.templatized? || !page.published?
|
94
94
|
false
|
95
|
-
elsif @
|
96
|
-
(page.fullpath =~ @
|
95
|
+
elsif @_options[:exclude]
|
96
|
+
(page.fullpath =~ @_options[:exclude]).nil?
|
97
97
|
else
|
98
98
|
true
|
99
99
|
end
|
@@ -118,7 +118,7 @@ module Locomotive
|
|
118
118
|
# @return [ Boolean ] True if the children have to be rendered.
|
119
119
|
#
|
120
120
|
def render_children_for_page?(page, depth)
|
121
|
-
depth.succ <= @
|
121
|
+
depth.succ <= @_options[:depth].to_i &&
|
122
122
|
(page.children || []).select { |child| self.include_page?(child) }.any?
|
123
123
|
end
|
124
124
|
|
@@ -130,12 +130,12 @@ module Locomotive
|
|
130
130
|
# @return [ String ] The label in HTML
|
131
131
|
#
|
132
132
|
def entry_label(page)
|
133
|
-
icon = @
|
134
|
-
title = @
|
133
|
+
icon = @_options[:icon] ? '<span></span>' : ''
|
134
|
+
title = @_options[:liquid_render] ? @_options[:liquid_render].render('page' => page) : page.title
|
135
135
|
|
136
136
|
if icon.blank?
|
137
137
|
title
|
138
|
-
elsif @
|
138
|
+
elsif @_options[:icon] == 'after'
|
139
139
|
"#{title} #{icon}"
|
140
140
|
else
|
141
141
|
"#{icon} #{title}"
|
@@ -165,7 +165,7 @@ module Locomotive
|
|
165
165
|
#
|
166
166
|
def entry_css(page, css = '')
|
167
167
|
_css = 'link'
|
168
|
-
_css += " #{page} #{@
|
168
|
+
_css += " #{page} #{@_options[:active_class]}" if self.page_selected?(page)
|
169
169
|
|
170
170
|
(_css + " #{css}").strip
|
171
171
|
end
|
@@ -192,7 +192,7 @@ module Locomotive
|
|
192
192
|
end
|
193
193
|
|
194
194
|
self.render_tag(:li, id: "#{page.slug.to_s.dasherize}-link", css: css) do
|
195
|
-
children_output = depth.succ <= @
|
195
|
+
children_output = depth.succ <= @_options[:depth].to_i ? self.render_entry_children(page, depth.succ) : ''
|
196
196
|
%{<a href="#{url}"#{options}>#{label}</a>} + children_output
|
197
197
|
end
|
198
198
|
end
|
@@ -209,7 +209,7 @@ module Locomotive
|
|
209
209
|
css = self.bootstrap? ? 'dropdown-menu' : ''
|
210
210
|
|
211
211
|
unless entries.empty?
|
212
|
-
self.render_tag(:ul, id: "#{@
|
212
|
+
self.render_tag(:ul, id: "#{@_options[:id]}-#{page.slug.to_s.dasherize}", css: css) do
|
213
213
|
self.build_entries_output(entries, depth)
|
214
214
|
end
|
215
215
|
else
|
@@ -219,16 +219,16 @@ module Locomotive
|
|
219
219
|
|
220
220
|
# Set the value (default or assigned by the tag) of the options.
|
221
221
|
#
|
222
|
-
def set_options(markup,
|
223
|
-
@
|
222
|
+
def set_options(markup, options)
|
223
|
+
@_options = { id: 'nav', class: '', active_class: 'on', bootstrap: false, no_wrapper: false }
|
224
224
|
|
225
|
-
markup.scan(::Liquid::TagAttributes) { |key, value| @
|
225
|
+
markup.scan(::Liquid::TagAttributes) { |key, value| @_options[key.to_sym] = value.gsub(/"|'/, '') }
|
226
226
|
|
227
|
-
@
|
227
|
+
@_options[:exclude] = Regexp.new(@_options[:exclude]) if @_options[:exclude]
|
228
228
|
|
229
|
-
if @
|
230
|
-
if template = self.parse_snippet_template(
|
231
|
-
@
|
229
|
+
if @_options[:snippet]
|
230
|
+
if template = self.parse_snippet_template(options, @_options[:snippet])
|
231
|
+
@_options[:liquid_render] = template
|
232
232
|
end
|
233
233
|
end
|
234
234
|
end
|
@@ -272,11 +272,11 @@ module Locomotive
|
|
272
272
|
end
|
273
273
|
|
274
274
|
def bootstrap?
|
275
|
-
@
|
275
|
+
@_options[:bootstrap].to_bool
|
276
276
|
end
|
277
277
|
|
278
278
|
def no_wrapper?
|
279
|
-
@
|
279
|
+
@_options[:no_wrapper].to_bool
|
280
280
|
end
|
281
281
|
|
282
282
|
::Liquid::Template.register_tag('nav', Nav)
|
@@ -18,12 +18,12 @@ module Locomotive
|
|
18
18
|
|
19
19
|
Syntax = /(#{::Liquid::Expression}+)\s+by\s+([0-9]+)/
|
20
20
|
|
21
|
-
def initialize(tag_name, markup, tokens,
|
21
|
+
def initialize(tag_name, markup, tokens, options)
|
22
22
|
if markup =~ Syntax
|
23
23
|
@collection_name = $1
|
24
24
|
@per_page = $2.to_i
|
25
25
|
else
|
26
|
-
raise ::Liquid::SyntaxError.new("
|
26
|
+
raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.paginate"), options[:line])
|
27
27
|
end
|
28
28
|
|
29
29
|
super
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Wagon
|
3
|
+
module Liquid
|
4
|
+
module Tags
|
5
|
+
|
6
|
+
# Assign sets a variable in your session.
|
7
|
+
#
|
8
|
+
# {% session_assign foo = 'monkey' %}
|
9
|
+
#
|
10
|
+
# You can then use the variable later in the page.
|
11
|
+
#
|
12
|
+
# {{ session.foo }}
|
13
|
+
#
|
14
|
+
class SessionAssign < ::Liquid::Tag
|
15
|
+
Syntax = /(#{::Liquid::VariableSignature}+)\s*=\s*(#{::Liquid::QuotedFragment}+)/
|
16
|
+
|
17
|
+
def initialize(tag_name, markup, tokens, options)
|
18
|
+
if markup =~ Syntax
|
19
|
+
@to = $1
|
20
|
+
@from = $2
|
21
|
+
else
|
22
|
+
raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.session_assign"), options[:line])
|
23
|
+
end
|
24
|
+
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def render(context)
|
29
|
+
request = context.registers[:request]
|
30
|
+
|
31
|
+
request.session[@to.to_sym] = context[@from]
|
32
|
+
''
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
::Liquid::Template.register_tag('session_assign', SessionAssign)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -6,15 +6,14 @@ module Locomotive
|
|
6
6
|
class Snippet < ::Liquid::Include
|
7
7
|
|
8
8
|
def render(context)
|
9
|
-
name
|
9
|
+
name = @template_name.gsub(/[\"\']/, '')
|
10
|
+
snippet = context.registers[:mounting_point].snippets[name]
|
10
11
|
|
11
|
-
|
12
|
+
raise ::Liquid::StandardError.new("Unknown snippet \"#{name}\"") if snippet.nil?
|
12
13
|
|
13
|
-
|
14
|
+
partial = self.parse_template(snippet)
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
variable = context[@variable_name || @template_name[1..-2]]
|
16
|
+
variable = context[@variable_name || @template_name[1..-2]]
|
18
17
|
|
19
18
|
context.stack do
|
20
19
|
@attributes.each do |key, value|
|
@@ -31,10 +30,30 @@ module Locomotive
|
|
31
30
|
partial.render(context)
|
32
31
|
end)
|
33
32
|
|
33
|
+
Locomotive::Wagon::Logger.info " Rendered snippet #{name}"
|
34
|
+
|
34
35
|
output
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
39
|
+
protected
|
40
|
+
|
41
|
+
def parse_template(snippet)
|
42
|
+
begin
|
43
|
+
::Liquid::Template.parse(snippet.source)
|
44
|
+
rescue ::Liquid::Error => e
|
45
|
+
# do it again on the raw source instead so that the error line matches
|
46
|
+
# the source file.
|
47
|
+
begin
|
48
|
+
::Liquid::Template.parse(snippet.template.raw_source)
|
49
|
+
rescue ::Liquid::Error => e
|
50
|
+
e.backtrace.unshift "#{snippet.template.filepath}:#{e.line + 1}:in `#{snippet.name}'"
|
51
|
+
e.line = self.line - 1
|
52
|
+
raise e
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
38
57
|
end
|
39
58
|
|
40
59
|
::Liquid::Template.register_tag('include', Snippet)
|
@@ -4,19 +4,20 @@ module Locomotive
|
|
4
4
|
module Tags
|
5
5
|
class WithScope < ::Liquid::Block
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
SlashedString = /\/[^\/]*\//
|
8
|
+
TagAttributes = /(\w+|\w+\.\w+)\s*\:\s*(#{SlashedString}|#{::Liquid::QuotedFragment})/
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
def initialize(tag_name, markup, tokens, options)
|
11
|
+
@tag_options = HashWithIndifferentAccess.new
|
12
|
+
markup.scan(TagAttributes) do |key, value|
|
13
|
+
@tag_options[key] = value
|
12
14
|
end
|
13
|
-
|
14
15
|
super
|
15
16
|
end
|
16
17
|
|
17
18
|
def render(context)
|
18
19
|
context.stack do
|
19
|
-
context['with_scope'] = decode(@
|
20
|
+
context['with_scope'] = decode(@tag_options, context)
|
20
21
|
render_all(@nodelist, context)
|
21
22
|
end
|
22
23
|
end
|
@@ -26,8 +27,8 @@ module Locomotive
|
|
26
27
|
def decode(attributes, context)
|
27
28
|
attributes.each_pair do |key, value|
|
28
29
|
attributes[key] = (case value
|
29
|
-
when /^true|false$/i
|
30
|
-
when
|
30
|
+
when /^true|false$/i then value == 'true'
|
31
|
+
when /^\/[^\/]*\/$/ then Regexp.new(value[1..-2])
|
31
32
|
when /^["|'](.+)["|']$/ then $1.gsub(/^["|']/, '').gsub(/["|']$/, '')
|
32
33
|
else
|
33
34
|
context[value] || value
|
@@ -2,4 +2,8 @@ require 'locomotive/wagon/misc/core_ext.rb'
|
|
2
2
|
require 'locomotive/wagon/misc/will_paginate.rb'
|
3
3
|
require 'locomotive/wagon/misc/httparty.rb'
|
4
4
|
require 'locomotive/wagon/misc/dragonfly.rb'
|
5
|
-
require 'locomotive/wagon/misc/i18n.rb'
|
5
|
+
require 'locomotive/wagon/misc/i18n.rb'
|
6
|
+
require 'locomotive/wagon/misc/mounter.rb'
|
7
|
+
require 'locomotive/wagon/misc/markdown.rb'
|
8
|
+
require 'locomotive/wagon/misc/haml.rb'
|
9
|
+
require 'locomotive/wagon/misc/better_errors.rb'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module BetterErrors
|
4
|
+
class MiddlewareWrapper
|
5
|
+
|
6
|
+
def initialize(app)
|
7
|
+
@@middleware ||= BetterErrors::Middleware.new(app)
|
8
|
+
@@middleware.instance_variable_set(:@app, app)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env['action_dispatch.request.parameters'] = Rack::Request.new(env).params
|
13
|
+
|
14
|
+
@@middleware.call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
module FrameWithLiquidContext
|
20
|
+
|
21
|
+
extend ActiveSupport::Concern
|
22
|
+
|
23
|
+
included do
|
24
|
+
|
25
|
+
attr_accessor :liquid_context
|
26
|
+
|
27
|
+
alias_method_chain :local_variables, :liquid_context
|
28
|
+
|
29
|
+
class << self
|
30
|
+
|
31
|
+
alias_method_chain :from_exception, :liquid_context
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def local_variables_with_liquid_context
|
37
|
+
if self.liquid_context
|
38
|
+
scope = self.liquid_context.scopes.last.clone
|
39
|
+
|
40
|
+
scope.delete_if { |k, _| %w(models contents params session).include?(k) }.tap do |_scope|
|
41
|
+
_scope['site'] = _scope['site']._source.to_hash
|
42
|
+
_scope['page'] = _scope['page'].to_hash.delete_if { |k, _| %w(template).include?(k) }
|
43
|
+
end
|
44
|
+
else
|
45
|
+
self.local_variables_without_liquid_context
|
46
|
+
end
|
47
|
+
rescue Exception => e
|
48
|
+
puts "[BetterError] Fatal error: #{e.message}".red
|
49
|
+
puts e.backtrace.join("\n")
|
50
|
+
{}
|
51
|
+
end
|
52
|
+
|
53
|
+
module ClassMethods
|
54
|
+
|
55
|
+
def from_exception_with_liquid_context(exception)
|
56
|
+
from_exception_without_liquid_context(exception).tap do |list|
|
57
|
+
if exception.respond_to?(:liquid_context)
|
58
|
+
list.first.liquid_context = exception.liquid_context
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class StackFrame
|
67
|
+
include FrameWithLiquidContext
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -44,4 +44,11 @@ unless String.instance_methods.include?(:to_bool)
|
|
44
44
|
class FalseClass
|
45
45
|
def to_bool; self; end
|
46
46
|
end
|
47
|
-
end
|
47
|
+
end
|
48
|
+
|
49
|
+
unless Array.instance_methods.include?(:contains?)
|
50
|
+
class Array
|
51
|
+
def contains?(other); (self & other) == other; end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Haml::Filters
|
2
|
+
|
3
|
+
remove_filter("Markdown") #remove the existing Markdown filter
|
4
|
+
|
5
|
+
module Markdown # the contents of this are as before, but without the lazy_require call
|
6
|
+
|
7
|
+
include Haml::Filters::Base
|
8
|
+
|
9
|
+
def render text
|
10
|
+
Locomotive::Wagon::Markdown.render text
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'redcarpet'
|
2
|
+
|
3
|
+
module Locomotive
|
4
|
+
module Wagon
|
5
|
+
module Markdown
|
6
|
+
|
7
|
+
def self.render(text)
|
8
|
+
self.parser.render(text)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.parser
|
12
|
+
@@markdown ||= Redcarpet::Markdown.new Redcarpet::Render::HTML, {
|
13
|
+
autolink: true,
|
14
|
+
fenced_code: true,
|
15
|
+
generate_toc: true,
|
16
|
+
gh_blockcode: true,
|
17
|
+
hard_wrap: true,
|
18
|
+
no_intraemphasis: true,
|
19
|
+
strikethrough: true,
|
20
|
+
tables: true,
|
21
|
+
xhtml: true
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Mounter
|
3
|
+
module Models
|
4
|
+
class Page
|
5
|
+
|
6
|
+
def render(context)
|
7
|
+
self.parse(context).render(context)
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def parse(context)
|
13
|
+
options = {
|
14
|
+
page: self,
|
15
|
+
mounting_point: context.registers[:mounting_point],
|
16
|
+
error_mode: :strict,
|
17
|
+
count_lines: true
|
18
|
+
}
|
19
|
+
|
20
|
+
begin
|
21
|
+
template = ::Liquid::Template.parse(self.source, options)
|
22
|
+
rescue Liquid::SyntaxError => e
|
23
|
+
# do it again on the raw source instead so that the error line matches
|
24
|
+
# the source file.
|
25
|
+
::Liquid::Template.parse(self.template.raw_source, options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|