liquid 5.3.0 → 5.4.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.
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