locomotivecms_steam 1.5.0.rc0 → 1.5.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/Gemfile +3 -6
- data/Gemfile.lock +39 -39
- data/README.md +2 -2
- data/lib/locomotive/steam/adapters/filesystem/sanitizers/section.rb +62 -16
- data/lib/locomotive/steam/adapters/filesystem/sanitizers/site.rb +15 -1
- data/lib/locomotive/steam/adapters/filesystem/yaml_loader.rb +30 -9
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb +1 -1
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb +1 -1
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/section.rb +14 -2
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/site.rb +1 -1
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/translation.rb +1 -1
- data/lib/locomotive/steam/adapters/mongodb.rb +1 -1
- data/lib/locomotive/steam/entities/content_entry.rb +0 -1
- data/lib/locomotive/steam/entities/site.rb +4 -0
- data/lib/locomotive/steam/errors.rb +54 -18
- data/lib/locomotive/steam/liquid/drops/content_entry.rb +1 -1
- data/lib/locomotive/steam/liquid/drops/content_entry_collection.rb +1 -1
- data/lib/locomotive/steam/liquid/drops/content_types.rb +1 -1
- data/lib/locomotive/steam/liquid/drops/inherited_block.rb +28 -0
- data/lib/locomotive/steam/liquid/drops/metafields.rb +2 -2
- data/lib/locomotive/steam/liquid/drops/params.rb +1 -1
- data/lib/locomotive/steam/liquid/drops/section.rb +10 -2
- data/lib/locomotive/steam/liquid/drops/section_content_proxy.rb +13 -2
- data/lib/locomotive/steam/liquid/drops/section_editor_setting_data.rb +1 -1
- data/lib/locomotive/steam/liquid/drops/session_proxy.rb +1 -1
- data/lib/locomotive/steam/liquid/file_system.rb +46 -0
- data/lib/locomotive/steam/liquid/filters/array.rb +61 -0
- data/lib/locomotive/steam/liquid/filters/misc.rb +12 -2
- data/lib/locomotive/steam/liquid/filters/number.rb +13 -12
- data/lib/locomotive/steam/liquid/filters/text.rb +4 -0
- data/lib/locomotive/steam/liquid/patches.rb +58 -19
- data/lib/locomotive/steam/liquid/tags/alt_page_links.rb +9 -5
- data/lib/locomotive/steam/liquid/tags/concerns/attributes.rb +47 -0
- data/lib/locomotive/steam/liquid/tags/concerns/path.rb +18 -31
- data/lib/locomotive/steam/liquid/tags/concerns/section.rb +22 -11
- data/lib/locomotive/steam/liquid/tags/consume.rb +26 -33
- data/lib/locomotive/steam/liquid/tags/csrf.rb +2 -2
- data/lib/locomotive/steam/liquid/tags/editable/base.rb +30 -20
- data/lib/locomotive/steam/liquid/tags/editable/control.rb +2 -2
- data/lib/locomotive/steam/liquid/tags/editable/file.rb +11 -11
- data/lib/locomotive/steam/liquid/tags/editable/text.rb +5 -5
- data/lib/locomotive/steam/liquid/tags/extends.rb +56 -8
- data/lib/locomotive/steam/liquid/tags/global_section.rb +6 -6
- data/lib/locomotive/steam/liquid/tags/google_analytics.rb +16 -6
- data/lib/locomotive/steam/liquid/tags/hybrid.rb +8 -4
- data/lib/locomotive/steam/liquid/tags/inherited_block.rb +90 -13
- data/lib/locomotive/steam/liquid/tags/inline_editor.rb +4 -4
- data/lib/locomotive/steam/liquid/tags/link_to.rb +2 -1
- data/lib/locomotive/steam/liquid/tags/locale_switcher.rb +25 -21
- data/lib/locomotive/steam/liquid/tags/model_form.rb +38 -17
- data/lib/locomotive/steam/liquid/tags/nav.rb +4 -4
- data/lib/locomotive/steam/liquid/tags/page_not_found.rb +19 -0
- data/lib/locomotive/steam/liquid/tags/paginate.rb +13 -7
- data/lib/locomotive/steam/liquid/tags/path_to.rb +1 -0
- data/lib/locomotive/steam/liquid/tags/redirect_to.rb +34 -0
- data/lib/locomotive/steam/liquid/tags/section.rb +34 -33
- data/lib/locomotive/steam/liquid/tags/sections_dropzone.rb +1 -1
- data/lib/locomotive/steam/liquid/tags/seo.rb +2 -4
- data/lib/locomotive/steam/liquid/tags/session_assign.rb +1 -0
- data/lib/locomotive/steam/liquid/tags/snippet.rb +21 -29
- data/lib/locomotive/steam/liquid/tags/with_scope.rb +61 -27
- data/lib/locomotive/steam/liquid.rb +3 -1
- data/lib/locomotive/steam/middlewares/cache.rb +117 -0
- data/lib/locomotive/steam/middlewares/concerns/helpers.rb +22 -8
- data/lib/locomotive/steam/middlewares/concerns/liquid_context.rb +5 -1
- data/lib/locomotive/steam/middlewares/concerns/rendering.rb +53 -0
- data/lib/locomotive/steam/middlewares/impersonated_entry.rb +4 -0
- data/lib/locomotive/steam/middlewares/locale.rb +2 -2
- data/lib/locomotive/steam/middlewares/locale_redirection.rb +1 -1
- data/lib/locomotive/steam/middlewares/logging.rb +1 -0
- data/lib/locomotive/steam/middlewares/page_not_found.rb +37 -0
- data/lib/locomotive/steam/middlewares/redirection.rb +1 -1
- data/lib/locomotive/steam/middlewares/renderer.rb +4 -26
- data/lib/locomotive/steam/middlewares/thread_safe.rb +0 -4
- data/lib/locomotive/steam/models/pager.rb +1 -0
- data/lib/locomotive/steam/server.rb +3 -1
- data/lib/locomotive/steam/services/action_service.rb +5 -0
- data/lib/locomotive/steam/services/auth_service.rb +9 -9
- data/lib/locomotive/steam/services/cookie_service.rb +1 -0
- data/lib/locomotive/steam/services/external_api_service.rb +5 -0
- data/lib/locomotive/steam/services/liquid_parser_service.rb +4 -2
- data/lib/locomotive/steam/services/page_finder_service.rb +1 -1
- data/lib/locomotive/steam/services/recaptcha_service.rb +4 -2
- data/lib/locomotive/steam/version.rb +1 -1
- data/lib/locomotive/steam.rb +5 -1
- data/locomotivecms_steam.gemspec +4 -4
- data/spec/fixtures/default/app/views/pages/basic.liquid.haml +1 -0
- data/spec/fixtures/default/app/views/pages/music.liquid.haml +6 -0
- data/spec/fixtures/default/app/views/sections/carousel.liquid +15 -16
- data/spec/fixtures/default/app/views/sections/footer.liquid +37 -3
- data/spec/fixtures/default/app/views/sections/header.liquid +47 -10
- data/spec/fixtures/default/app/views/sections/misc/hero.liquid +28 -0
- data/spec/fixtures/default/config/metafields_schema.yml +3 -0
- data/spec/integration/liquid/tags/section_spec.rb +82 -0
- data/spec/integration/repositories/content_entry_repository_spec.rb +9 -0
- data/spec/integration/server/basic_spec.rb +2 -2
- data/spec/integration/server/metafields_spec.rb +1 -0
- data/spec/integration/services/content_entry_service_spec.rb +12 -0
- data/spec/support/helpers.rb +1 -0
- data/spec/support/liquid.rb +32 -2
- data/spec/support/mongo.rb +1 -0
- data/spec/unit/adapters/filesystem/sanitizers/section_spec.rb +66 -40
- data/spec/unit/adapters/filesystem/yaml_loaders/section_spec.rb +25 -0
- data/spec/unit/errors_spec.rb +1 -1
- data/spec/unit/liquid/drops/content_entry_collection_spec.rb +3 -3
- data/spec/unit/liquid/drops/content_entry_spec.rb +4 -4
- data/spec/unit/liquid/drops/content_types_spec.rb +2 -2
- data/spec/unit/liquid/drops/metafields_spec.rb +8 -8
- data/spec/unit/liquid/drops/params_spec.rb +5 -5
- data/spec/unit/liquid/drops/section_content_proxy_spec.rb +69 -18
- data/spec/unit/liquid/drops/section_spec.rb +1 -1
- data/spec/unit/liquid/file_system_spec.rb +25 -0
- data/spec/unit/liquid/filters/array_spec.rb +140 -0
- data/spec/unit/liquid/filters/misc_spec.rb +21 -3
- data/spec/unit/liquid/filters/number_spec.rb +4 -4
- data/spec/unit/liquid/filters/text_spec.rb +4 -0
- data/spec/unit/liquid/tags/alt_page_links_spec.rb +19 -2
- data/spec/unit/liquid/tags/authorize_spec.rb +1 -1
- data/spec/unit/liquid/tags/editable/text_spec.rb +32 -4
- data/spec/unit/liquid/tags/extends_spec.rb +115 -28
- data/spec/unit/liquid/tags/global_section_spec.rb +4 -3
- data/spec/unit/liquid/tags/google_analytics_spec.rb +21 -2
- data/spec/unit/liquid/tags/inherited_block_spec.rb +18 -4
- data/spec/unit/liquid/tags/inline_editor_spec.rb +11 -0
- data/spec/unit/liquid/tags/link_to_spec.rb +1 -1
- data/spec/unit/liquid/tags/model_form_spec.rb +7 -0
- data/spec/unit/liquid/tags/page_not_found_spec.rb +14 -0
- data/spec/unit/liquid/tags/redirect_to_spec.rb +171 -0
- data/spec/unit/liquid/tags/section_spec.rb +43 -3
- data/spec/unit/liquid/tags/sections_dropzone_spec.rb +0 -1
- data/spec/unit/liquid/tags/snippet_spec.rb +9 -8
- data/spec/unit/liquid/tags/with_scope_spec.rb +80 -60
- data/spec/unit/middlewares/cache_spec.rb +186 -0
- data/spec/unit/middlewares/impersonated_entry_spec.rb +7 -0
- data/spec/unit/middlewares/locale_redirection_spec.rb +7 -0
- data/spec/unit/middlewares/locale_spec.rb +8 -1
- data/spec/unit/middlewares/page_not_found_spec.rb +46 -0
- data/spec/unit/middlewares/redirection_spec.rb +8 -0
- data/spec/unit/middlewares/renderer_spec.rb +64 -6
- data/spec/unit/middlewares/section_spec.rb +1 -0
- data/spec/unit/models/pager_spec.rb +11 -1
- data/spec/unit/repositories/section_repository_spec.rb +1 -1
- data/spec/unit/services/action_service_spec.rb +23 -3
- data/spec/unit/services/page_redirection_service_spec.rb +2 -2
- data/spec/unit/services/recaptcha_service_spec.rb +1 -1
- metadata +50 -24
@@ -5,34 +5,41 @@ module Locomotive::Steam
|
|
5
5
|
|
6
6
|
class RedirectionException < ::Exception
|
7
7
|
|
8
|
-
attr_reader :url
|
8
|
+
attr_reader :url, :permanent
|
9
9
|
|
10
|
-
def initialize(url)
|
11
|
-
@url
|
12
|
-
|
10
|
+
def initialize(url, permanent: false)
|
11
|
+
@url = url
|
12
|
+
@permanent = permanent
|
13
|
+
super("Redirect to #{url} (#{permanent ? '301': '302'})")
|
13
14
|
end
|
14
15
|
|
15
16
|
end
|
16
17
|
|
17
|
-
class
|
18
|
+
class PageNotFoundException < ::Exception
|
19
|
+
end
|
20
|
+
|
21
|
+
class TemplateError < ::Liquid::Error
|
18
22
|
|
19
23
|
LINES_RANGE = 10
|
20
24
|
|
21
|
-
attr_accessor :
|
25
|
+
attr_accessor :source, :original_backtrace
|
22
26
|
|
23
|
-
def initialize(message,
|
24
|
-
@file, @source, @line, @original_backtrace = file, source, line, original_backtrace
|
27
|
+
def initialize(message, template_name, source, line_number, original_backtrace)
|
25
28
|
super(message)
|
29
|
+
self.template_name = template_name
|
30
|
+
self.line_number = line_number
|
31
|
+
self.source = source
|
32
|
+
self.original_backtrace = original_backtrace
|
26
33
|
end
|
27
34
|
|
28
35
|
def code_lines
|
29
|
-
return [] if source.blank? ||
|
36
|
+
return [] if source.blank? || line_number.nil?
|
30
37
|
|
31
38
|
lines = source.split("\n")
|
32
39
|
|
33
|
-
start =
|
40
|
+
start = line_number - (LINES_RANGE / 2)
|
34
41
|
start = 1 if start <= 0
|
35
|
-
finish =
|
42
|
+
finish = line_number + (LINES_RANGE / 2)
|
36
43
|
|
37
44
|
(start..finish).map { |i| [i, lines[i - 1]] }
|
38
45
|
end
|
@@ -41,21 +48,38 @@ module Locomotive::Steam
|
|
41
48
|
original_backtrace
|
42
49
|
end
|
43
50
|
|
51
|
+
private
|
52
|
+
|
53
|
+
def message_prefix
|
54
|
+
""
|
55
|
+
# "Liquid parsing error - "
|
56
|
+
end
|
57
|
+
|
44
58
|
end
|
45
59
|
|
46
|
-
class
|
60
|
+
class LiquidError < TemplateError
|
47
61
|
|
48
62
|
def initialize(error, file, source)
|
49
|
-
message
|
50
|
-
|
51
|
-
backtrace
|
63
|
+
message = error.message
|
64
|
+
line_number = error.respond_to?(:line_number) ? error.line_number : error.line
|
65
|
+
backtrace = error.backtrace
|
52
66
|
|
53
|
-
super(message, file, source,
|
67
|
+
super(message, file, source, line_number, backtrace)
|
54
68
|
end
|
55
69
|
|
56
70
|
end
|
57
71
|
|
58
|
-
class
|
72
|
+
class RenderError < LiquidError
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def message_prefix
|
77
|
+
"Render - "
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
class JsonParsingError < TemplateError
|
59
83
|
|
60
84
|
def initialize(error, file, source)
|
61
85
|
line = if error.message =~ /at line ([0-9]+)/
|
@@ -67,9 +91,15 @@ module Locomotive::Steam
|
|
67
91
|
super(error.message, file, source, line, error.backtrace)
|
68
92
|
end
|
69
93
|
|
94
|
+
private
|
95
|
+
|
96
|
+
def message_prefix
|
97
|
+
"JSON parsing error - "
|
98
|
+
end
|
99
|
+
|
70
100
|
end
|
71
101
|
|
72
|
-
class ActionError <
|
102
|
+
class ActionError < TemplateError
|
73
103
|
|
74
104
|
attr_accessor :action
|
75
105
|
|
@@ -77,6 +107,12 @@ module Locomotive::Steam
|
|
77
107
|
super(error.message, nil, script, 0, error.backtrace)
|
78
108
|
end
|
79
109
|
|
110
|
+
private
|
111
|
+
|
112
|
+
def message_prefix
|
113
|
+
"Action error - "
|
114
|
+
end
|
115
|
+
|
80
116
|
end
|
81
117
|
|
82
118
|
end
|
@@ -38,7 +38,7 @@ module Locomotive
|
|
38
38
|
{ 'create' => public_submission_url }
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
41
|
+
def liquid_method_missing(meth)
|
42
42
|
if (meth.to_s =~ /^group_by_(.+)$/) == 0
|
43
43
|
repository.group_by_select_option($1)
|
44
44
|
elsif (meth.to_s =~ /^(.+)_options$/) == 0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
module Drops
|
5
|
+
|
6
|
+
# Used to render the content of the parent block.
|
7
|
+
#
|
8
|
+
# {% extends home %}
|
9
|
+
# {% block content }{{ block.super }}{% endblock %}
|
10
|
+
#
|
11
|
+
class InheritedBlock < ::Liquid::Drop
|
12
|
+
def initialize(block)
|
13
|
+
@block = block
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
@block.name
|
18
|
+
end
|
19
|
+
|
20
|
+
def super
|
21
|
+
@block.call_super(@context)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -10,7 +10,7 @@ module Locomotive
|
|
10
10
|
alias :count :size
|
11
11
|
alias :length :size
|
12
12
|
|
13
|
-
def
|
13
|
+
def liquid_method_missing(meth)
|
14
14
|
find_value(meth.to_s)
|
15
15
|
end
|
16
16
|
|
@@ -79,7 +79,7 @@ module Locomotive
|
|
79
79
|
|
80
80
|
class Metafields < Base
|
81
81
|
|
82
|
-
def
|
82
|
+
def liquid_method_missing(meth)
|
83
83
|
find_namespace(meth.to_s)
|
84
84
|
end
|
85
85
|
|
@@ -38,8 +38,16 @@ module Locomotive
|
|
38
38
|
@section.definition['class']
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
@content['anchor'] || id
|
41
|
+
def anchor_id
|
42
|
+
"#{@content['anchor'] || id}-section"
|
43
|
+
end
|
44
|
+
|
45
|
+
def locomotive_attributes
|
46
|
+
%(data-locomotive-section-id="#{id}" data-locomotive-section-type="#{type}").tap do
|
47
|
+
# let Steam know that we won't need to wrap the section HTML
|
48
|
+
# into an extra DIV layer.
|
49
|
+
@context['is_section_locomotive_attributes_displayed'] = true
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
53
|
def blocks
|
@@ -12,12 +12,15 @@ module Locomotive
|
|
12
12
|
@content, @settings = content, settings
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def liquid_method_missing(name)
|
16
16
|
value = @content[name.to_s]
|
17
17
|
|
18
|
+
return nil if value.blank?
|
19
|
+
|
18
20
|
case type_of(name)
|
19
21
|
when 'url' then SectionUrlField.new(*url_finder.url_for(value))
|
20
22
|
when 'image_picker' then SectionImagePickerField.new(value)
|
23
|
+
when 'integer' then value.to_i
|
21
24
|
when 'text' then url_finder.decode_urls_for(value)
|
22
25
|
else value
|
23
26
|
end
|
@@ -68,6 +71,10 @@ module Locomotive
|
|
68
71
|
@attributes[:cropped]
|
69
72
|
end
|
70
73
|
|
74
|
+
def present?
|
75
|
+
self.source.present?
|
76
|
+
end
|
77
|
+
|
71
78
|
def to_s
|
72
79
|
self.cropped || self.source || ''
|
73
80
|
end
|
@@ -78,7 +85,7 @@ module Locomotive
|
|
78
85
|
class SectionUrlField < ::Liquid::Drop
|
79
86
|
|
80
87
|
def initialize(url, new_window = false)
|
81
|
-
@url, @new_window = url
|
88
|
+
@url, @new_window = url, new_window
|
82
89
|
end
|
83
90
|
|
84
91
|
def new_window
|
@@ -89,6 +96,10 @@ module Locomotive
|
|
89
96
|
!!@new_window ? 'target="_blank"' : ''
|
90
97
|
end
|
91
98
|
|
99
|
+
def present?
|
100
|
+
@url.present?
|
101
|
+
end
|
102
|
+
|
92
103
|
def to_s
|
93
104
|
@url
|
94
105
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
|
5
|
+
# A Liquid file system is a way to let your templates retrieve other templates for use with the include and sections tags.
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
#
|
9
|
+
# Liquid::Template.file_system = Liquid::LocalFileSystem.new(template_path)
|
10
|
+
# liquid = Liquid::Template.parse(template)
|
11
|
+
#
|
12
|
+
# This will parse the template from both the DB or the Filesystem.
|
13
|
+
#
|
14
|
+
class FileSystem
|
15
|
+
|
16
|
+
attr_reader :section_finder, :snippet_finder
|
17
|
+
|
18
|
+
def initialize(section_finder: nil, snippet_finder: nil)
|
19
|
+
@section_finder, @snippet_finder = section_finder, snippet_finder
|
20
|
+
end
|
21
|
+
|
22
|
+
# Called by Liquid to retrieve a template file
|
23
|
+
def read_template_file(template_path)
|
24
|
+
type, name = template_path.split('--')
|
25
|
+
|
26
|
+
entity = (
|
27
|
+
case type
|
28
|
+
when 'sections'
|
29
|
+
section_finder.find(name)
|
30
|
+
when 'snippets'
|
31
|
+
snippet_finder.find(name)
|
32
|
+
else
|
33
|
+
raise ::Liquid::FileSystemError, "This liquid context does not allow #{type}."
|
34
|
+
end
|
35
|
+
)
|
36
|
+
|
37
|
+
raise ::Liquid::FileSystemError, "Unable to find #{name} in the #{type} folder" if entity.nil?
|
38
|
+
|
39
|
+
entity.liquid_source
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
module Filters
|
5
|
+
|
6
|
+
module Array
|
7
|
+
|
8
|
+
def pop(array, input = 1)
|
9
|
+
return array unless array.is_a?(::Array)
|
10
|
+
new_ary = array.dup
|
11
|
+
new_ary.pop(input.to_i || 1)
|
12
|
+
new_ary
|
13
|
+
end
|
14
|
+
|
15
|
+
def push(array, input)
|
16
|
+
return array unless array.is_a?(::Array)
|
17
|
+
new_ary = array.dup
|
18
|
+
new_ary.push(input)
|
19
|
+
new_ary
|
20
|
+
end
|
21
|
+
|
22
|
+
def shift(array, input = 1)
|
23
|
+
return array unless array.is_a?(::Array)
|
24
|
+
new_ary = array.dup
|
25
|
+
new_ary.shift(input.to_i || 1)
|
26
|
+
new_ary
|
27
|
+
end
|
28
|
+
|
29
|
+
def unshift(array, input)
|
30
|
+
return array unless array.is_a?(::Array)
|
31
|
+
new_ary = array.dup
|
32
|
+
new_ary.unshift(*input)
|
33
|
+
new_ary
|
34
|
+
end
|
35
|
+
|
36
|
+
def in_groups_of(array, number, fill_with = nil)
|
37
|
+
return array unless array.respond_to?(:all) || array.respond_to?(:each_slice)
|
38
|
+
|
39
|
+
number = number.to_i
|
40
|
+
grouped_array = array.respond_to?(:all) ? array.all : array
|
41
|
+
|
42
|
+
if fill_with != false
|
43
|
+
# size % number gives how many extra we have;
|
44
|
+
# subtracting from number gives how many to add;
|
45
|
+
# modulo number ensures we don't add group of just fill.
|
46
|
+
padding = (number - grouped_array.size % number) % number
|
47
|
+
grouped_array = grouped_array + ::Array.new(padding, fill_with)
|
48
|
+
end
|
49
|
+
|
50
|
+
grouped_array.each_slice(number).to_a
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
::Liquid::Template.register_filter(Array)
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -4,6 +4,14 @@ module Locomotive
|
|
4
4
|
module Filters
|
5
5
|
module Misc
|
6
6
|
|
7
|
+
def blank?(input)
|
8
|
+
input.blank?
|
9
|
+
end
|
10
|
+
|
11
|
+
def present?(input)
|
12
|
+
input.present?
|
13
|
+
end
|
14
|
+
|
7
15
|
# was called modulo at first
|
8
16
|
def str_modulo(word, index, modulo)
|
9
17
|
(index.to_i + 1) % modulo == 0 ? word : ''
|
@@ -38,10 +46,12 @@ module Locomotive
|
|
38
46
|
elsif property == 'to_i'.freeze
|
39
47
|
e.to_i
|
40
48
|
elsif e.respond_to?(:[])
|
41
|
-
e[property]
|
49
|
+
r = e[property]
|
50
|
+
r.is_a?(Proc) ? r.call : r
|
42
51
|
end
|
43
52
|
end
|
44
|
-
|
53
|
+
rescue TypeError
|
54
|
+
raise_property_error(property)
|
45
55
|
end
|
46
56
|
|
47
57
|
def hexdigest(input, key, digest = nil)
|
@@ -4,15 +4,15 @@ module Locomotive
|
|
4
4
|
module Filters
|
5
5
|
module Number
|
6
6
|
|
7
|
-
def money(input,
|
7
|
+
def money(input, options = nil)
|
8
8
|
NumberProxyHelper.new(:currency, @context).invoke(input, options)
|
9
9
|
end
|
10
10
|
|
11
|
-
def percentage(input,
|
11
|
+
def percentage(input, options = nil)
|
12
12
|
NumberProxyHelper.new(:percentage, @context).invoke(input, options)
|
13
13
|
end
|
14
14
|
|
15
|
-
def human_size(input,
|
15
|
+
def human_size(input, options = nil)
|
16
16
|
NumberProxyHelper.new(:human_size, @context).invoke(input, options)
|
17
17
|
end
|
18
18
|
|
@@ -30,17 +30,18 @@ module Locomotive
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def invoke(input, options)
|
33
|
-
|
34
|
-
send :"number_to_#{@name}", input, _options
|
33
|
+
send :"number_to_#{@name}", input, interpolate_options(options)
|
35
34
|
end
|
36
35
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
def interpolate_options(options)
|
37
|
+
(options || {}).transform_values do |option|
|
38
|
+
if option.is_a?(String)
|
39
|
+
_option = ::Liquid::Expression.parse(option)
|
40
|
+
@context.evaluate(_option) || option
|
41
|
+
else
|
42
|
+
option
|
43
|
+
end
|
44
|
+
end
|
44
45
|
end
|
45
46
|
|
46
47
|
end
|
@@ -1,9 +1,48 @@
|
|
1
|
+
# Enhance the IF condition to write the following statement:
|
2
|
+
#
|
3
|
+
# {% if value is present %}Value is not blank{% endif %}
|
4
|
+
#
|
5
|
+
Liquid::Condition.operators['is'.freeze] = lambda { |cond, left, right| cond.send(:equal_variables, left, right) }
|
6
|
+
|
1
7
|
module Liquid
|
8
|
+
|
9
|
+
class Expression
|
10
|
+
|
11
|
+
class << self
|
12
|
+
alias_method :parse_without_extra_literals, :parse
|
13
|
+
end
|
14
|
+
|
15
|
+
EXTRA_LITERALS = {
|
16
|
+
'present' => MethodLiteral.new(:present?, '').freeze
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def self.parse(markup)
|
20
|
+
if EXTRA_LITERALS.key?(markup)
|
21
|
+
EXTRA_LITERALS[markup]
|
22
|
+
else
|
23
|
+
parse_without_extra_literals(markup)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
class ParseContext
|
30
|
+
|
31
|
+
def []=(option_key, value)
|
32
|
+
@options[option_key] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def merge(options)
|
36
|
+
@template_options.merge(options)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
2
41
|
module StandardFilters
|
3
42
|
|
4
43
|
private
|
5
44
|
|
6
|
-
#
|
45
|
+
# FIXME: Handle DateTime, Date and Time objects, convert them
|
7
46
|
# into seconds (integer)
|
8
47
|
def to_number(obj)
|
9
48
|
case obj
|
@@ -19,32 +58,32 @@ module Liquid
|
|
19
58
|
end
|
20
59
|
|
21
60
|
end
|
22
|
-
end
|
23
61
|
|
24
|
-
|
25
|
-
module OptionsBuilder
|
26
|
-
|
27
|
-
private
|
62
|
+
class PartialCache
|
28
63
|
|
29
|
-
def
|
30
|
-
|
64
|
+
def self.load(template_name, context:, parse_context:)
|
65
|
+
begin
|
66
|
+
cached_partials = (context.registers[:cached_partials] ||= {})
|
67
|
+
cached = cached_partials[template_name]
|
68
|
+
return cached if cached
|
31
69
|
|
32
|
-
|
70
|
+
file_system = (context.registers[:file_system] ||= ::Liquid::Template.file_system)
|
71
|
+
source = file_system.read_template_file(template_name)
|
72
|
+
parse_context.partial = true
|
33
73
|
|
34
|
-
|
74
|
+
partial = ::Liquid::Template.parse(source, parse_context)
|
75
|
+
cached_partials[template_name] = partial
|
35
76
|
|
36
|
-
Solid::Arguments.parse(string)
|
37
|
-
end
|
38
77
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
78
|
+
rescue ::Liquid::SyntaxError => e
|
79
|
+
# FIXME: we had to reload the template one more time. Not ideal.
|
80
|
+
file_system = (context.registers[:file_system] ||= ::Liquid::Template.file_system)
|
81
|
+
source = file_system.read_template_file(template_name)
|
82
|
+
raise Locomotive::Steam::LiquidError.new(e, template_name, source)
|
44
83
|
end
|
84
|
+
ensure
|
85
|
+
parse_context.partial = false
|
45
86
|
end
|
46
87
|
|
47
88
|
end
|
48
89
|
end
|
49
|
-
|
50
|
-
Liquid::Tag.send(:include, Liquid::OptionsBuilder)
|
@@ -13,10 +13,12 @@ module Locomotive
|
|
13
13
|
if @site.locales.size == 1
|
14
14
|
''
|
15
15
|
else
|
16
|
+
ending_path = context['alt_page_links_ending_path'] || ''
|
17
|
+
|
16
18
|
(
|
17
|
-
[%(<link rel="alternate" hreflang="x-default" href="#{url_for(@site.default_locale, true)}" />)] +
|
19
|
+
[%(<link rel="alternate" hreflang="x-default" href="#{url_for(@site.default_locale, ending_path, true)}" />)] +
|
18
20
|
@site.locales.map do |locale|
|
19
|
-
%(<link rel="alternate" hreflang="#{locale}" href="#{url_for(locale)}" />)
|
21
|
+
%(<link rel="alternate" hreflang="#{locale}" href="#{url_for(locale, ending_path)}" />)
|
20
22
|
end
|
21
23
|
).join("\n")
|
22
24
|
end
|
@@ -30,15 +32,17 @@ module Locomotive
|
|
30
32
|
#
|
31
33
|
# Note: the index page has a different behaviour because rendering "/" depends
|
32
34
|
# on the language returned by the browser (so might be different based on the user session).
|
33
|
-
def url_for(locale, default = false)
|
35
|
+
def url_for(locale, ending_path = '', default = false)
|
34
36
|
change_page_locale(locale, @page) do
|
35
|
-
fullpath = services.url_builder.url_for(@page.send(:_source), locale, @page.index? && !default ? true : nil)
|
37
|
+
fullpath = services.url_builder.url_for(@page.send(:_source), locale, @site.prefix_default_locale) #@page.index? && !default ? true : nil)
|
36
38
|
|
37
39
|
if @page.index? && default
|
38
40
|
fullpath.gsub!(/\/#{locale}$/, '/')
|
39
41
|
end
|
40
42
|
|
41
|
-
|
43
|
+
fullpath.gsub!(/\/$/, '') if ending_path.present?
|
44
|
+
|
45
|
+
@base_url + fullpath + ending_path
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
module Tags
|
5
|
+
module Concerns
|
6
|
+
|
7
|
+
# Many of Liquid tags have attributes (like options)
|
8
|
+
# This module makes sure we use the same reliable way to
|
9
|
+
# extract and evaluate them.
|
10
|
+
|
11
|
+
module Attributes
|
12
|
+
|
13
|
+
attr_reader :attributes, :raw_attributes
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def parse_attributes(markup, default = {})
|
18
|
+
@attributes = default || {}
|
19
|
+
@raw_attributes = {}
|
20
|
+
|
21
|
+
return if markup.blank?
|
22
|
+
|
23
|
+
markup.scan(tag_attributes_regexp) do |key, value|
|
24
|
+
_key = key.to_sym
|
25
|
+
|
26
|
+
@attributes[_key] = block_given? ? yield(value) : ::Liquid::Expression.parse(value)
|
27
|
+
@raw_attributes[_key] = value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def evaluate_attributes(context)
|
32
|
+
@attributes = @attributes.transform_values do |attribute|
|
33
|
+
context.evaluate(attribute)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def tag_attributes_regexp
|
38
|
+
::Liquid::TagAttributes
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|