liquid 5.5.0 → 5.6.0

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.
@@ -85,6 +85,4 @@ module Liquid
85
85
  raise_tag_never_closed("raw")
86
86
  end
87
87
  end
88
-
89
- Template.register_tag('comment', Comment)
90
88
  end
@@ -17,6 +17,4 @@ module Liquid
17
17
  output
18
18
  end
19
19
  end
20
-
21
- Template.register_tag('continue', Continue)
22
20
  end
@@ -26,14 +26,20 @@ module Liquid
26
26
  when NamedSyntax
27
27
  @variables = variables_from_string(Regexp.last_match(2))
28
28
  @name = parse_expression(Regexp.last_match(1))
29
+ @is_named = true
29
30
  when SimpleSyntax
30
31
  @variables = variables_from_string(markup)
31
32
  @name = @variables.to_s
33
+ @is_named = !@name.match?(/\w+:0x\h{8}/)
32
34
  else
33
35
  raise SyntaxError, options[:locale].t("errors.syntax.cycle")
34
36
  end
35
37
  end
36
38
 
39
+ def named?
40
+ @is_named
41
+ end
42
+
37
43
  def render_to_output_buffer(context, output)
38
44
  context.registers[:cycle] ||= {}
39
45
 
@@ -72,6 +78,4 @@ module Liquid
72
78
  end
73
79
  end
74
80
  end
75
-
76
- Template.register_tag('cycle', Cycle)
77
81
  end
@@ -35,6 +35,4 @@ module Liquid
35
35
  output
36
36
  end
37
37
  end
38
-
39
- Template.register_tag('decrement', Decrement)
40
38
  end
@@ -36,6 +36,4 @@ module Liquid
36
36
  end
37
37
  end
38
38
  end
39
-
40
- Template.register_tag('echo', Echo)
41
39
  end
@@ -201,6 +201,4 @@ module Liquid
201
201
  end
202
202
  end
203
203
  end
204
-
205
- Template.register_tag('for', For)
206
204
  end
@@ -111,7 +111,7 @@ module Liquid
111
111
  def parse_binary_comparisons(p)
112
112
  condition = parse_comparison(p)
113
113
  first_condition = condition
114
- while (op = (p.id?('and') || p.id?('or')))
114
+ while (op = p.id?('and') || p.id?('or'))
115
115
  child_condition = parse_comparison(p)
116
116
  condition.send(op, child_condition)
117
117
  condition = child_condition
@@ -135,6 +135,4 @@ module Liquid
135
135
  end
136
136
  end
137
137
  end
138
-
139
- Template.register_tag('if', If)
140
138
  end
@@ -14,6 +14,4 @@ module Liquid
14
14
  output
15
15
  end
16
16
  end
17
-
18
- Template.register_tag('ifchanged', Ifchanged)
19
17
  end
@@ -110,6 +110,4 @@ module Liquid
110
110
  end
111
111
  end
112
112
  end
113
-
114
- Template.register_tag('include', Include)
115
113
  end
@@ -35,6 +35,4 @@ module Liquid
35
35
  output
36
36
  end
37
37
  end
38
-
39
- Template.register_tag('increment', Increment)
40
38
  end
@@ -25,6 +25,4 @@ module Liquid
25
25
  true
26
26
  end
27
27
  end
28
-
29
- Template.register_tag('#', InlineComment)
30
28
  end
@@ -56,6 +56,4 @@ module Liquid
56
56
  end
57
57
  end
58
58
  end
59
-
60
- Template.register_tag('raw', Raw)
61
59
  end
@@ -108,6 +108,4 @@ module Liquid
108
108
  end
109
109
  end
110
110
  end
111
-
112
- Template.register_tag('render', Render)
113
111
  end
@@ -65,6 +65,12 @@ module Liquid
65
65
  super
66
66
  output << '</td>'
67
67
 
68
+ # Handle any interrupts if they exist.
69
+ if context.interrupt?
70
+ interrupt = context.pop_interrupt
71
+ break if interrupt.is_a?(BreakInterrupt)
72
+ end
73
+
68
74
  if tablerowloop.col_last && !tablerowloop.last
69
75
  output << "</tr>\n<tr class=\"row#{tablerowloop.row + 1}\">"
70
76
  end
@@ -91,6 +97,4 @@ module Liquid
91
97
  raise Liquid::ArgumentError, "invalid integer"
92
98
  end
93
99
  end
94
-
95
- Template.register_tag('tablerow', TableRow)
96
100
  end
@@ -44,6 +44,4 @@ module Liquid
44
44
  output
45
45
  end
46
46
  end
47
-
48
- Template.register_tag('unless', Unless)
49
47
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tags/table_row"
4
+ require_relative "tags/echo"
5
+ require_relative "tags/if"
6
+ require_relative "tags/break"
7
+ require_relative "tags/inline_comment"
8
+ require_relative "tags/for"
9
+ require_relative "tags/assign"
10
+ require_relative "tags/ifchanged"
11
+ require_relative "tags/case"
12
+ require_relative "tags/include"
13
+ require_relative "tags/continue"
14
+ require_relative "tags/capture"
15
+ require_relative "tags/decrement"
16
+ require_relative "tags/unless"
17
+ require_relative "tags/increment"
18
+ require_relative "tags/comment"
19
+ require_relative "tags/raw"
20
+ require_relative "tags/render"
21
+ require_relative "tags/cycle"
22
+
23
+ module Liquid
24
+ module Tags
25
+ STANDARD_TAGS = {
26
+ 'cycle' => Cycle,
27
+ 'render' => Render,
28
+ 'raw' => Raw,
29
+ 'comment' => Comment,
30
+ 'increment' => Increment,
31
+ 'unless' => Unless,
32
+ 'decrement' => Decrement,
33
+ 'capture' => Capture,
34
+ 'continue' => Continue,
35
+ 'include' => Include,
36
+ 'case' => Case,
37
+ 'ifchanged' => Ifchanged,
38
+ 'assign' => Assign,
39
+ 'for' => For,
40
+ '#' => InlineComment,
41
+ 'break' => Break,
42
+ 'if' => If,
43
+ 'echo' => Echo,
44
+ 'tablerow' => TableRow,
45
+ }.freeze
46
+ end
47
+ end
@@ -18,89 +18,78 @@ module Liquid
18
18
  attr_accessor :root, :name
19
19
  attr_reader :resource_limits, :warnings
20
20
 
21
- class TagRegistry
22
- include Enumerable
21
+ attr_reader :profiler
23
22
 
24
- def initialize
25
- @tags = {}
26
- @cache = {}
23
+ class << self
24
+ # Sets how strict the parser should be.
25
+ # :lax acts like liquid 2.5 and silently ignores malformed tags in most cases.
26
+ # :warn is the default and will give deprecation warnings when invalid syntax is used.
27
+ # :strict will enforce correct syntax.
28
+ def error_mode=(mode)
29
+ Deprecations.warn("Template.error_mode=", "Environment#error_mode=")
30
+ Environment.default.error_mode = mode
27
31
  end
28
32
 
29
- def [](tag_name)
30
- return nil unless @tags.key?(tag_name)
31
- return @cache[tag_name] if Liquid.cache_classes
32
-
33
- lookup_class(@tags[tag_name]).tap { |o| @cache[tag_name] = o }
33
+ def error_mode
34
+ Environment.default.error_mode
34
35
  end
35
36
 
36
- def []=(tag_name, klass)
37
- @tags[tag_name] = klass.name
38
- @cache[tag_name] = klass
37
+ def default_exception_renderer=(renderer)
38
+ Deprecations.warn("Template.default_exception_renderer=", "Environment#exception_renderer=")
39
+ Environment.default.exception_renderer = renderer
39
40
  end
40
41
 
41
- def delete(tag_name)
42
- @tags.delete(tag_name)
43
- @cache.delete(tag_name)
42
+ def default_exception_renderer
43
+ Environment.default.exception_renderer
44
44
  end
45
45
 
46
- def each(&block)
47
- @tags.each(&block)
46
+ def file_system=(file_system)
47
+ Deprecations.warn("Template.file_system=", "Environment#file_system=")
48
+ Environment.default.file_system = file_system
48
49
  end
49
50
 
50
- private
51
-
52
- def lookup_class(name)
53
- Object.const_get(name)
51
+ def file_system
52
+ Environment.default.file_system
54
53
  end
55
- end
56
-
57
- attr_reader :profiler
58
54
 
59
- class << self
60
- # Sets how strict the parser should be.
61
- # :lax acts like liquid 2.5 and silently ignores malformed tags in most cases.
62
- # :warn is the default and will give deprecation warnings when invalid syntax is used.
63
- # :strict will enforce correct syntax.
64
- attr_accessor :error_mode
65
- Template.error_mode = :lax
66
-
67
- attr_accessor :default_exception_renderer
68
- Template.default_exception_renderer = lambda do |exception|
69
- exception
55
+ def tags
56
+ Environment.default.tags
70
57
  end
71
58
 
72
- attr_accessor :file_system
73
- Template.file_system = BlankFileSystem.new
74
-
75
- attr_accessor :tags
76
- Template.tags = TagRegistry.new
77
- private :tags=
78
-
79
59
  def register_tag(name, klass)
80
- tags[name.to_s] = klass
60
+ Deprecations.warn("Template.register_tag", "Environment#register_tag")
61
+ Environment.default.register_tag(name, klass)
81
62
  end
82
63
 
83
64
  # Pass a module with filter methods which should be available
84
65
  # to all liquid views. Good for registering the standard library
85
66
  def register_filter(mod)
86
- StrainerFactory.add_global_filter(mod)
67
+ Deprecations.warn("Template.register_filter", "Environment#register_filter")
68
+ Environment.default.register_filter(mod)
87
69
  end
88
70
 
89
- attr_accessor :default_resource_limits
90
- Template.default_resource_limits = {}
91
- private :default_resource_limits=
71
+ private def default_resource_limits=(limits)
72
+ Deprecations.warn("Template.default_resource_limits=", "Environment#default_resource_limits=")
73
+ Environment.default.default_resource_limits = limits
74
+ end
75
+
76
+ def default_resource_limits
77
+ Environment.default.default_resource_limits
78
+ end
92
79
 
93
80
  # creates a new <tt>Template</tt> object from liquid source code
94
81
  # To enable profiling, pass in <tt>profile: true</tt> as an option.
95
82
  # See Liquid::Profiler for more information
96
83
  def parse(source, options = {})
97
- new.parse(source, options)
84
+ environment = options[:environment] || Environment.default
85
+ new(environment: environment).parse(source, options)
98
86
  end
99
87
  end
100
88
 
101
- def initialize
89
+ def initialize(environment: Environment.default)
90
+ @environment = environment
102
91
  @rethrow_errors = false
103
- @resource_limits = ResourceLimits.new(Template.default_resource_limits)
92
+ @resource_limits = ResourceLimits.new(environment.default_resource_limits)
104
93
  end
105
94
 
106
95
  # Parse source code.
@@ -162,11 +151,11 @@ module Liquid
162
151
  c
163
152
  when Liquid::Drop
164
153
  drop = args.shift
165
- drop.context = Context.new([drop, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits)
154
+ drop.context = Context.new([drop, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits, {}, @environment)
166
155
  when Hash
167
- Context.new([args.shift, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits)
156
+ Context.new([args.shift, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits, {}, @environment)
168
157
  when nil
169
- Context.new(assigns, instance_assigns, registers, @rethrow_errors, @resource_limits)
158
+ Context.new(assigns, instance_assigns, registers, @rethrow_errors, @resource_limits, {}, @environment)
170
159
  else
171
160
  raise ArgumentError, "Expected Hash or Liquid::Context as parameter"
172
161
  end
@@ -226,8 +215,14 @@ module Liquid
226
215
  @options = options
227
216
  @profiling = profiling
228
217
  @line_numbers = options[:line_numbers] || @profiling
229
- parse_context = options.is_a?(ParseContext) ? options : ParseContext.new(options)
230
- @warnings = parse_context.warnings
218
+ parse_context = if options.is_a?(ParseContext)
219
+ options
220
+ else
221
+ opts = options.key?(:environment) ? options : options.merge(environment: @environment)
222
+ ParseContext.new(opts)
223
+ end
224
+
225
+ @warnings = parse_context.warnings
231
226
  parse_context
232
227
  end
233
228
 
@@ -5,7 +5,7 @@ module Liquid
5
5
  attr_reader :line_number, :for_liquid_tag
6
6
 
7
7
  def initialize(source, line_numbers = false, line_number: nil, for_liquid_tag: false)
8
- @source = source
8
+ @source = source.to_s.to_str
9
9
  @line_number = line_number || (line_numbers ? 1 : nil)
10
10
  @for_liquid_tag = for_liquid_tag
11
11
  @offset = 0
@@ -68,7 +68,7 @@ module Liquid
68
68
  @name = parse_context.parse_expression(p.expression)
69
69
  while p.consume?(:pipe)
70
70
  filtername = p.consume(:id)
71
- filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
71
+ filterargs = p.consume?(:colon) ? parse_filterargs(p) : Const::EMPTY_ARRAY
72
72
  @filters << parse_filter_expressions(filtername, filterargs)
73
73
  end
74
74
  p.consume(:end_of_string)
@@ -95,15 +95,21 @@ module Liquid
95
95
 
96
96
  def render_to_output_buffer(context, output)
97
97
  obj = render(context)
98
+ render_obj_to_output(obj, output)
99
+ output
100
+ end
98
101
 
99
- if obj.is_a?(Array)
100
- output << obj.join
101
- elsif obj.nil?
102
- else
102
+ def render_obj_to_output(obj, output)
103
+ case obj
104
+ when NilClass
105
+ # Do nothing
106
+ when Array
107
+ obj.each do |o|
108
+ render_obj_to_output(o, output)
109
+ end
110
+ when
103
111
  output << obj.to_s
104
112
  end
105
-
106
- output
107
113
  end
108
114
 
109
115
  def disabled?(_context)
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Liquid
5
- VERSION = "5.5.0"
5
+ VERSION = "5.6.0"
6
6
  end
data/lib/liquid.rb CHANGED
@@ -44,13 +44,20 @@ module Liquid
44
44
  VariableParser = /\[(?>[^\[\]]+|\g<0>)*\]|#{VariableSegment}+\??/o
45
45
 
46
46
  RAISE_EXCEPTION_LAMBDA = ->(_e) { raise }
47
-
48
- singleton_class.send(:attr_accessor, :cache_classes)
49
- self.cache_classes = true
50
47
  end
51
48
 
52
49
  require "liquid/version"
50
+ require "liquid/deprecations"
51
+ require "liquid/const"
52
+ require 'liquid/standardfilters'
53
+ require 'liquid/file_system'
54
+ require 'liquid/parser_switching'
55
+ require 'liquid/tag'
56
+ require 'liquid/block'
53
57
  require 'liquid/parse_tree_visitor'
58
+ require 'liquid/interrupts'
59
+ require 'liquid/tags'
60
+ require "liquid/environment"
54
61
  require 'liquid/lexer'
55
62
  require 'liquid/parser'
56
63
  require 'liquid/i18n'
@@ -61,23 +68,16 @@ require 'liquid/extensions'
61
68
  require 'liquid/errors'
62
69
  require 'liquid/interrupts'
63
70
  require 'liquid/strainer_template'
64
- require 'liquid/strainer_factory'
65
71
  require 'liquid/expression'
66
72
  require 'liquid/context'
67
- require 'liquid/parser_switching'
68
73
  require 'liquid/tag'
69
- require 'liquid/tag/disabler'
70
- require 'liquid/tag/disableable'
71
- require 'liquid/block'
72
74
  require 'liquid/block_body'
73
75
  require 'liquid/document'
74
76
  require 'liquid/variable'
75
77
  require 'liquid/variable_lookup'
76
78
  require 'liquid/range_lookup'
77
- require 'liquid/file_system'
78
79
  require 'liquid/resource_limits'
79
80
  require 'liquid/template'
80
- require 'liquid/standardfilters'
81
81
  require 'liquid/condition'
82
82
  require 'liquid/utils'
83
83
  require 'liquid/tokenizer'
@@ -86,7 +86,3 @@ require 'liquid/partial_cache'
86
86
  require 'liquid/usage'
87
87
  require 'liquid/registers'
88
88
  require 'liquid/template_factory'
89
-
90
- # Load all the tags of the standard library
91
- #
92
- Dir["#{__dir__}/liquid/tags/*.rb"].each { |f| require f }
metadata CHANGED
@@ -1,15 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: liquid
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.5.0
4
+ version: 5.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Lütke
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-03-21 00:00:00.000000000 Z
10
+ date: 2024-12-19 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: strscan
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: bigdecimal
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
13
40
  - !ruby/object:Gem::Dependency
14
41
  name: rake
15
42
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +65,6 @@ dependencies:
38
65
  - - ">="
39
66
  - !ruby/object:Gem::Version
40
67
  version: '0'
41
- description:
42
68
  email:
43
69
  - tobi@leetsoft.com
44
70
  executables: []
@@ -54,9 +80,12 @@ files:
54
80
  - lib/liquid/block.rb
55
81
  - lib/liquid/block_body.rb
56
82
  - lib/liquid/condition.rb
83
+ - lib/liquid/const.rb
57
84
  - lib/liquid/context.rb
85
+ - lib/liquid/deprecations.rb
58
86
  - lib/liquid/document.rb
59
87
  - lib/liquid/drop.rb
88
+ - lib/liquid/environment.rb
60
89
  - lib/liquid/errors.rb
61
90
  - lib/liquid/expression.rb
62
91
  - lib/liquid/extensions.rb
@@ -77,12 +106,12 @@ files:
77
106
  - lib/liquid/registers.rb
78
107
  - lib/liquid/resource_limits.rb
79
108
  - lib/liquid/standardfilters.rb
80
- - lib/liquid/strainer_factory.rb
81
109
  - lib/liquid/strainer_template.rb
82
110
  - lib/liquid/tablerowloop_drop.rb
83
111
  - lib/liquid/tag.rb
84
112
  - lib/liquid/tag/disableable.rb
85
113
  - lib/liquid/tag/disabler.rb
114
+ - lib/liquid/tags.rb
86
115
  - lib/liquid/tags/assign.rb
87
116
  - lib/liquid/tags/break.rb
88
117
  - lib/liquid/tags/capture.rb
@@ -110,12 +139,11 @@ files:
110
139
  - lib/liquid/variable.rb
111
140
  - lib/liquid/variable_lookup.rb
112
141
  - lib/liquid/version.rb
113
- homepage: http://www.liquidmarkup.org
142
+ homepage: https://shopify.github.io/liquid/
114
143
  licenses:
115
144
  - MIT
116
145
  metadata:
117
146
  allowed_push_host: https://rubygems.org
118
- post_install_message:
119
147
  rdoc_options: []
120
148
  require_paths:
121
149
  - lib
@@ -123,15 +151,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
151
  requirements:
124
152
  - - ">="
125
153
  - !ruby/object:Gem::Version
126
- version: 2.7.0
154
+ version: 3.0.0
127
155
  required_rubygems_version: !ruby/object:Gem::Requirement
128
156
  requirements:
129
157
  - - ">="
130
158
  - !ruby/object:Gem::Version
131
159
  version: 1.3.7
132
160
  requirements: []
133
- rubygems_version: 3.5.6
134
- signing_key:
161
+ rubygems_version: 3.6.1
135
162
  specification_version: 4
136
163
  summary: A secure, non-evaling end user template engine with aesthetic markup.
137
164
  test_files: []
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Liquid
4
- # StrainerFactory is the factory for the filters system.
5
- module StrainerFactory
6
- extend self
7
-
8
- def add_global_filter(filter)
9
- strainer_class_cache.clear
10
- GlobalCache.add_filter(filter)
11
- end
12
-
13
- def create(context, filters = [])
14
- strainer_from_cache(filters).new(context)
15
- end
16
-
17
- def global_filter_names
18
- GlobalCache.filter_method_names
19
- end
20
-
21
- GlobalCache = Class.new(StrainerTemplate)
22
-
23
- private
24
-
25
- def strainer_from_cache(filters)
26
- if filters.empty?
27
- GlobalCache
28
- else
29
- strainer_class_cache[filters] ||= begin
30
- klass = Class.new(GlobalCache)
31
- filters.each { |f| klass.add_filter(f) }
32
- klass
33
- end
34
- end
35
- end
36
-
37
- def strainer_class_cache
38
- @strainer_class_cache ||= {}
39
- end
40
- end
41
- end