Class: Twig::Environment

Inherits:
Object
  • Object
show all
Defined in:
lib/twig/environment.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(loader, options = {}) ⇒ Environment

Returns a new instance of Environment.

Parameters:



12
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
# File 'lib/twig/environment.rb', line 12

def initialize(loader, options = {})
  @loader = loader
  @extension_set = ExtensionSet.new
  @options = {
    cache: false,
    debug: false,
    charset: 'UTF-8',
    strict_variables: false,
    autoescape: :html,
    auto_reload: nil,
    allow_helper_methods: false,
  }.merge(options)

  @auto_reload = @options[:auto_reload].nil? ? @options[:debug] : @options[:auto_reload]
  @charset = @options[:charset]
  @strict_variables = @options[:strict_variables]

  self.cache = @options[:cache]

  @loaded_templates = {}
  @globals = {}
  @runtimes = {}
  @runtime_loaders = []
  @default_runtime_loader = RuntimeLoader::Factory.new({
    Runtime::Escaper => -> { Runtime::Escaper.new(@charset) },
  })

  add_extension(Extension::Core.new)
  add_extension(Extension::Escaper.new(@options[:autoescape]))
end

Instance Attribute Details

#cacheCache::Base

Returns:



6
7
8
# File 'lib/twig/environment.rb', line 6

def cache
  @cache
end

#charsetCache::Base (readonly)

Returns:



6
7
8
# File 'lib/twig/environment.rb', line 6

def charset
  @charset
end

#loaderTwig::Loader::Base (readonly)

Returns:



9
10
11
# File 'lib/twig/environment.rb', line 9

def loader
  @loader
end

Instance Method Details

#add_extension(extension) ⇒ Object

Parameters:



161
162
163
# File 'lib/twig/environment.rb', line 161

def add_extension(extension)
  extension_set.add(extension)
end

#add_global(name, value) ⇒ Object



216
217
218
# File 'lib/twig/environment.rb', line 216

def add_global(name, value)
  @globals[name] = value
end

#add_runtime_loader(loader) ⇒ Object

Parameters:



182
183
184
# File 'lib/twig/environment.rb', line 182

def add_runtime_loader(loader)
  runtime_loaders << loader
end

#allow_helper_methods?Boolean

Returns:

  • (Boolean)


274
275
276
# File 'lib/twig/environment.rb', line 274

def allow_helper_methods?
  @options[:allow_helper_methods]
end

#compile(node) ⇒ Object

Parameters:



236
237
238
# File 'lib/twig/environment.rb', line 236

def compile(node)
  compiler.compile(node).source
end

#compile_source(source) ⇒ Object

Parameters:



241
242
243
244
245
246
# File 'lib/twig/environment.rb', line 241

def compile_source(source)
  compile(parse(tokenize(source)))
rescue Error::Base => e
  e.source_context = source
  raise e
end

#create_template(template, name = nil) ⇒ Twig::Template

Returns:



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/twig/environment.rb', line 131

def create_template(template, name = nil)
  hash = ::Digest::SHA256.hexdigest(template)
  name = if name.nil?
           "__string_template__#{hash}"
         else
           "#{name} (string template #{hash})"
         end

  chain_loader = Loader::Chain.new([
    Loader::Hash.new({ name => template }),
    current = loader,
  ])

  @loader = chain_loader

  cls = template_class(name)
  TemplateWrapper.new(self, load_template(cls, name))
ensure
  @loader = current
end

#debug?Boolean

Returns:

  • (Boolean)


278
279
280
# File 'lib/twig/environment.rb', line 278

def debug?
  @options[:debug]
end

#expression_parsersExpressionParser::ExpressionParsers



187
188
189
# File 'lib/twig/environment.rb', line 187

def expression_parsers
  extension_set.expression_parsers
end

#extension(name) ⇒ Object



152
153
154
# File 'lib/twig/environment.rb', line 152

def extension(name)
  extension_set.get(name)
end

#extension?(name) ⇒ Boolean

Returns:

  • (Boolean)


156
157
158
# File 'lib/twig/environment.rb', line 156

def extension?(name)
  extension_set.has?(name)
end

#filter(name) ⇒ TwigFilter?

Returns:



192
193
194
# File 'lib/twig/environment.rb', line 192

def filter(name)
  extension_set.filter(name)
end

#function(name) ⇒ TwigFunction?

Returns:



197
198
199
# File 'lib/twig/environment.rb', line 197

def function(name)
  extension_set.function(name)
end

#globalsObject



220
221
222
# File 'lib/twig/environment.rb', line 220

def globals
  @resolved_globals ||= extension_set.globals.merge(@globals)
end

#load(name) ⇒ Twig::TemplateWrapper

Parameters:

Returns:



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/twig/environment.rb', line 51

def load(name)
  if name.is_a?(Twig::TemplateWrapper)
    return name
  end

  cls = template_class(name)
  TemplateWrapper.new(
    self,
    load_template(cls, name)
  )
end

#load_and_compile(name) ⇒ String

Returns:

  • (String)


249
250
251
252
# File 'lib/twig/environment.rb', line 249

def load_and_compile(name)
  source = loader.get_source_context(name)
  compile_source(source)
end

#load_template(cls, name, index: nil) ⇒ Twig::Template

Parameters:

  • cls (String)

    The class name to load

  • name (String)

    The template name

  • index (Integer, nil) (defaults to: nil)

    Index for embedded templates

Returns:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/twig/environment.rb', line 90

def load_template(cls, name, index: nil)
  main_cls = cls

  if index
    cls += "___#{index}"
  end

  if !index.nil? && Twig.const_defined?(cls)
    return @loaded_templates[cls] = Twig.const_get(cls).new(self)
  end

  cache_key = cache.generate_key(name, main_cls)

  # If not auto_reloading just use whatever is in the cache
  if !@auto_reload || template_fresh?(name, cache.timestamp(cache_key))
    if @loaded_templates.key?(cls)
      return @loaded_templates[cls]
    end

    @cache.load(cache_key)

    if Twig.const_defined?(cls)
      return @loaded_templates[cls] = Twig.const_get(cls).new(self)
    end
  end

  # No caches have fresh template at this point, so write it now
  code = render_ruby(name)

  # File cache loader won't rely on eval
  @cache.write(cache_key, code)
  @cache.load(cache_key)

  # Finally just eval the generated code if cache doesn't
  # create the class
  Twig.module_eval(code) unless Twig.const_defined?(cls)

  @loaded_templates[cls] = Twig.const_get(cls).new(self)
end

#node_visitorsArray<NodeVisitor::Base>

Returns:



212
213
214
# File 'lib/twig/environment.rb', line 212

def node_visitors
  extension_set.node_visitors
end

#parse(stream) ⇒ Object

Parameters:



231
232
233
# File 'lib/twig/environment.rb', line 231

def parse(stream)
  parser.parse(stream)
end

#resolve_template(names) ⇒ Object

Parameters:

Raises:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/twig/environment.rb', line 64

def resolve_template(names)
  unless names.is_a?(Array)
    return load(names)
  end

  count = names.length

  names.each do |name|
    if name.is_a?(Twig::TemplateWrapper)
      return name
    end

    unless count == 1 || loader.exists?(name)
      next
    end

    return load(name)
  end

  raise Error::Loader, "Unable to find one of the following templates: \"#{names.join('", "')}\"."
end

#runtime(klass) ⇒ Object

Raises:



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/twig/environment.rb', line 165

def runtime(klass)
  return runtimes[klass] if runtimes.key?(klass)

  runtime_loaders.each do |loader|
    if (runtime = loader.load(klass))
      return runtimes[klass] = runtime
    end
  end

  if (runtime = default_runtime_loader.load(klass))
    return runtimes[klass] = runtime
  end

  raise Error::Runtime, "Unable to load the \"#{klass}\" runtime."
end

#strict_variables?Boolean

Returns:

  • (Boolean)


282
283
284
# File 'lib/twig/environment.rb', line 282

def strict_variables?
  @strict_variables
end

#template_class(name, index = nil) ⇒ Object



43
44
45
46
47
# File 'lib/twig/environment.rb', line 43

def template_class(name, index = nil)
  key = loader.get_cache_key(name)

  "Compiled::Template_#{::Digest::SHA256.hexdigest(key)}#{"___#{index}" if index}"
end

#template_fresh?(name, time) ⇒ Boolean

Parameters:

  • name (String)
  • time (Integer)

Returns:

  • (Boolean)


256
257
258
259
# File 'lib/twig/environment.rb', line 256

def template_fresh?(name, time)
  # @todo check extension set last modified
  loader.fresh?(name, time)
end

#test(name) ⇒ TwigTest?

Returns:



202
203
204
# File 'lib/twig/environment.rb', line 202

def test(name)
  extension_set.test(name)
end

#token_parser(name) ⇒ TokenParser::Base?

Returns:



207
208
209
# File 'lib/twig/environment.rb', line 207

def token_parser(name)
  extension_set.token_parser(name)
end

#tokenize(source) ⇒ TokenStream

Parameters:

Returns:



226
227
228
# File 'lib/twig/environment.rb', line 226

def tokenize(source)
  lexer.tokenize(source)
end