liquid 5.3.0 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +16 -1
  3. data/README.md +2 -2
  4. data/lib/liquid/block_body.rb +4 -4
  5. data/lib/liquid/context.rb +6 -2
  6. data/lib/liquid/forloop_drop.rb +44 -1
  7. data/lib/liquid/locales/en.yml +6 -5
  8. data/lib/liquid/partial_cache.rb +3 -3
  9. data/lib/liquid/{static_registers.rb → registers.rb} +13 -10
  10. data/lib/liquid/standardfilters.rb +406 -57
  11. data/lib/liquid/strainer_factory.rb +4 -0
  12. data/lib/liquid/strainer_template.rb +4 -0
  13. data/lib/liquid/tablerowloop_drop.rb +58 -1
  14. data/lib/liquid/tags/assign.rb +12 -8
  15. data/lib/liquid/tags/break.rb +8 -0
  16. data/lib/liquid/tags/capture.rb +13 -10
  17. data/lib/liquid/tags/case.rb +21 -0
  18. data/lib/liquid/tags/comment.rb +13 -0
  19. data/lib/liquid/tags/continue.rb +8 -9
  20. data/lib/liquid/tags/cycle.rb +12 -11
  21. data/lib/liquid/tags/decrement.rb +16 -17
  22. data/lib/liquid/tags/echo.rb +16 -9
  23. data/lib/liquid/tags/for.rb +22 -43
  24. data/lib/liquid/tags/if.rb +11 -9
  25. data/lib/liquid/tags/include.rb +15 -13
  26. data/lib/liquid/tags/increment.rb +16 -14
  27. data/lib/liquid/tags/inline_comment.rb +43 -0
  28. data/lib/liquid/tags/raw.rb +11 -0
  29. data/lib/liquid/tags/render.rb +29 -4
  30. data/lib/liquid/tags/table_row.rb +22 -0
  31. data/lib/liquid/tags/unless.rb +15 -4
  32. data/lib/liquid/template.rb +2 -3
  33. data/lib/liquid/variable.rb +4 -4
  34. data/lib/liquid/variable_lookup.rb +10 -7
  35. data/lib/liquid/version.rb +1 -1
  36. data/lib/liquid.rb +2 -2
  37. metadata +7 -123
  38. data/lib/liquid/register.rb +0 -6
  39. data/test/fixtures/en_locale.yml +0 -9
  40. data/test/integration/assign_test.rb +0 -117
  41. data/test/integration/blank_test.rb +0 -109
  42. data/test/integration/block_test.rb +0 -58
  43. data/test/integration/capture_test.rb +0 -58
  44. data/test/integration/context_test.rb +0 -634
  45. data/test/integration/document_test.rb +0 -21
  46. data/test/integration/drop_test.rb +0 -257
  47. data/test/integration/error_handling_test.rb +0 -272
  48. data/test/integration/expression_test.rb +0 -46
  49. data/test/integration/filter_kwarg_test.rb +0 -24
  50. data/test/integration/filter_test.rb +0 -189
  51. data/test/integration/hash_ordering_test.rb +0 -25
  52. data/test/integration/output_test.rb +0 -125
  53. data/test/integration/parsing_quirks_test.rb +0 -134
  54. data/test/integration/profiler_test.rb +0 -240
  55. data/test/integration/security_test.rb +0 -89
  56. data/test/integration/standard_filter_test.rb +0 -925
  57. data/test/integration/tag/disableable_test.rb +0 -59
  58. data/test/integration/tag_test.rb +0 -45
  59. data/test/integration/tags/break_tag_test.rb +0 -17
  60. data/test/integration/tags/continue_tag_test.rb +0 -17
  61. data/test/integration/tags/echo_test.rb +0 -13
  62. data/test/integration/tags/for_tag_test.rb +0 -466
  63. data/test/integration/tags/if_else_tag_test.rb +0 -190
  64. data/test/integration/tags/include_tag_test.rb +0 -269
  65. data/test/integration/tags/increment_tag_test.rb +0 -25
  66. data/test/integration/tags/liquid_tag_test.rb +0 -116
  67. data/test/integration/tags/raw_tag_test.rb +0 -34
  68. data/test/integration/tags/render_tag_test.rb +0 -213
  69. data/test/integration/tags/standard_tag_test.rb +0 -303
  70. data/test/integration/tags/statements_test.rb +0 -113
  71. data/test/integration/tags/table_row_test.rb +0 -66
  72. data/test/integration/tags/unless_else_tag_test.rb +0 -28
  73. data/test/integration/template_test.rb +0 -340
  74. data/test/integration/trim_mode_test.rb +0 -563
  75. data/test/integration/variable_test.rb +0 -138
  76. data/test/test_helper.rb +0 -207
  77. data/test/unit/block_unit_test.rb +0 -53
  78. data/test/unit/condition_unit_test.rb +0 -181
  79. data/test/unit/file_system_unit_test.rb +0 -37
  80. data/test/unit/i18n_unit_test.rb +0 -39
  81. data/test/unit/lexer_unit_test.rb +0 -53
  82. data/test/unit/parse_tree_visitor_test.rb +0 -261
  83. data/test/unit/parser_unit_test.rb +0 -84
  84. data/test/unit/partial_cache_unit_test.rb +0 -128
  85. data/test/unit/regexp_unit_test.rb +0 -46
  86. data/test/unit/static_registers_unit_test.rb +0 -156
  87. data/test/unit/strainer_factory_unit_test.rb +0 -101
  88. data/test/unit/strainer_template_unit_test.rb +0 -82
  89. data/test/unit/tag_unit_test.rb +0 -23
  90. data/test/unit/tags/case_tag_unit_test.rb +0 -12
  91. data/test/unit/tags/for_tag_unit_test.rb +0 -15
  92. data/test/unit/tags/if_tag_unit_test.rb +0 -10
  93. data/test/unit/template_factory_unit_test.rb +0 -12
  94. data/test/unit/template_unit_test.rb +0 -87
  95. data/test/unit/tokenizer_unit_test.rb +0 -62
  96. data/test/unit/variable_unit_test.rb +0 -164
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0e965825a9194672f6d2b9c3011db0125eb3dbbb6d44cacf67559140c3f0f9b
4
- data.tar.gz: d1d98d881037c5ff8cc2b9da99d3b3e002eb1ca1d2bda593c806830c1607a98a
3
+ metadata.gz: c8408df245a1cc22ee1154fe5387e3e41eb3c740f7277e7d3736c1863d387e47
4
+ data.tar.gz: 64549a58828fd7e9e0eb7310cb4371e75e64a7c3249fe9ebd021039e3334bba1
5
5
  SHA512:
6
- metadata.gz: fa9caca36072ca79bb727b7bdb9a671e082039c3c999d6cbb79bf8b1feec0d514159daedf2b54f561e66ca5ab7e11273956fb49afbae3580004d3e1d3780b9ab
7
- data.tar.gz: a766a7b068287a7db0a70222a149f8a52a659e93c6593bb53a31e5cee279cbc65b7db14eaa1cc0e89e816bd76020bf352814cd9c2c6b4e32436f743ab0c8e629
6
+ metadata.gz: 29aaff16e3bc464712cdcac3aa205df943132198ef9568d46f4a123d327849f7ead7bd669a095eae0425581eb59ea08874ac38664bf9d8df00b0aa99917c7768
7
+ data.tar.gz: 9f6070c39733b7f4064f70676b1f886fc61070f3ba8921360b9c5fcdb09c217b3e58c3d59d8293b24b6c18e55899ed17552a2f867ea8eb95e7dee9a7deb29ae5
data/History.md CHANGED
@@ -1,10 +1,25 @@
1
1
  # Liquid Change Log
2
2
 
3
+ ## 5.4.0 2022-07-29
4
+
5
+ ### Breaking Changes
6
+ * Drop support for end-of-life Ruby versions (2.5 and 2.6) (#1578) [Andy Waite]
7
+
8
+ ### Features
9
+ * Allow `#` to be used as an inline comment tag (#1498) [CP Clermont]
10
+
11
+ ### Fixes
12
+ * `PartialCache` now shares snippet cache with subcontexts by default (#1553) [Chris AtLee]
13
+ * Hash registers no longer leak into subcontexts as static registers (#1564) [Chris AtLee]
14
+ * Fix `ParseTreeVisitor` for `with` variable expressions in `Render` tag (#1596) [CP Clermont]
15
+
16
+ ### Changed
17
+ * Liquid::Context#registers now always returns a Liquid::Registers object, though supports the most used Hash functions for compatibility (#1553)
18
+
3
19
  ## 5.3.0 2022-03-22
4
20
 
5
21
  ### Fixes
6
22
  * StandardFilter: Fix missing @context on iterations (#1525) [Thierry Joyal]
7
- * Test under Ruby 3.1 (#1533) [petergoldstein]
8
23
  * Fix warning about block and default value in `static_registers.rb` (#1531) [Peter Zhu]
9
24
 
10
25
  ### Deprecation
data/README.md CHANGED
@@ -63,13 +63,13 @@ when templates are invalid. You can enable this new parser like this:
63
63
 
64
64
  ```ruby
65
65
  Liquid::Template.error_mode = :strict # Raises a SyntaxError when invalid syntax is used
66
- Liquid::Template.error_mode = :warn # Adds errors to template.errors but continues as normal
66
+ Liquid::Template.error_mode = :warn # Adds strict errors to template.errors but continues as normal
67
67
  Liquid::Template.error_mode = :lax # The default mode, accepts almost anything.
68
68
  ```
69
69
 
70
70
  If you want to set the error mode only on specific templates you can pass `:error_mode` as an option to `parse`:
71
71
  ```ruby
72
- Liquid::Template.parse(source, :error_mode => :strict)
72
+ Liquid::Template.parse(source, error_mode: :strict)
73
73
  ```
74
74
  This is useful for doing things like enabling strict mode only in the theme editor.
75
75
 
@@ -4,8 +4,8 @@ require 'English'
4
4
 
5
5
  module Liquid
6
6
  class BlockBody
7
- LiquidTagToken = /\A\s*(\w+)\s*(.*?)\z/o
8
- FullToken = /\A#{TagStart}#{WhitespaceControl}?(\s*)(\w+)(\s*)(.*?)#{WhitespaceControl}?#{TagEnd}\z/om
7
+ LiquidTagToken = /\A\s*(#{TagName})\s*(.*?)\z/o
8
+ FullToken = /\A#{TagStart}#{WhitespaceControl}?(\s*)(#{TagName})(\s*)(.*?)#{WhitespaceControl}?#{TagEnd}\z/om
9
9
  ContentOfVariable = /\A#{VariableStart}#{WhitespaceControl}?(.*?)#{WhitespaceControl}?#{VariableEnd}\z/om
10
10
  WhitespaceOrNothing = /\A\s*\z/
11
11
  TAGSTART = "{%"
@@ -37,7 +37,7 @@ module Liquid
37
37
 
38
38
  private def parse_for_liquid_tag(tokenizer, parse_context)
39
39
  while (token = tokenizer.shift)
40
- unless token.empty? || token =~ WhitespaceOrNothing
40
+ unless token.empty? || token.match?(WhitespaceOrNothing)
41
41
  unless token =~ LiquidTagToken
42
42
  # line isn't empty but didn't match tag syntax, yield and let the
43
43
  # caller raise a syntax error
@@ -150,7 +150,7 @@ module Liquid
150
150
  end
151
151
  parse_context.trim_whitespace = false
152
152
  @nodelist << token
153
- @blank &&= !!(token =~ WhitespaceOrNothing)
153
+ @blank &&= token.match?(WhitespaceOrNothing)
154
154
  end
155
155
  parse_context.line_number = tokenizer.line_number
156
156
  end
@@ -28,7 +28,7 @@ module Liquid
28
28
 
29
29
  @static_environments = [static_environments].flat_map(&:freeze).freeze
30
30
  @scopes = [(outer_scope || {})]
31
- @registers = registers
31
+ @registers = registers.is_a?(Registers) ? registers : Registers.new(registers)
32
32
  @errors = []
33
33
  @partial = false
34
34
  @strict_variables = false
@@ -39,6 +39,10 @@ module Liquid
39
39
  @global_filter = nil
40
40
  @disabled_tags = {}
41
41
 
42
+ @registers.static[:cached_partials] ||= {}
43
+ @registers.static[:file_system] ||= Liquid::Template.file_system
44
+ @registers.static[:template_factory] ||= Liquid::TemplateFactory.new
45
+
42
46
  self.exception_renderer = Template.default_exception_renderer
43
47
  if rethrow_errors
44
48
  self.exception_renderer = Liquid::RAISE_EXCEPTION_LAMBDA
@@ -140,7 +144,7 @@ module Liquid
140
144
  self.class.build(
141
145
  resource_limits: resource_limits,
142
146
  static_environments: static_environments,
143
- registers: StaticRegisters.new(registers)
147
+ registers: Registers.new(registers)
144
148
  ).tap do |subcontext|
145
149
  subcontext.base_scope_depth = base_scope_depth + 1
146
150
  subcontext.exception_renderer = exception_renderer
@@ -1,6 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Liquid
4
+ # @liquid_public_docs
5
+ # @liquid_type object
6
+ # @liquid_name forloop
7
+ # @liquid_summary
8
+ # Information about a parent [`for` loop](/api/liquid/tags#for).
4
9
  class ForloopDrop < Drop
5
10
  def initialize(name, length, parentloop)
6
11
  @name = name
@@ -9,33 +14,71 @@ module Liquid
9
14
  @index = 0
10
15
  end
11
16
 
12
- attr_reader :length, :parentloop
17
+ # @liquid_public_docs
18
+ # @liquid_name length
19
+ # @liquid_summary
20
+ # The total number of iterations in the loop.
21
+ # @liquid_return [number]
22
+ attr_reader :length
23
+
24
+ # @liquid_public_docs
25
+ # @liquid_name parentloop
26
+ # @liquid_summary
27
+ # The parent `forloop` object.
28
+ # @liquid_description
29
+ # If the current `for` loop isn't nested inside another `for` loop, then `nil` is returned.
30
+ # @liquid_return [forloop]
31
+ attr_reader :parentloop
13
32
 
14
33
  def name
15
34
  Usage.increment('forloop_drop_name')
16
35
  @name
17
36
  end
18
37
 
38
+ # @liquid_public_docs
39
+ # @liquid_summary
40
+ # The 1-based index of the current iteration.
41
+ # @liquid_return [number]
19
42
  def index
20
43
  @index + 1
21
44
  end
22
45
 
46
+ # @liquid_public_docs
47
+ # @liquid_summary
48
+ # The 0-based index of the current iteration.
49
+ # @liquid_return [number]
23
50
  def index0
24
51
  @index
25
52
  end
26
53
 
54
+ # @liquid_public_docs
55
+ # @liquid_summary
56
+ # The 1-based index of the current iteration, in reverse order.
57
+ # @liquid_return [number]
27
58
  def rindex
28
59
  @length - @index
29
60
  end
30
61
 
62
+ # @liquid_public_docs
63
+ # @liquid_summary
64
+ # The 0-based index of the current iteration, in reverse order.
65
+ # @liquid_return [number]
31
66
  def rindex0
32
67
  @length - @index - 1
33
68
  end
34
69
 
70
+ # @liquid_public_docs
71
+ # @liquid_summary
72
+ # Returns `true` if the current iteration is the first. Returns `false` if not.
73
+ # @liquid_return [boolean]
35
74
  def first
36
75
  @index == 0
37
76
  end
38
77
 
78
+ # @liquid_public_docs
79
+ # @liquid_summary
80
+ # Returns `true` if the current iteration is the last. Returns `false` if not.
81
+ # @liquid_return [boolean]
39
82
  def last
40
83
  @index == @length - 1
41
84
  end
@@ -13,15 +13,16 @@
13
13
  for_invalid_attribute: "Invalid attribute in for loop. Valid attributes are limit and offset"
14
14
  if: "Syntax Error in tag 'if' - Valid syntax: if [expression]"
15
15
  include: "Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]"
16
- unknown_tag: "Unknown tag '%{tag}'"
16
+ inline_comment_invalid: "Syntax error in tag '#' - Each line of comments must be prefixed by the '#' character"
17
17
  invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
18
+ render: "Syntax error in tag 'render' - Template name must be a quoted string"
19
+ table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
20
+ tag_never_closed: "'%{block_name}' tag was never closed"
21
+ tag_termination: "Tag '%{token}' was not properly terminated with regexp: %{tag_end}"
18
22
  unexpected_else: "%{block_name} tag does not expect 'else' tag"
19
23
  unexpected_outer_tag: "Unexpected outer '%{tag}' tag"
20
- tag_termination: "Tag '%{token}' was not properly terminated with regexp: %{tag_end}"
24
+ unknown_tag: "Unknown tag '%{tag}'"
21
25
  variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
22
- tag_never_closed: "'%{block_name}' tag was never closed"
23
- table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
24
- render: "Syntax error in tag 'render' - Template name must be a quoted string"
25
26
  argument:
26
27
  include: "Argument error in tag 'include' - Illegal template name"
27
28
  disabled:
@@ -3,16 +3,16 @@
3
3
  module Liquid
4
4
  class PartialCache
5
5
  def self.load(template_name, context:, parse_context:)
6
- cached_partials = (context.registers[:cached_partials] ||= {})
6
+ cached_partials = context.registers[:cached_partials]
7
7
  cached = cached_partials[template_name]
8
8
  return cached if cached
9
9
 
10
- file_system = (context.registers[:file_system] ||= Liquid::Template.file_system)
10
+ file_system = context.registers[:file_system]
11
11
  source = file_system.read_template_file(template_name)
12
12
 
13
13
  parse_context.partial = true
14
14
 
15
- template_factory = (context.registers[:template_factory] ||= Liquid::TemplateFactory.new)
15
+ template_factory = context.registers[:template_factory]
16
16
  template = template_factory.for(template_name)
17
17
 
18
18
  partial = template.parse(source, parse_context)
@@ -1,35 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Liquid
4
- class StaticRegisters
4
+ class Registers
5
5
  attr_reader :static
6
6
 
7
7
  def initialize(registers = {})
8
- @static = registers.is_a?(StaticRegisters) ? registers.static : registers
9
- @registers = {}
8
+ @static = registers.is_a?(Registers) ? registers.static : registers
9
+ @changes = {}
10
10
  end
11
11
 
12
12
  def []=(key, value)
13
- @registers[key] = value
13
+ @changes[key] = value
14
14
  end
15
15
 
16
16
  def [](key)
17
- if @registers.key?(key)
18
- @registers[key]
17
+ if @changes.key?(key)
18
+ @changes[key]
19
19
  else
20
20
  @static[key]
21
21
  end
22
22
  end
23
23
 
24
24
  def delete(key)
25
- @registers.delete(key)
25
+ @changes.delete(key)
26
26
  end
27
27
 
28
28
  UNDEFINED = Object.new
29
29
 
30
30
  def fetch(key, default = UNDEFINED, &block)
31
- if @registers.key?(key)
32
- @registers.fetch(key)
31
+ if @changes.key?(key)
32
+ @changes.fetch(key)
33
33
  elsif default != UNDEFINED
34
34
  if block_given?
35
35
  @static.fetch(key, &block)
@@ -42,7 +42,10 @@ module Liquid
42
42
  end
43
43
 
44
44
  def key?(key)
45
- @registers.key?(key) || @static.key?(key)
45
+ @changes.key?(key) || @static.key?(key)
46
46
  end
47
47
  end
48
+
49
+ # Alias for backwards compatibility
50
+ StaticRegisters = Registers
48
51
  end