Class: Liquid::Template

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

Overview

Templates are central to liquid. Interpretating templates is a two step process. First you compile the source code you got. During compile time some extensive error checking is performed. your code should expect to get some SyntaxErrors.

After you have a compiled template you can then render it. You can use a compiled template over and over again and keep it cached.

Example:

template = Liquid::Template.parse(source)
template.render('user_name' => 'bob')

Constant Summary collapse

DEFAULT_OPTIONS =
{
  :locale => I18n.new
}
@@file_system =
BlankFileSystem.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTemplate

creates a new Template from an array of tokens. Use Template.parse instead



77
78
79
# File 'lib/liquid/template.rb', line 77

def initialize
  @resource_limits = {}
end

Instance Attribute Details

#resource_limitsObject

Returns the value of attribute resource_limits.



21
22
23
# File 'lib/liquid/template.rb', line 21

def resource_limits
  @resource_limits
end

#rootObject

Returns the value of attribute root.



21
22
23
# File 'lib/liquid/template.rb', line 21

def root
  @root
end

Class Method Details

.count_linesObject



46
47
48
# File 'lib/liquid/template.rb', line 46

def count_lines
  @count_lines || false
end

.count_lines=(flag) ⇒ Object

Disabled (false) for better performance



42
43
44
# File 'lib/liquid/template.rb', line 42

def count_lines=(flag)
  @count_lines = flag
end

.error_modeObject



58
59
60
# File 'lib/liquid/template.rb', line 58

def error_mode
  @error_mode || :lax
end

.error_mode=(mode) ⇒ Object

Sets how strict the parser should be. :lax acts like liquid 2.5 and silently ignores malformed tags in most cases. :warn is the default and will give deprecation warnings when invalid syntax is used. :strict will enforce correct syntax.



54
55
56
# File 'lib/liquid/template.rb', line 54

def error_mode=(mode)
  @error_mode = mode
end

.file_systemObject



25
26
27
# File 'lib/liquid/template.rb', line 25

def file_system
  @@file_system
end

.file_system=(obj) ⇒ Object



29
30
31
# File 'lib/liquid/template.rb', line 29

def file_system=(obj)
  @@file_system = obj
end

.parse(source, options = {}) ⇒ Object

creates a new Template object from liquid source code



69
70
71
72
73
# File 'lib/liquid/template.rb', line 69

def parse(source, options = {})
  template = Template.new
  template.parse(source, options)
  template
end

.register_filter(mod) ⇒ Object

Pass a module with filter methods which should be available to all liquid views. Good for registering the standard library



64
65
66
# File 'lib/liquid/template.rb', line 64

def register_filter(mod)
  Strainer.global_filter(mod)
end

.register_tag(name, klass) ⇒ Object



33
34
35
# File 'lib/liquid/template.rb', line 33

def register_tag(name, klass)
  tags[name.to_s] = klass
end

.tagsObject



37
38
39
# File 'lib/liquid/template.rb', line 37

def tags
  @tags ||= {}
end

Instance Method Details

#_walk(list, memo = {}, &block) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/liquid/template.rb', line 178

def _walk(list, memo = {}, &block)
  list.each do |node|
    saved_memo = memo.clone

    # puts "fetch ! #{node.respond_to?(:name) ? node.name : 'String'} / #{node.respond_to?(:nodelist)}"
    if block_given?
      # puts "youpi ! #{node.name}"
      _memo = yield(node, memo) || {}
      memo.merge!(_memo)
    end

    if node.respond_to?(:nodelist) && !node.nodelist.blank?
      self._walk(node.nodelist, memo, &block)
    end

    memo = saved_memo
  end
  memo
end

#assignsObject



99
100
101
# File 'lib/liquid/template.rb', line 99

def assigns
  @assigns ||= {}
end

#errorsObject



107
108
109
# File 'lib/liquid/template.rb', line 107

def errors
  @errors ||= []
end

#instance_assignsObject



103
104
105
# File 'lib/liquid/template.rb', line 103

def instance_assigns
  @instance_assigns ||= {}
end

#parse(source, options = {}) ⇒ Object

Parse source code. Returns self for easy chaining



83
84
85
86
87
88
# File 'lib/liquid/template.rb', line 83

def parse(source, options = {})
  _options = { template: self }.merge(DEFAULT_OPTIONS).merge(options)
  @root = Document.new(tokenize(source), _options)
  @warnings = nil
  self
end

#registersObject



95
96
97
# File 'lib/liquid/template.rb', line 95

def registers
  @registers ||= {}
end

#render(*args) ⇒ Object

Render takes a hash with local variables.

if you use the same filters over and over again consider registering them globally with Template.register_filter

Following options can be passed:

* <tt>filters</tt> : array with local filters
* <tt>registers</tt> : hash with register variables. Those can be accessed from
  filters and tags and might be useful to integrate liquid more with its host application


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/liquid/template.rb', line 122

def render(*args)
  return '' if @root.nil?

  context = case args.first
  when Liquid::Context
    args.shift
  when Liquid::Drop
    drop = args.shift
    drop.context = Context.new([drop, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits)
  when Hash
    Context.new([args.shift, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits)
  when nil
    Context.new(assigns, instance_assigns, registers, @rethrow_errors, @resource_limits)
  else
    raise ArgumentError, "Expected Hash or Liquid::Context as parameter"
  end

  case args.last
  when Hash
    options = args.pop

    if options[:registers].is_a?(Hash)
      self.registers.merge!(options[:registers])
    end

    if options[:filters]
      context.add_filters(options[:filters])
    end

  when Module
    context.add_filters(args.pop)
  when Array
    context.add_filters(args.pop)
  end

  begin
    # render the nodelist.
    # for performance reasons we get an array back here. join will make a string out of it.
    result = @root.render(context)
    result.respond_to?(:join) ? result.join : result
  rescue Liquid::MemoryError => e
    context.handle_error(e)
  ensure
    @errors = context.errors
  end
end

#render!(*args) ⇒ Object



169
170
171
# File 'lib/liquid/template.rb', line 169

def render!(*args)
  @rethrow_errors = true; render(*args)
end

#walk(memo = {}, &block) ⇒ Object



173
174
175
176
# File 'lib/liquid/template.rb', line 173

def walk(memo = {}, &block)
  # puts @root.nodelist.inspect
  self._walk(@root.nodelist, memo, &block)
end

#warningsObject



90
91
92
93
# File 'lib/liquid/template.rb', line 90

def warnings
  return [] unless @root
  @warnings ||= @root.warnings
end