liquid 3.0.6 → 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.
- checksums.yaml +5 -5
 - data/History.md +243 -58
 - data/README.md +43 -4
 - data/lib/liquid/block.rb +57 -123
 - data/lib/liquid/block_body.rb +217 -85
 - data/lib/liquid/condition.rb +92 -45
 - data/lib/liquid/context.rb +154 -89
 - data/lib/liquid/document.rb +57 -9
 - data/lib/liquid/drop.rb +20 -17
 - data/lib/liquid/errors.rb +27 -29
 - data/lib/liquid/expression.rb +32 -20
 - data/lib/liquid/extensions.rb +21 -7
 - data/lib/liquid/file_system.rb +17 -15
 - data/lib/liquid/forloop_drop.rb +92 -0
 - data/lib/liquid/i18n.rb +10 -8
 - data/lib/liquid/interrupts.rb +4 -3
 - data/lib/liquid/lexer.rb +37 -26
 - data/lib/liquid/locales/en.yml +13 -6
 - data/lib/liquid/parse_context.rb +54 -0
 - data/lib/liquid/parse_tree_visitor.rb +42 -0
 - data/lib/liquid/parser.rb +30 -18
 - data/lib/liquid/parser_switching.rb +20 -6
 - data/lib/liquid/partial_cache.rb +24 -0
 - data/lib/liquid/profiler/hooks.rb +26 -14
 - data/lib/liquid/profiler.rb +72 -92
 - data/lib/liquid/range_lookup.rb +28 -3
 - data/lib/liquid/registers.rb +51 -0
 - data/lib/liquid/resource_limits.rb +62 -0
 - data/lib/liquid/standardfilters.rb +715 -132
 - data/lib/liquid/strainer_factory.rb +41 -0
 - data/lib/liquid/strainer_template.rb +62 -0
 - data/lib/liquid/tablerowloop_drop.rb +121 -0
 - data/lib/liquid/tag/disableable.rb +22 -0
 - data/lib/liquid/tag/disabler.rb +21 -0
 - data/lib/liquid/tag.rb +35 -12
 - data/lib/liquid/tags/assign.rb +57 -18
 - data/lib/liquid/tags/break.rb +15 -5
 - data/lib/liquid/tags/capture.rb +24 -18
 - data/lib/liquid/tags/case.rb +79 -30
 - data/lib/liquid/tags/comment.rb +19 -4
 - data/lib/liquid/tags/continue.rb +16 -12
 - data/lib/liquid/tags/cycle.rb +47 -27
 - data/lib/liquid/tags/decrement.rb +23 -24
 - data/lib/liquid/tags/echo.rb +41 -0
 - data/lib/liquid/tags/for.rb +155 -124
 - data/lib/liquid/tags/if.rb +97 -63
 - data/lib/liquid/tags/ifchanged.rb +11 -12
 - data/lib/liquid/tags/include.rb +82 -73
 - data/lib/liquid/tags/increment.rb +23 -17
 - data/lib/liquid/tags/inline_comment.rb +43 -0
 - data/lib/liquid/tags/raw.rb +50 -8
 - data/lib/liquid/tags/render.rb +109 -0
 - data/lib/liquid/tags/table_row.rb +57 -41
 - data/lib/liquid/tags/unless.rb +38 -20
 - data/lib/liquid/template.rb +71 -103
 - data/lib/liquid/template_factory.rb +9 -0
 - data/lib/liquid/tokenizer.rb +39 -0
 - data/lib/liquid/usage.rb +8 -0
 - data/lib/liquid/utils.rb +63 -9
 - data/lib/liquid/variable.rb +74 -56
 - data/lib/liquid/variable_lookup.rb +31 -15
 - data/lib/liquid/version.rb +3 -1
 - data/lib/liquid.rb +27 -12
 - metadata +30 -106
 - data/lib/liquid/module_ex.rb +0 -62
 - data/lib/liquid/strainer.rb +0 -59
 - data/lib/liquid/token.rb +0 -18
 - data/test/fixtures/en_locale.yml +0 -9
 - data/test/integration/assign_test.rb +0 -48
 - data/test/integration/blank_test.rb +0 -106
 - data/test/integration/capture_test.rb +0 -50
 - data/test/integration/context_test.rb +0 -32
 - data/test/integration/drop_test.rb +0 -271
 - data/test/integration/error_handling_test.rb +0 -207
 - data/test/integration/filter_test.rb +0 -138
 - data/test/integration/hash_ordering_test.rb +0 -23
 - data/test/integration/output_test.rb +0 -124
 - data/test/integration/parsing_quirks_test.rb +0 -116
 - data/test/integration/render_profiling_test.rb +0 -154
 - data/test/integration/security_test.rb +0 -64
 - data/test/integration/standard_filter_test.rb +0 -396
 - data/test/integration/tags/break_tag_test.rb +0 -16
 - data/test/integration/tags/continue_tag_test.rb +0 -16
 - data/test/integration/tags/for_tag_test.rb +0 -375
 - data/test/integration/tags/if_else_tag_test.rb +0 -190
 - data/test/integration/tags/include_tag_test.rb +0 -234
 - data/test/integration/tags/increment_tag_test.rb +0 -24
 - data/test/integration/tags/raw_tag_test.rb +0 -25
 - data/test/integration/tags/standard_tag_test.rb +0 -297
 - data/test/integration/tags/statements_test.rb +0 -113
 - data/test/integration/tags/table_row_test.rb +0 -63
 - data/test/integration/tags/unless_else_tag_test.rb +0 -26
 - data/test/integration/template_test.rb +0 -182
 - data/test/integration/variable_test.rb +0 -82
 - data/test/test_helper.rb +0 -89
 - data/test/unit/block_unit_test.rb +0 -55
 - data/test/unit/condition_unit_test.rb +0 -149
 - data/test/unit/context_unit_test.rb +0 -492
 - data/test/unit/file_system_unit_test.rb +0 -35
 - data/test/unit/i18n_unit_test.rb +0 -37
 - data/test/unit/lexer_unit_test.rb +0 -48
 - data/test/unit/module_ex_unit_test.rb +0 -87
 - data/test/unit/parser_unit_test.rb +0 -82
 - data/test/unit/regexp_unit_test.rb +0 -44
 - data/test/unit/strainer_unit_test.rb +0 -69
 - data/test/unit/tag_unit_test.rb +0 -16
 - data/test/unit/tags/case_tag_unit_test.rb +0 -10
 - data/test/unit/tags/for_tag_unit_test.rb +0 -13
 - data/test/unit/tags/if_tag_unit_test.rb +0 -8
 - data/test/unit/template_unit_test.rb +0 -69
 - data/test/unit/tokenizer_unit_test.rb +0 -38
 - data/test/unit/variable_unit_test.rb +0 -145
 - /data/{MIT-LICENSE → LICENSE} +0 -0
 
    
        data/lib/liquid/tags/if.rb
    CHANGED
    
    | 
         @@ -1,106 +1,140 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Liquid
         
     | 
| 
       2 
     | 
    
         
            -
              #  
     | 
| 
       3 
     | 
    
         
            -
              #
         
     | 
| 
       4 
     | 
    
         
            -
              # 
     | 
| 
       5 
     | 
    
         
            -
              # 
     | 
| 
       6 
     | 
    
         
            -
              # 
     | 
| 
       7 
     | 
    
         
            -
              # 
     | 
| 
      
 4 
     | 
    
         
            +
              # @liquid_public_docs
         
     | 
| 
      
 5 
     | 
    
         
            +
              # @liquid_type tag
         
     | 
| 
      
 6 
     | 
    
         
            +
              # @liquid_category conditional
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @liquid_name if
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @liquid_summary
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   Renders an expression if a specific condition is `true`.
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @liquid_syntax
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   {% if condition %}
         
     | 
| 
      
 12 
     | 
    
         
            +
              #     expression
         
     | 
| 
       8 
13 
     | 
    
         
             
              #   {% endif %}
         
     | 
| 
       9 
     | 
    
         
            -
              #
         
     | 
| 
       10 
     | 
    
         
            -
              # 
     | 
| 
       11 
     | 
    
         
            -
              #
         
     | 
| 
      
 14 
     | 
    
         
            +
              # @liquid_syntax_keyword condition The condition to evaluate.
         
     | 
| 
      
 15 
     | 
    
         
            +
              # @liquid_syntax_keyword expression The expression to render if the condition is met.
         
     | 
| 
       12 
16 
     | 
    
         
             
              class If < Block
         
     | 
| 
       13 
     | 
    
         
            -
                Syntax 
     | 
| 
      
 17 
     | 
    
         
            +
                Syntax                  = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/o
         
     | 
| 
       14 
18 
     | 
    
         
             
                ExpressionsAndOperators = /(?:\b(?:\s?and\s?|\s?or\s?)\b|(?:\s*(?!\b(?:\s?and\s?|\s?or\s?)\b)(?:#{QuotedFragment}|\S+)\s*)+)/o
         
     | 
| 
       15 
     | 
    
         
            -
                BOOLEAN_OPERATORS 
     | 
| 
      
 19 
     | 
    
         
            +
                BOOLEAN_OPERATORS       = %w(and or).freeze
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                attr_reader :blocks
         
     | 
| 
       16 
22 
     | 
    
         | 
| 
       17 
23 
     | 
    
         
             
                def initialize(tag_name, markup, options)
         
     | 
| 
       18 
24 
     | 
    
         
             
                  super
         
     | 
| 
       19 
25 
     | 
    
         
             
                  @blocks = []
         
     | 
| 
       20 
     | 
    
         
            -
                  push_block('if' 
     | 
| 
      
 26 
     | 
    
         
            +
                  push_block('if', markup)
         
     | 
| 
       21 
27 
     | 
    
         
             
                end
         
     | 
| 
       22 
28 
     | 
    
         | 
| 
       23 
29 
     | 
    
         
             
                def nodelist
         
     | 
| 
       24 
     | 
    
         
            -
                  @blocks. 
     | 
| 
      
 30 
     | 
    
         
            +
                  @blocks.map(&:attachment)
         
     | 
| 
       25 
31 
     | 
    
         
             
                end
         
     | 
| 
       26 
32 
     | 
    
         | 
| 
      
 33 
     | 
    
         
            +
                def parse(tokens)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  while parse_body(@blocks.last.attachment, tokens)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @blocks.reverse_each do |block|
         
     | 
| 
      
 37 
     | 
    
         
            +
                    block.attachment.remove_blank_strings if blank?
         
     | 
| 
      
 38 
     | 
    
         
            +
                    block.attachment.freeze
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                ELSE_TAG_NAMES = ['elsif', 'else'].freeze
         
     | 
| 
      
 43 
     | 
    
         
            +
                private_constant :ELSE_TAG_NAMES
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       27 
45 
     | 
    
         
             
                def unknown_tag(tag, markup, tokens)
         
     | 
| 
       28 
     | 
    
         
            -
                  if  
     | 
| 
      
 46 
     | 
    
         
            +
                  if ELSE_TAG_NAMES.include?(tag)
         
     | 
| 
       29 
47 
     | 
    
         
             
                    push_block(tag, markup)
         
     | 
| 
       30 
48 
     | 
    
         
             
                  else
         
     | 
| 
       31 
49 
     | 
    
         
             
                    super
         
     | 
| 
       32 
50 
     | 
    
         
             
                  end
         
     | 
| 
       33 
51 
     | 
    
         
             
                end
         
     | 
| 
       34 
52 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                def  
     | 
| 
       36 
     | 
    
         
            -
                   
     | 
| 
       37 
     | 
    
         
            -
                     
     | 
| 
       38 
     | 
    
         
            -
                       
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                def render_to_output_buffer(context, output)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  @blocks.each do |block|
         
     | 
| 
      
 55 
     | 
    
         
            +
                    result = Liquid::Utils.to_liquid_value(
         
     | 
| 
      
 56 
     | 
    
         
            +
                      block.evaluate(context)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    )
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    if result
         
     | 
| 
      
 60 
     | 
    
         
            +
                      return block.attachment.render_to_output_buffer(context, output)
         
     | 
| 
       41 
61 
     | 
    
         
             
                    end
         
     | 
| 
       42 
     | 
    
         
            -
                    ''.freeze
         
     | 
| 
       43 
62 
     | 
    
         
             
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  output
         
     | 
| 
       44 
65 
     | 
    
         
             
                end
         
     | 
| 
       45 
66 
     | 
    
         | 
| 
       46 
67 
     | 
    
         
             
                private
         
     | 
| 
       47 
68 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                    end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                    @blocks.push(block)
         
     | 
| 
       56 
     | 
    
         
            -
                    @nodelist = block.attach(Array.new)
         
     | 
| 
      
 69 
     | 
    
         
            +
                def push_block(tag, markup)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  block = if tag == 'else'
         
     | 
| 
      
 71 
     | 
    
         
            +
                    ElseCondition.new
         
     | 
| 
      
 72 
     | 
    
         
            +
                  else
         
     | 
| 
      
 73 
     | 
    
         
            +
                    parse_with_selected_parser(markup)
         
     | 
| 
       57 
74 
     | 
    
         
             
                  end
         
     | 
| 
       58 
75 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
                   
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 76 
     | 
    
         
            +
                  @blocks.push(block)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  block.attach(new_body)
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def parse_expression(markup)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  Condition.parse_expression(parse_context, markup)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
       62 
83 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
      
 84 
     | 
    
         
            +
                def lax_parse(markup)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  expressions = markup.scan(ExpressionsAndOperators)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop =~ Syntax
         
     | 
| 
       64 
87 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                      operator = expressions.pop.to_s.strip
         
     | 
| 
      
 88 
     | 
    
         
            +
                  condition = Condition.new(parse_expression(Regexp.last_match(1)), Regexp.last_match(2), parse_expression(Regexp.last_match(3)))
         
     | 
| 
       67 
89 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 90 
     | 
    
         
            +
                  until expressions.empty?
         
     | 
| 
      
 91 
     | 
    
         
            +
                    operator = expressions.pop.to_s.strip
         
     | 
| 
       69 
92 
     | 
    
         | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                      raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless BOOLEAN_OPERATORS.include?(operator)
         
     | 
| 
       72 
     | 
    
         
            -
                      new_condition.send(operator, condition)
         
     | 
| 
       73 
     | 
    
         
            -
                      condition = new_condition
         
     | 
| 
       74 
     | 
    
         
            -
                    end
         
     | 
| 
      
 93 
     | 
    
         
            +
                    raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop.to_s =~ Syntax
         
     | 
| 
       75 
94 
     | 
    
         | 
| 
       76 
     | 
    
         
            -
                     
     | 
| 
      
 95 
     | 
    
         
            +
                    new_condition = Condition.new(parse_expression(Regexp.last_match(1)), Regexp.last_match(2), parse_expression(Regexp.last_match(3)))
         
     | 
| 
      
 96 
     | 
    
         
            +
                    raise SyntaxError, options[:locale].t("errors.syntax.if") unless BOOLEAN_OPERATORS.include?(operator)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    new_condition.send(operator, condition)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    condition = new_condition
         
     | 
| 
       77 
99 
     | 
    
         
             
                  end
         
     | 
| 
       78 
100 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
                   
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
      
 101 
     | 
    
         
            +
                  condition
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                def strict_parse(markup)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  p = Parser.new(markup)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  condition = parse_binary_comparisons(p)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  p.consume(:end_of_string)
         
     | 
| 
      
 108 
     | 
    
         
            +
                  condition
         
     | 
| 
      
 109 
     | 
    
         
            +
                end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                def parse_binary_comparisons(p)
         
     | 
| 
      
 112 
     | 
    
         
            +
                  condition = parse_comparison(p)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  first_condition = condition
         
     | 
| 
      
 114 
     | 
    
         
            +
                  while (op = (p.id?('and') || p.id?('or')))
         
     | 
| 
      
 115 
     | 
    
         
            +
                    child_condition = parse_comparison(p)
         
     | 
| 
      
 116 
     | 
    
         
            +
                    condition.send(op, child_condition)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    condition = child_condition
         
     | 
| 
       84 
118 
     | 
    
         
             
                  end
         
     | 
| 
      
 119 
     | 
    
         
            +
                  first_condition
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
       85 
121 
     | 
    
         | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                     
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
      
 122 
     | 
    
         
            +
                def parse_comparison(p)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  a = parse_expression(p.expression)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  if (op = p.consume?(:comparison))
         
     | 
| 
      
 125 
     | 
    
         
            +
                    b = parse_expression(p.expression)
         
     | 
| 
      
 126 
     | 
    
         
            +
                    Condition.new(a, op, b)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  else
         
     | 
| 
      
 128 
     | 
    
         
            +
                    Condition.new(a)
         
     | 
| 
       92 
129 
     | 
    
         
             
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
       93 
131 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                     
     | 
| 
       97 
     | 
    
         
            -
                      b = p.expression
         
     | 
| 
       98 
     | 
    
         
            -
                      Condition.new(a, op, b)
         
     | 
| 
       99 
     | 
    
         
            -
                    else
         
     | 
| 
       100 
     | 
    
         
            -
                      Condition.new(a)
         
     | 
| 
       101 
     | 
    
         
            -
                    end
         
     | 
| 
      
 132 
     | 
    
         
            +
                class ParseTreeVisitor < Liquid::ParseTreeVisitor
         
     | 
| 
      
 133 
     | 
    
         
            +
                  def children
         
     | 
| 
      
 134 
     | 
    
         
            +
                    @node.blocks
         
     | 
| 
       102 
135 
     | 
    
         
             
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
       103 
137 
     | 
    
         
             
              end
         
     | 
| 
       104 
138 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
              Template.register_tag('if' 
     | 
| 
      
 139 
     | 
    
         
            +
              Template.register_tag('if', If)
         
     | 
| 
       106 
140 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,20 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Liquid
         
     | 
| 
       2 
4 
     | 
    
         
             
              class Ifchanged < Block
         
     | 
| 
      
 5 
     | 
    
         
            +
                def render_to_output_buffer(context, output)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  block_output = +''
         
     | 
| 
      
 7 
     | 
    
         
            +
                  super(context, block_output)
         
     | 
| 
       3 
8 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
                    output = super
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                    if output != context.registers[:ifchanged]
         
     | 
| 
       10 
     | 
    
         
            -
                      context.registers[:ifchanged] = output
         
     | 
| 
       11 
     | 
    
         
            -
                      output
         
     | 
| 
       12 
     | 
    
         
            -
                    else
         
     | 
| 
       13 
     | 
    
         
            -
                      ''.freeze
         
     | 
| 
       14 
     | 
    
         
            -
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
                  if block_output != context.registers[:ifchanged]
         
     | 
| 
      
 10 
     | 
    
         
            +
                    context.registers[:ifchanged] = block_output
         
     | 
| 
      
 11 
     | 
    
         
            +
                    output << block_output
         
     | 
| 
       15 
12 
     | 
    
         
             
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  output
         
     | 
| 
       16 
15 
     | 
    
         
             
                end
         
     | 
| 
       17 
16 
     | 
    
         
             
              end
         
     | 
| 
       18 
17 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
              Template.register_tag('ifchanged' 
     | 
| 
      
 18 
     | 
    
         
            +
              Template.register_tag('ifchanged', Ifchanged)
         
     | 
| 
       20 
19 
     | 
    
         
             
            end
         
     | 
    
        data/lib/liquid/tags/include.rb
    CHANGED
    
    | 
         @@ -1,104 +1,113 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              #
         
     | 
| 
       5 
     | 
    
         
            -
              #  
     | 
| 
       6 
     | 
    
         
            -
              #
         
     | 
| 
       7 
     | 
    
         
            -
              # 
     | 
| 
       8 
     | 
    
         
            -
              #
         
     | 
| 
       9 
     | 
    
         
            -
              #  
     | 
| 
       10 
     | 
    
         
            -
              #
         
     | 
| 
       11 
     | 
    
         
            -
              #    
     | 
| 
       12 
     | 
    
         
            -
              #
         
     | 
| 
       13 
     | 
    
         
            -
              #  
     | 
| 
       14 
     | 
    
         
            -
              #
         
     | 
| 
       15 
     | 
    
         
            -
              # 
     | 
| 
      
 3 
     | 
    
         
            +
            module Liquid
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @liquid_public_docs
         
     | 
| 
      
 5 
     | 
    
         
            +
              # @liquid_type tag
         
     | 
| 
      
 6 
     | 
    
         
            +
              # @liquid_category theme
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @liquid_name include
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @liquid_summary
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   Renders a [snippet](/themes/architecture#snippets).
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @liquid_description
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   Inside the snippet, you can access and alter variables that are [created](/api/liquid/tags#variable-tags) outside of the
         
     | 
| 
      
 12 
     | 
    
         
            +
              #   snippet.
         
     | 
| 
      
 13 
     | 
    
         
            +
              # @liquid_syntax
         
     | 
| 
      
 14 
     | 
    
         
            +
              #   {% include 'filename' %}
         
     | 
| 
      
 15 
     | 
    
         
            +
              # @liquid_syntax_keyword filename The name of the snippet to render, without the `.liquid` extension.
         
     | 
| 
      
 16 
     | 
    
         
            +
              # @liquid_deprecated
         
     | 
| 
      
 17 
     | 
    
         
            +
              #   Deprecated because the way that variables are handled reduces performance and makes code harder to both read and maintain.
         
     | 
| 
       16 
18 
     | 
    
         
             
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              #   The `include` tag has been replaced by [`render`](/api/liquid/tags#render).
         
     | 
| 
       17 
20 
     | 
    
         
             
              class Include < Tag
         
     | 
| 
       18 
     | 
    
         
            -
                 
     | 
| 
      
 21 
     | 
    
         
            +
                prepend Tag::Disableable
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                SYNTAX = /(#{QuotedFragment}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
         
     | 
| 
      
 24 
     | 
    
         
            +
                Syntax = SYNTAX
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                attr_reader :template_name_expr, :variable_name_expr, :attributes
         
     | 
| 
       19 
27 
     | 
    
         | 
| 
       20 
28 
     | 
    
         
             
                def initialize(tag_name, markup, options)
         
     | 
| 
       21 
29 
     | 
    
         
             
                  super
         
     | 
| 
       22 
30 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                  if markup =~  
     | 
| 
      
 31 
     | 
    
         
            +
                  if markup =~ SYNTAX
         
     | 
| 
       24 
32 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                     
     | 
| 
       26 
     | 
    
         
            -
                     
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 33 
     | 
    
         
            +
                    template_name = Regexp.last_match(1)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    variable_name = Regexp.last_match(3)
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    @alias_name         = Regexp.last_match(5)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @variable_name_expr = variable_name ? parse_expression(variable_name) : nil
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @template_name_expr = parse_expression(template_name)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @attributes         = {}
         
     | 
| 
       28 
40 
     | 
    
         | 
| 
       29 
41 
     | 
    
         
             
                    markup.scan(TagAttributes) do |key, value|
         
     | 
| 
       30 
     | 
    
         
            -
                      @attributes[key] = value
         
     | 
| 
      
 42 
     | 
    
         
            +
                      @attributes[key] = parse_expression(value)
         
     | 
| 
       31 
43 
     | 
    
         
             
                    end
         
     | 
| 
       32 
44 
     | 
    
         | 
| 
       33 
45 
     | 
    
         
             
                  else
         
     | 
| 
       34 
     | 
    
         
            -
                    raise SyntaxError 
     | 
| 
      
 46 
     | 
    
         
            +
                    raise SyntaxError, options[:locale].t("errors.syntax.include")
         
     | 
| 
       35 
47 
     | 
    
         
             
                  end
         
     | 
| 
       36 
48 
     | 
    
         
             
                end
         
     | 
| 
       37 
49 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                def parse( 
     | 
| 
      
 50 
     | 
    
         
            +
                def parse(_tokens)
         
     | 
| 
       39 
51 
     | 
    
         
             
                end
         
     | 
| 
       40 
52 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                def  
     | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
      
 53 
     | 
    
         
            +
                def render_to_output_buffer(context, output)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  template_name = context.evaluate(@template_name_expr)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  raise ArgumentError, options[:locale].t("errors.argument.include") unless template_name
         
     | 
| 
       44 
56 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                   
     | 
| 
       46 
     | 
    
         
            -
                     
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                     
     | 
| 
      
 57 
     | 
    
         
            +
                  partial = PartialCache.load(
         
     | 
| 
      
 58 
     | 
    
         
            +
                    template_name,
         
     | 
| 
      
 59 
     | 
    
         
            +
                    context: context,
         
     | 
| 
      
 60 
     | 
    
         
            +
                    parse_context: parse_context
         
     | 
| 
      
 61 
     | 
    
         
            +
                  )
         
     | 
| 
       49 
62 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                    else
         
     | 
| 
       57 
     | 
    
         
            -
                      context[context_variable_name] = variable
         
     | 
| 
       58 
     | 
    
         
            -
                      partial.render(context)
         
     | 
| 
       59 
     | 
    
         
            -
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  context_variable_name = @alias_name || template_name.split('/').last
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  variable = if @variable_name_expr
         
     | 
| 
      
 66 
     | 
    
         
            +
                    context.evaluate(@variable_name_expr)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  else
         
     | 
| 
      
 68 
     | 
    
         
            +
                    context.find_variable(template_name, raise_on_not_found: false)
         
     | 
| 
       60 
69 
     | 
    
         
             
                  end
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
70 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                   
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                    template_name =  
     | 
| 
      
 71 
     | 
    
         
            +
                  old_template_name = context.template_name
         
     | 
| 
      
 72 
     | 
    
         
            +
                  old_partial       = context.partial
         
     | 
| 
      
 73 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 74 
     | 
    
         
            +
                    context.template_name = template_name
         
     | 
| 
      
 75 
     | 
    
         
            +
                    context.partial       = true
         
     | 
| 
      
 76 
     | 
    
         
            +
                    context.stack do
         
     | 
| 
      
 77 
     | 
    
         
            +
                      @attributes.each do |key, value|
         
     | 
| 
      
 78 
     | 
    
         
            +
                        context[key] = context.evaluate(value)
         
     | 
| 
      
 79 
     | 
    
         
            +
                      end
         
     | 
| 
       67 
80 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
                      if variable.is_a?(Array)
         
     | 
| 
      
 82 
     | 
    
         
            +
                        variable.each do |var|
         
     | 
| 
      
 83 
     | 
    
         
            +
                          context[context_variable_name] = var
         
     | 
| 
      
 84 
     | 
    
         
            +
                          partial.render_to_output_buffer(context, output)
         
     | 
| 
      
 85 
     | 
    
         
            +
                        end
         
     | 
| 
      
 86 
     | 
    
         
            +
                      else
         
     | 
| 
      
 87 
     | 
    
         
            +
                        context[context_variable_name] = variable
         
     | 
| 
      
 88 
     | 
    
         
            +
                        partial.render_to_output_buffer(context, output)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
       70 
90 
     | 
    
         
             
                    end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                     
     | 
| 
       73 
     | 
    
         
            -
                     
     | 
| 
       74 
     | 
    
         
            -
                    context.registers[:cached_partials] = cached_partials
         
     | 
| 
       75 
     | 
    
         
            -
                    partial
         
     | 
| 
      
 91 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 92 
     | 
    
         
            +
                    context.template_name = old_template_name
         
     | 
| 
      
 93 
     | 
    
         
            +
                    context.partial       = old_partial
         
     | 
| 
       76 
94 
     | 
    
         
             
                  end
         
     | 
| 
       77 
95 
     | 
    
         | 
| 
       78 
     | 
    
         
            -
                   
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
                    # make read_template_file call backwards-compatible.
         
     | 
| 
       82 
     | 
    
         
            -
                    case file_system.method(:read_template_file).arity
         
     | 
| 
       83 
     | 
    
         
            -
                    when 1
         
     | 
| 
       84 
     | 
    
         
            -
                      file_system.read_template_file(context[@template_name])
         
     | 
| 
       85 
     | 
    
         
            -
                    when 2
         
     | 
| 
       86 
     | 
    
         
            -
                      file_system.read_template_file(context[@template_name], context)
         
     | 
| 
       87 
     | 
    
         
            -
                    else
         
     | 
| 
       88 
     | 
    
         
            -
                      raise ArgumentError, "file_system.read_template_file expects two parameters: (template_name, context)"
         
     | 
| 
       89 
     | 
    
         
            -
                    end
         
     | 
| 
       90 
     | 
    
         
            -
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  output
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
       91 
98 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
      
 99 
     | 
    
         
            +
                alias_method :parse_context, :options
         
     | 
| 
      
 100 
     | 
    
         
            +
                private :parse_context
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                class ParseTreeVisitor < Liquid::ParseTreeVisitor
         
     | 
| 
      
 103 
     | 
    
         
            +
                  def children
         
     | 
| 
      
 104 
     | 
    
         
            +
                    [
         
     | 
| 
      
 105 
     | 
    
         
            +
                      @node.template_name_expr,
         
     | 
| 
      
 106 
     | 
    
         
            +
                      @node.variable_name_expr,
         
     | 
| 
      
 107 
     | 
    
         
            +
                    ] + @node.attributes.values
         
     | 
| 
       100 
108 
     | 
    
         
             
                  end
         
     | 
| 
      
 109 
     | 
    
         
            +
                end
         
     | 
| 
       101 
110 
     | 
    
         
             
              end
         
     | 
| 
       102 
111 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
              Template.register_tag('include' 
     | 
| 
      
 112 
     | 
    
         
            +
              Template.register_tag('include', Include)
         
     | 
| 
       104 
113 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,31 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Liquid
         
     | 
| 
       2 
     | 
    
         
            -
              #  
     | 
| 
       3 
     | 
    
         
            -
              # 
     | 
| 
       4 
     | 
    
         
            -
              # 
     | 
| 
       5 
     | 
    
         
            -
              # 
     | 
| 
       6 
     | 
    
         
            -
              #
         
     | 
| 
       7 
     | 
    
         
            -
              # 
     | 
| 
       8 
     | 
    
         
            -
              #
         
     | 
| 
       9 
     | 
    
         
            -
              #    
     | 
| 
       10 
     | 
    
         
            -
              #
         
     | 
| 
       11 
     | 
    
         
            -
              #  
     | 
| 
       12 
     | 
    
         
            -
              #
         
     | 
| 
       13 
     | 
    
         
            -
              #    Hello: 0
         
     | 
| 
       14 
     | 
    
         
            -
              #    Hello: 1
         
     | 
| 
       15 
     | 
    
         
            -
              #    Hello: 2
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @liquid_public_docs
         
     | 
| 
      
 5 
     | 
    
         
            +
              # @liquid_type tag
         
     | 
| 
      
 6 
     | 
    
         
            +
              # @liquid_category variable
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @liquid_name increment
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @liquid_summary
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   Creates a new variable, with a default value of 0, that's increased by 1 with each subsequent call.
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @liquid_description
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   Variables that are declared with `increment` are unique to the [layout](/themes/architecture/layouts), [template](/themes/architecture/templates),
         
     | 
| 
      
 12 
     | 
    
         
            +
              #   or [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   [snippets](/themes/architecture#snippets) included in the file.
         
     | 
| 
       16 
14 
     | 
    
         
             
              #
         
     | 
| 
      
 15 
     | 
    
         
            +
              #   Similarly, variables that are created with `increment` are independent from those created with [`assign`](/api/liquid/tags#assign)
         
     | 
| 
      
 16 
     | 
    
         
            +
              #   and [`capture`](/api/liquid/tags#capture). However, `increment` and [`decrement`](/api/liquid/tags#decrement) share
         
     | 
| 
      
 17 
     | 
    
         
            +
              #   variables.
         
     | 
| 
      
 18 
     | 
    
         
            +
              # @liquid_syntax
         
     | 
| 
      
 19 
     | 
    
         
            +
              #   {% increment variable_name %}
         
     | 
| 
      
 20 
     | 
    
         
            +
              # @liquid_syntax_keyword variable_name The name of the variable being incremented.
         
     | 
| 
       17 
21 
     | 
    
         
             
              class Increment < Tag
         
     | 
| 
       18 
22 
     | 
    
         
             
                def initialize(tag_name, markup, options)
         
     | 
| 
       19 
23 
     | 
    
         
             
                  super
         
     | 
| 
       20 
24 
     | 
    
         
             
                  @variable = markup.strip
         
     | 
| 
       21 
25 
     | 
    
         
             
                end
         
     | 
| 
       22 
26 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                def  
     | 
| 
      
 27 
     | 
    
         
            +
                def render_to_output_buffer(context, output)
         
     | 
| 
       24 
28 
     | 
    
         
             
                  value = context.environments.first[@variable] ||= 0
         
     | 
| 
       25 
29 
     | 
    
         
             
                  context.environments.first[@variable] = value + 1
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  output << value.to_s
         
     | 
| 
      
 32 
     | 
    
         
            +
                  output
         
     | 
| 
       27 
33 
     | 
    
         
             
                end
         
     | 
| 
       28 
34 
     | 
    
         
             
              end
         
     | 
| 
       29 
35 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
              Template.register_tag('increment' 
     | 
| 
      
 36 
     | 
    
         
            +
              Template.register_tag('increment', Increment)
         
     | 
| 
       31 
37 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Liquid
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @liquid_public_docs
         
     | 
| 
      
 5 
     | 
    
         
            +
              # @liquid_type tag
         
     | 
| 
      
 6 
     | 
    
         
            +
              # @liquid_category syntax
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @liquid_name inline_comment
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @liquid_summary
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   Prevents an expression from being rendered or output.
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @liquid_description
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   Any text inside an `inline_comment` tag won't be rendered or output.
         
     | 
| 
      
 12 
     | 
    
         
            +
              #
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   You can create multi-line inline comments. However, each line must begin with a `#`.
         
     | 
| 
      
 14 
     | 
    
         
            +
              # @liquid_syntax
         
     | 
| 
      
 15 
     | 
    
         
            +
              #   {% # content %}
         
     | 
| 
      
 16 
     | 
    
         
            +
              # @liquid_syntax_keyword content The content of the comment.
         
     | 
| 
      
 17 
     | 
    
         
            +
              class InlineComment < Tag
         
     | 
| 
      
 18 
     | 
    
         
            +
                def initialize(tag_name, markup, options)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  super
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # Semantically, a comment should only ignore everything after it on the line.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # Currently, this implementation doesn't support mixing a comment with another tag
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # but we need to reserve future support for this and prevent the introduction
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # of inline comments from being backward incompatible change.
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # As such, we're forcing users to put a # symbol on every line otherwise this
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # tag will throw an error.
         
     | 
| 
      
 28 
     | 
    
         
            +
                  if markup.match?(/\n\s*[^#\s]/)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    raise SyntaxError, options[:locale].t("errors.syntax.inline_comment_invalid")
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def render_to_output_buffer(_context, output)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  output
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def blank?
         
     | 
| 
      
 38 
     | 
    
         
            +
                  true
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              Template.register_tag('#', InlineComment)
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/liquid/tags/raw.rb
    CHANGED
    
    | 
         @@ -1,19 +1,61 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Liquid
         
     | 
| 
      
 4 
     | 
    
         
            +
              # @liquid_public_docs
         
     | 
| 
      
 5 
     | 
    
         
            +
              # @liquid_type tag
         
     | 
| 
      
 6 
     | 
    
         
            +
              # @liquid_category syntax
         
     | 
| 
      
 7 
     | 
    
         
            +
              # @liquid_name raw
         
     | 
| 
      
 8 
     | 
    
         
            +
              # @liquid_summary
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   Outputs any Liquid code as text instead of rendering it.
         
     | 
| 
      
 10 
     | 
    
         
            +
              # @liquid_syntax
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   {% raw %}
         
     | 
| 
      
 12 
     | 
    
         
            +
              #     expression
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   {% endraw %}
         
     | 
| 
      
 14 
     | 
    
         
            +
              # @liquid_syntax_keyword expression The expression to be output without being rendered.
         
     | 
| 
       2 
15 
     | 
    
         
             
              class Raw < Block
         
     | 
| 
      
 16 
     | 
    
         
            +
                Syntax = /\A\s*\z/
         
     | 
| 
       3 
17 
     | 
    
         
             
                FullTokenPossiblyInvalid = /\A(.*)#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om
         
     | 
| 
       4 
18 
     | 
    
         | 
| 
      
 19 
     | 
    
         
            +
                def initialize(tag_name, markup, parse_context)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  super
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  ensure_valid_markup(tag_name, markup, parse_context)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       5 
25 
     | 
    
         
             
                def parse(tokens)
         
     | 
| 
       6 
     | 
    
         
            -
                  @ 
     | 
| 
       7 
     | 
    
         
            -
                   
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                       
     | 
| 
       11 
     | 
    
         
            -
                      return if block_delimiter == $2
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @body = +''
         
     | 
| 
      
 27 
     | 
    
         
            +
                  while (token = tokens.shift)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    if token =~ FullTokenPossiblyInvalid && block_delimiter == Regexp.last_match(2)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      @body << Regexp.last_match(1) if Regexp.last_match(1) != ""
         
     | 
| 
      
 30 
     | 
    
         
            +
                      return
         
     | 
| 
       12 
31 
     | 
    
         
             
                    end
         
     | 
| 
       13 
     | 
    
         
            -
                    @ 
     | 
| 
      
 32 
     | 
    
         
            +
                    @body << token unless token.empty?
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  raise_tag_never_closed(block_name)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def render_to_output_buffer(_context, output)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  output << @body
         
     | 
| 
      
 40 
     | 
    
         
            +
                  output
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def nodelist
         
     | 
| 
      
 44 
     | 
    
         
            +
                  [@body]
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def blank?
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @body.empty?
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                protected
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def ensure_valid_markup(tag_name, markup, parse_context)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  unless Syntax.match?(markup)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    raise SyntaxError, parse_context.locale.t("errors.syntax.tag_unexpected_args", tag: tag_name)
         
     | 
| 
       14 
56 
     | 
    
         
             
                  end
         
     | 
| 
       15 
57 
     | 
    
         
             
                end
         
     | 
| 
       16 
58 
     | 
    
         
             
              end
         
     | 
| 
       17 
59 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
              Template.register_tag('raw' 
     | 
| 
      
 60 
     | 
    
         
            +
              Template.register_tag('raw', Raw)
         
     | 
| 
       19 
61 
     | 
    
         
             
            end
         
     |