Class: Liquid::Variable

Inherits:
Object
  • Object
show all
Defined in:
lib/liquid/variable.rb

Overview

Holds variables. Variables are only loaded “just in time” and are not evaluated as part of the render stage

{{ monkey }}
{{ user.name }}

Variables can be combined with filters:

{{ user | link }}

Constant Summary collapse

FilterParser =
/(?:#{FilterSeparator}|(?:\s*(?:#{QuotedFragment}|#{ArgumentSeparator})\s*)+)/o
EasyParse =
/^ *(\w+(?:\.\w+)*) *$/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(markup, options = {}) ⇒ Variable

Returns a new instance of Variable.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/liquid/variable.rb', line 18

def initialize(markup, options = {})
  @markup  = markup
  @name    = nil
  @options = options || {}
  

  case @options[:error_mode] || Template.error_mode
  when :strict then strict_parse(markup)
  when :lax    then lax_parse(markup)
  when :warn
    begin
      strict_parse(markup)
    rescue SyntaxError => e
      @warnings ||= []
      @warnings << e
      lax_parse(markup)
    end
  end
end

Instance Attribute Details

#filtersObject

Returns the value of attribute filters.



16
17
18
# File 'lib/liquid/variable.rb', line 16

def filters
  @filters
end

#nameObject

Returns the value of attribute name.



16
17
18
# File 'lib/liquid/variable.rb', line 16

def name
  @name
end

#warningsObject

Returns the value of attribute warnings.



16
17
18
# File 'lib/liquid/variable.rb', line 16

def warnings
  @warnings
end

Instance Method Details

#lax_parse(markup) ⇒ Object



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

def lax_parse(markup)
  @filters = []
  if match = markup.match(/\s*(#{QuotedFragment})(.*)/o)
    @name = match[1]
    if match[2].match(/#{FilterSeparator}\s*(.*)/o)
      filters = Regexp.last_match(1).scan(FilterParser)
      filters.each do |f|
        if matches = f.match(/\s*(\w+)/)
          filtername = matches[1]
          filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o).flatten
          @filters << [filtername, filterargs]
        end
      end
    end
  end
end

#parse_filterargs(p) ⇒ Object



78
79
80
81
82
83
84
85
86
# File 'lib/liquid/variable.rb', line 78

def parse_filterargs(p)
  # first argument
  filterargs = [p.argument]
  # followed by comma separated others
  while p.consume?(:comma)
    filterargs << p.argument
  end
  filterargs
end

#render(context) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/liquid/variable.rb', line 88

def render(context)
  return '' if @name.nil?
  @filters.inject(context[@name]) do |output, filter|
    filterargs = []
    keyword_args = {}
    filter[1].to_a.each do |a|
      if matches = a.match(/\A#{TagAttributes}\z/o)
        keyword_args[matches[1]] = context[matches[2]]
      else
        filterargs << context[a]
      end
    end
    filterargs << keyword_args unless keyword_args.empty?
    begin
      output = context.invoke(filter[0], output, *filterargs)
    rescue FilterNotFound
      raise FilterNotFound, "Error - filter '#{filter[0]}' in '#{@markup.strip}' could not be found."
    end
  end
end

#strict_parse(markup) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/liquid/variable.rb', line 55

def strict_parse(markup)
  # Very simple valid cases
  if markup =~ EasyParse
    @name = $1
    @filters = []
    return
  end

  @filters = []
  p = Parser.new(markup)
  # Could be just filters with no input
  @name = p.look(:pipe) ? '' : p.expression
  while p.consume?(:pipe)
    filtername = p.consume(:id)
    filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
    @filters << [filtername, filterargs]
  end
  p.consume(:end_of_string)
rescue SyntaxError => e
  e.message << " in \"{{#{markup}}}\""
  raise e
end