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}+)(\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, #strict_parse_with_error_mode_fallback

Constructor Details

#initialize(tag_name, markup, options) ⇒ Render

Returns a new instance of Render.

Raises:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/liquid/tags/render.rb', line 36

def initialize(tag_name, markup, options)
  super

  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

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)


56
57
58
# File 'lib/liquid/tags/render.rb', line 56

def for_loop?
  @is_for_loop
end

#render_tag(context, output) ⇒ Object

Raises:

  • (::ArgumentError)


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/liquid/tags/render.rb', line 64

def render_tag(context, output)
  # The expression should be a String literal, which parses to a String object
  template_name = @template_name_expr
  raise ::ArgumentError unless template_name.is_a?(String)

  partial = PartialCache.load(
    template_name,
    context: context,
    parse_context: parse_context,
  )

  context_variable_name = @alias_name || template_name.split('/').last

  render_partial_func = ->(var, forloop) {
    inner_context               = context.new_isolated_subcontext
    inner_context.template_name = partial.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



60
61
62
# File 'lib/liquid/tags/render.rb', line 60

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