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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +1 -1
  4. data/Rakefile +1 -1
  5. data/generators/blank/app/views/pages/404.liquid.haml +11 -0
  6. data/generators/blank/app/views/pages/index.liquid.haml +12 -0
  7. data/generators/blank/config/site.yml.tt +3 -0
  8. data/generators/bootstrap/config/site.yml.tt +3 -0
  9. data/generators/content_type/data/%name%.yml.tt +2 -2
  10. data/generators/foundation/config/site.yml.tt +3 -0
  11. data/lib/locomotive/wagon.rb +10 -2
  12. data/lib/locomotive/wagon/cli.rb +1 -1
  13. data/lib/locomotive/wagon/exceptions.rb +27 -0
  14. data/lib/locomotive/wagon/generators/site/blank.rb +10 -1
  15. data/lib/locomotive/wagon/liquid.rb +1 -1
  16. data/lib/locomotive/wagon/liquid/drops/content_types.rb +5 -0
  17. data/lib/locomotive/wagon/liquid/drops/session_proxy.rb +18 -0
  18. data/lib/locomotive/wagon/liquid/drops/site.rb +4 -0
  19. data/lib/locomotive/wagon/liquid/errors.rb +10 -0
  20. data/lib/locomotive/wagon/liquid/filters/date.rb +62 -24
  21. data/lib/locomotive/wagon/liquid/filters/html.rb +7 -5
  22. data/lib/locomotive/wagon/liquid/filters/misc.rb +17 -0
  23. data/lib/locomotive/wagon/liquid/filters/text.rb +8 -2
  24. data/lib/locomotive/wagon/liquid/patches.rb +1 -1
  25. data/lib/locomotive/wagon/liquid/scopeable.rb +128 -11
  26. data/lib/locomotive/wagon/liquid/tags/consume.rb +60 -18
  27. data/lib/locomotive/wagon/liquid/tags/editable/base.rb +4 -4
  28. data/lib/locomotive/wagon/liquid/tags/extends.rb +2 -2
  29. data/lib/locomotive/wagon/liquid/tags/google_analytics.rb +2 -2
  30. data/lib/locomotive/wagon/liquid/tags/link_to.rb +20 -9
  31. data/lib/locomotive/wagon/liquid/tags/locale_switcher.rb +7 -7
  32. data/lib/locomotive/wagon/liquid/tags/nav.rb +22 -22
  33. data/lib/locomotive/wagon/liquid/tags/paginate.rb +2 -2
  34. data/lib/locomotive/wagon/liquid/tags/session_assign.rb +41 -0
  35. data/lib/locomotive/wagon/liquid/tags/snippet.rb +25 -6
  36. data/lib/locomotive/wagon/liquid/tags/with_scope.rb +9 -8
  37. data/lib/locomotive/wagon/misc.rb +5 -1
  38. data/lib/locomotive/wagon/misc/better_errors.rb +70 -0
  39. data/lib/locomotive/wagon/misc/core_ext.rb +8 -1
  40. data/lib/locomotive/wagon/misc/haml.rb +15 -0
  41. data/lib/locomotive/wagon/misc/markdown.rb +27 -0
  42. data/lib/locomotive/wagon/misc/mounter.rb +32 -0
  43. data/lib/locomotive/wagon/server.rb +6 -4
  44. data/lib/locomotive/wagon/server/dynamic_assets.rb +3 -8
  45. data/lib/locomotive/wagon/server/logging.rb +2 -2
  46. data/lib/locomotive/wagon/server/renderer.rb +17 -12
  47. data/lib/locomotive/wagon/server/timezone.rb +18 -0
  48. data/lib/locomotive/wagon/version.rb +1 -1
  49. data/locales/en.yml +11 -0
  50. data/locomotivecms_wagon.gemspec +6 -5
  51. data/spec/fixtures/default/app/content_types/events.yml +7 -1
  52. data/spec/fixtures/default/app/views/pages/contest.liquid.haml +18 -0
  53. data/spec/fixtures/default/app/views/pages/filtered.liquid.haml +10 -0
  54. data/spec/fixtures/default/app/views/pages/index.liquid.haml +2 -6
  55. data/spec/fixtures/default/app/views/pages/music.fr.liquid.haml +4 -0
  56. data/spec/fixtures/default/app/views/pages/songs/template.fr.liquid.haml +16 -0
  57. data/spec/fixtures/default/app/views/pages/songs/template/band.liquid.haml +16 -0
  58. data/spec/fixtures/default/app/views/snippets/footer.liquid.haml +6 -0
  59. data/spec/fixtures/default/app/views/snippets/song.fr.liquid.haml +1 -1
  60. data/spec/fixtures/default/data/events.yml +4 -0
  61. data/spec/integration/cassettes/pull.yml +308 -450
  62. data/spec/integration/cassettes/push.yml +446 -492
  63. data/spec/integration/cassettes/staging.yml +360 -500
  64. data/spec/integration/cli_spec.rb +2 -2
  65. data/spec/integration/server/basic_spec.rb +30 -0
  66. data/spec/integration/server/liquid_spec.rb +7 -0
  67. data/spec/integration/server/with_scope_spec.rb +20 -0
  68. data/spec/integration/sites_spec.rb +8 -7
  69. data/spec/support/helpers.rb +1 -1
  70. 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, context)
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, context)
25
+ self.set_options(markup, options)
26
26
  else
27
- raise ::Liquid::SyntaxError.new("Syntax Error in 'nav' - Valid syntax: nav <site|parent|page|<path to a page>> <options>")
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: @options[:id], css: @options[:class]) do
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 @options[:exclude]
96
- (page.fullpath =~ @options[:exclude]).nil?
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 <= @options[:depth].to_i &&
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 = @options[:icon] ? '<span></span>' : ''
134
- title = @options[:liquid_render] ? @options[:liquid_render].render('page' => page) : page.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 @options[:icon] == 'after'
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} #{@options[:active_class]}" if self.page_selected?(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 <= @options[:depth].to_i ? self.render_entry_children(page, 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: "#{@options[:id]}-#{page.slug.to_s.dasherize}", css: css) do
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, context)
223
- @options = { id: 'nav', class: '', active_class: 'on', bootstrap: false, no_wrapper: false }
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| @options[key.to_sym] = value.gsub(/"|'/, '') }
225
+ markup.scan(::Liquid::TagAttributes) { |key, value| @_options[key.to_sym] = value.gsub(/"|'/, '') }
226
226
 
227
- @options[:exclude] = Regexp.new(@options[:exclude]) if @options[:exclude]
227
+ @_options[:exclude] = Regexp.new(@_options[:exclude]) if @_options[:exclude]
228
228
 
229
- if @options[:snippet]
230
- if template = self.parse_snippet_template(context, @options[:snippet])
231
- @options[:liquid_render] = template
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
- @options[:bootstrap].to_bool
275
+ @_options[:bootstrap].to_bool
276
276
  end
277
277
 
278
278
  def no_wrapper?
279
- @options[:no_wrapper].to_bool
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, context)
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("Syntax Error in 'paginate' - Valid syntax: paginate <collection> by <number>")
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 = @template_name.gsub(/[\"\']/, '')
9
+ name = @template_name.gsub(/[\"\']/, '')
10
+ snippet = context.registers[:mounting_point].snippets[name]
10
11
 
11
- source = context.registers[:mounting_point].snippets[name].try(:source)
12
+ raise ::Liquid::StandardError.new("Unknown snippet \"#{name}\"") if snippet.nil?
12
13
 
13
- Locomotive::Wagon::Logger.info " Rendered snippet #{name}"
14
+ partial = self.parse_template(snippet)
14
15
 
15
- partial = ::Liquid::Template.parse(source)
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
- def initialize(tag_name, markup, tokens, context)
8
- @options = {}
7
+ SlashedString = /\/[^\/]*\//
8
+ TagAttributes = /(\w+|\w+\.\w+)\s*\:\s*(#{SlashedString}|#{::Liquid::QuotedFragment})/
9
9
 
10
- markup.scan(::Liquid::TagAttributes) do |key, value|
11
- @options[key] = value
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(@options, context)
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 then value == 'true'
30
- when /^[0-9]+$/ then value.to_i
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