Class: Liquid2::RenderTag

Inherits:
Tag
  • Object
show all
Defined in:
lib/liquid2/nodes/tags/render.rb

Overview

The standard render tag.

Instance Attribute Summary

Attributes inherited from Node

#blank, #token

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Tag

#name

Methods inherited from Node

#block_scope, #render_with_disabled_tag_check, #template_scope

Constructor Details

#initialize(token, name, repeat, var, as, args) ⇒ RenderTag

Returns a new instance of RenderTag.

Parameters:



50
51
52
53
54
55
56
57
58
# File 'lib/liquid2/nodes/tags/render.rb', line 50

def initialize(token, name, repeat, var, as, args)
  super(token)
  @template_name = name
  @repeat = repeat
  @var = var
  @as = as&.name
  @args = args
  @blank = false
end

Class Method Details

.parse(token, parser) ⇒ RenderTag

Parameters:

Returns:



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/liquid2/nodes/tags/render.rb', line 13

def self.parse(token, parser)
  name = parser.parse_string
  repeat = false
  var = nil # : Expression?
  as = nil # : Identifier?

  if parser.current_kind == :token_for && !%i[token_comma
                                              token_colon].include?(parser.peek_kind)
    parser.next
    repeat = true
    var = parser.parse_primary
    if parser.current_kind == :token_as
      parser.next
      as = parser.parse_identifier
    end
  elsif parser.current_kind == :token_with && !%i[token_comma
                                                  token_colon].include?(parser.peek_kind)
    parser.next
    var = parser.parse_primary
    if parser.current_kind == :token_as
      parser.next
      as = parser.parse_identifier
    end
  end

  parser.next if parser.current_kind == :token_comma
  args = parser.parse_keyword_arguments
  parser.carry_whitespace_control
  parser.eat(:token_tag_end)
  new(token, name, repeat, var, as, args)
end

Instance Method Details

#children(static_context, include_partials: true) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/liquid2/nodes/tags/render.rb', line 102

def children(static_context, include_partials: true)
  return [] unless include_partials

  name = static_context.evaluate(@template_name)
  template = static_context.env.get_template(name.to_s, context: static_context, tag: :include)
  template.ast
rescue LiquidTemplateNotFoundError => e
  e.token = @token
  e.template_name = static_context.template.full_name
  raise e
end

#expressionsObject



114
115
116
117
118
119
# File 'lib/liquid2/nodes/tags/render.rb', line 114

def expressions
  exprs = [@template_name]
  exprs << @var if @var
  exprs.concat(@args.map(&:value))
  exprs
end

#partial_scopeObject



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/liquid2/nodes/tags/render.rb', line 121

def partial_scope
  scope = @args.map { |arg| Identifier.new([:token_word, arg.name, arg.token.last]) }

  if @var
    if @as
      scope << @as # steep:ignore
    elsif @template_name.is_a?(String)
      scope << Identifier.new([:token_word, @template_name.split(".").first, @token.last])
    end
  end

  Partial.new(@template_name, :isolated, scope)
end

#render(context, buffer) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/liquid2/nodes/tags/render.rb', line 60

def render(context, buffer)
  template = context.env.get_template(@template_name, context: context, tag: :render)
  namespace = @args.to_h { |arg| [arg.name, context.evaluate(arg.value)] }

  ctx = context.copy(namespace,
                     template: template,
                     disabled_tags: DISABLED_TAGS,
                     carry_loop_iterations: true)

  if @var
    val = context.evaluate(@var || raise)
    key = @as || template.name.split(".").first

    if @repeat && val.respond_to?(:[]) && val.respond_to?(:size)
      ctx.raise_for_loop_limit(length: val.size)

      forloop = ForLoop.new(
        key, val.size, context.env.undefined("parentloop")
      )

      namespace["forloop"] = forloop

      index = 0
      while index < val.length
        namespace[key] = val[index]
        index += 1
        forloop.next
        template.render_with_context(ctx, buffer, partial: true, block_scope: true)
      end
    else
      namespace[key] = val
      template.render_with_context(ctx, buffer, partial: true, block_scope: true)
    end
  else
    template.render_with_context(ctx, buffer, partial: true, block_scope: true)
  end
rescue LiquidTemplateNotFoundError => e
  e.token = @template_name
  e.template_name = context.template.full_name
  raise e
end