Class: Liquid::Render

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

Defined Under Namespace

Classes: ParseTreeVisitor

Constant Summary collapse

FOR =
'for'
SYNTAX =
/(#{QuotedString}+|#{VariableSegment}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o

Instance Attribute Summary collapse

Attributes inherited from Tag

#line_number, #nodelist, #parse_context, #tag_name

Instance Method Summary collapse

Methods inherited from Tag

#blank?, disable_tags, #name, parse, #parse, #raw, #render

Methods included from ParserSwitching

#parse_with_selected_parser, #rigid_mode?, #strict_parse_with_error_mode_fallback

Constructor Details

#initialize(tag_name, markup, options) ⇒ Render

Returns a new instance of Render.



36
37
38
39
# File 'lib/liquid/tags/render.rb', line 36

def initialize(tag_name, markup, options)
  super
  parse_with_selected_parser(markup)
end

Instance Attribute Details

#alias_nameObject (readonly)

Returns the value of attribute alias_name.



34
35
36
# File 'lib/liquid/tags/render.rb', line 34

def alias_name
  @alias_name
end

#attributesObject (readonly)

Returns the value of attribute attributes.



34
35
36
# File 'lib/liquid/tags/render.rb', line 34

def attributes
  @attributes
end

#template_name_exprObject (readonly)

Returns the value of attribute template_name_expr.



34
35
36
# File 'lib/liquid/tags/render.rb', line 34

def template_name_expr
  @template_name_expr
end

#variable_name_exprObject (readonly)

Returns the value of attribute variable_name_expr.



34
35
36
# File 'lib/liquid/tags/render.rb', line 34

def variable_name_expr
  @variable_name_expr
end

Instance Method Details

#for_loop?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/liquid/tags/render.rb', line 41

def for_loop?
  @is_for_loop
end

#lax_parse(markup) ⇒ Object

Raises:



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/liquid/tags/render.rb', line 124

def lax_parse(markup)
  raise SyntaxError, options[:locale].t("errors.syntax.render") unless markup =~ SYNTAX

  template_name = Regexp.last_match(1)
  with_or_for = Regexp.last_match(3)
  variable_name = Regexp.last_match(4)

  @alias_name = Regexp.last_match(6)
  @variable_name_expr = variable_name ? parse_expression(variable_name) : nil
  @template_name_expr = parse_expression(template_name)
  @is_for_loop = (with_or_for == FOR)

  @attributes = {}
  markup.scan(TagAttributes) do |key, value|
    @attributes[key] = parse_expression(value)
  end
end

#render_tag(context, output) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
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
# File 'lib/liquid/tags/render.rb', line 49

def render_tag(context, output)
  template = context.evaluate(@template_name_expr)

  if template.respond_to?(:to_partial)
    partial = template.to_partial
    template_name = template.filename
    context_variable_name = @alias_name || template.name
  elsif @template_name_expr.is_a?(String)
    partial = PartialCache.load(template, context: context, parse_context: parse_context)
    template_name = partial.name
    context_variable_name = @alias_name || template_name.split('/').last
  else
    raise ::ArgumentError
  end

  render_partial_func = ->(var, forloop) {
    inner_context               = context.new_isolated_subcontext
    inner_context.template_name = template_name
    inner_context.partial       = true
    inner_context['forloop']    = forloop if forloop

    @attributes.each do |key, value|
      inner_context[key] = context.evaluate(value)
    end
    inner_context[context_variable_name] = var unless var.nil?
    partial.render_to_output_buffer(inner_context, output)
    forloop&.send(:increment!)
  }

  variable = @variable_name_expr ? context.evaluate(@variable_name_expr) : nil
  if @is_for_loop && variable.respond_to?(:each) && variable.respond_to?(:count)
    forloop = Liquid::ForloopDrop.new(template_name, variable.count, nil)
    variable.each { |var| render_partial_func.call(var, forloop) }
  else
    render_partial_func.call(variable, nil)
  end

  output
end

#render_to_output_buffer(context, output) ⇒ Object



45
46
47
# File 'lib/liquid/tags/render.rb', line 45

def render_to_output_buffer(context, output)
  render_tag(context, output)
end

#rigid_parse(markup) ⇒ Object

render (string) (with|for expression)? (as id)? (key: value)*



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/liquid/tags/render.rb', line 90

def rigid_parse(markup)
  p = @parse_context.new_parser(markup)

  @template_name_expr = parse_expression(rigid_template_name(p), safe: true)
  with_or_for         = p.id?("for") || p.id?("with")
  @variable_name_expr = safe_parse_expression(p) if with_or_for
  @alias_name         = p.consume(:id) if p.id?("as")
  @is_for_loop        = (with_or_for == FOR)

  p.consume?(:comma)

  @attributes = {}
  while p.look(:id)
    key = p.consume
    p.consume(:colon)
    @attributes[key] = safe_parse_expression(p)
    p.consume?(:comma) # optional comma
  end

  p.consume(:end_of_string)
end

#rigid_template_name(p) ⇒ Object

Raises:



112
113
114
115
116
117
118
# File 'lib/liquid/tags/render.rb', line 112

def rigid_template_name(p)
  return p.consume(:string) if p.look(:string)
  return p.consume(:id) if p.look(:id)

  found = p.consume || "nothing"
  raise SyntaxError, options[:locale].t("errors.syntax.render_invalid_template_name", found: found)
end

#strict_parse(markup) ⇒ Object



120
121
122
# File 'lib/liquid/tags/render.rb', line 120

def strict_parse(markup)
  lax_parse(markup)
end