class Tilt::Template

  1. lib/tilt/template.rb
Superclass: Object

Base class for template implementations. Subclasses must implement the prepare method and one of the evaluate or precompiled_template methods.

Constants

CLASS_METHOD = Kernel.instance_method(:class)  
USE_BIND_CALL = RUBY_VERSION >= '3'  

Attributes

compiled_path [R]

A path ending in .rb that the template code will be written to, then required, instead of being evaled. This is useful for determining coverage of compiled template code, or to use static analysis tools on the compiled template code.

data [R]

Template source; loaded from a file or given directly.

default_encoding [R]

The encoding of the source data. Defaults to the default_encoding-option if present. You may override this method in your template class if you have a better hint of the data’s encoding.

file [R]

The name of the file where the template data was loaded from.

line [R]

The line number in file where template data was loaded from.

options [R]

A Hash of template engine specific options. This is passed directly to the underlying engine and is not used by the generic template interface.

Public Class methods

default_mime_type()

Use .metadata[:mime_type] instead.

[show source]
   # File lib/tilt/template.rb
45 def default_mime_type
46   metadata[:mime_type]
47 end
default_mime_type=(value)

Use .metadata[:mime_type] = val instead.

[show source]
   # File lib/tilt/template.rb
50 def default_mime_type=(value)
51   metadata[:mime_type] = value
52 end
metadata()

An empty Hash that the template engine can populate with various metadata.

[show source]
   # File lib/tilt/template.rb
40 def metadata
41   @metadata ||= {}
42 end
new(file=nil, line=nil, options=nil)

Create a new template with the file, line, and options specified. By default, template data is read from the file. When a block is given, it should read template data and return as a String. When file is nil, a block is required.

All arguments are optional. The following options are respected and are used by Tilt::Template itself and not the underlying template libraries:

:default_encoding

Force the encoding of the template to the given encoding.

:skip_compiled_encoding_detection

Do not scan template code for an encoding magic comment.

:fixed_locals

Force a specific method parameter signature, and call the method with a splat of locals, instead of passing the locals hash as a positional argument, and extracting locals from that. Should be a string containing the parameters for the compiled method, surrounded by parentheses. Can be set to false to disable the scan for embedded fixed locals.

:extract_fixed_locals

Whether embedded fixed locals should be scanned for and extracted from the template code.

:default_fixed_locals

Similar to fixed_locals, but lowest priority, only used if :fixed_locals is not provided and no embedded locals are found (or scanned for).

:scope_class

Force the scope class used for the method. By default, uses the class of the scope provided to render.

[show source]
    # File lib/tilt/template.rb
 82 def initialize(file=nil, line=nil, options=nil)
 83   @file, @line, @options = nil, 1, nil
 84 
 85   process_arg(options)
 86   process_arg(line)
 87   process_arg(file)
 88 
 89   raise ArgumentError, "file or block required" unless @file || block_given?
 90 
 91   @options ||= {}
 92 
 93   # Force a specific scope class, instead of using the class of the provided
 94   # scope as the scope class.
 95   @scope_class = @options.delete :scope_class
 96 
 97   # Force the encoding of the input data
 98   @default_encoding = @options.delete :default_encoding
 99 
100   # Skip encoding detection from magic comments and forcing that encoding
101   # for compiled templates
102   @skip_compiled_encoding_detection = @options.delete :skip_compiled_encoding_detection
103 
104   # Compiled path to use.  This must be specified as an option if
105   # providing the :scope_class option and using fixed locals,
106   # since template compilation occurs during initialization in that case.
107   if compiled_path = @options.delete(:compiled_path)
108     self.compiled_path = compiled_path
109   end
110 
111   # load template data and prepare (uses binread to avoid encoding issues)
112   @data = block_given? ? yield(self) : read_template_file
113 
114   if @data.respond_to?(:force_encoding)
115     if default_encoding
116       @data = _dup_string_if_frozen(@data)
117       @data.force_encoding(default_encoding)
118     end
119 
120     if !@data.valid_encoding?
121       raise Encoding::InvalidByteSequenceError, "#{eval_file} is not valid #{@data.encoding}"
122     end
123   end
124 
125   set_fixed_locals
126   prepare
127   set_compiled_method_cache
128 end

Public Instance methods

basename(suffix='')

The basename of the template file.

[show source]
    # File lib/tilt/template.rb
138 def basename(suffix='')
139   File.basename(@file, suffix) if @file
140 end
compiled_method(locals_keys, scope_class=nil)

The compiled method for the locals keys and scope_class provided. Returns an UnboundMethod, which can be used to define methods directly on the scope class, which are much faster to call than Tilt’s normal rendering.

[show source]
    # File lib/tilt/template.rb
191 def compiled_method(locals_keys, scope_class=nil)
192   if @fixed_locals
193     if @scope_class
194       return @compiled_method
195     else
196       key = scope_class
197     end
198   elsif @scope_class
199     key = locals_keys.dup.freeze
200   else
201     key = [scope_class, locals_keys].freeze
202   end
203 
204   LOCK.synchronize do
205     if meth = @compiled_method[key]
206       return meth
207     end
208   end
209   meth = compile_template_method(locals_keys, scope_class)
210   LOCK.synchronize do
211     @compiled_method[key] = meth
212   end
213   meth
214 end
compiled_path=(path)

Set the prefix to use for compiled paths, similar to using the :compiled_path template option. Note that this only has affect for future template compilations. When using the :scope_class template option, and using fixed_locals, calling this after the template is created has no effect, since the template is compiled during initialization in that case. It is recommended to use the :compiled_path template option instead of this method in new code.

[show source]
    # File lib/tilt/template.rb
177 def compiled_path=(path)
178   if path
179     # Use expanded paths when loading, since that is helpful
180     # for coverage.  Remove any .rb suffix, since that will
181     # be added back later.
182     path = File.expand_path(path.sub(/\.rb\z/i, ''))
183   end
184   @compiled_path = path
185 end
eval_file()

The filename used in backtraces to describe the template.

[show source]
    # File lib/tilt/template.rb
150 def eval_file
151   @file || '(__TEMPLATE__)'
152 end
fixed_locals?()

Whether the template uses fixed locals.

[show source]
    # File lib/tilt/template.rb
155 def fixed_locals?
156   @fixed_locals ? true : false
157 end
metadata()

An empty Hash that the template engine can populate with various metadata.

[show source]
    # File lib/tilt/template.rb
161 def metadata
162   if respond_to?(:allows_script?)
163     self.class.metadata.merge(:allows_script => allows_script?)
164   else
165     self.class.metadata
166   end
167 end
name()

The template file’s basename with all extensions chomped off.

[show source]
    # File lib/tilt/template.rb
143 def name
144   if bname = basename
145     bname.split('.', 2).first
146   end
147 end
render(scope=nil, locals=nil, &block)

Render the template in the given scope with the locals specified. If a block is given, it is typically available within the template via yield.

[show source]
    # File lib/tilt/template.rb
133 def render(scope=nil, locals=nil, &block)
134   evaluate(scope || Object.new, locals || EMPTY_HASH, &block)
135 end

Protected Instance methods

evaluate(scope, locals, &block)

Execute the compiled template and return the result string. Template evaluation is guaranteed to be performed in the scope object with the locals specified and with support for yielding to the block.

This method is only used by source generating templates. Subclasses that override render() may not support all features.

[show source]
    # File lib/tilt/template.rb
247 def evaluate(scope, locals, &block)
248   if @fixed_locals
249     locals_keys = EMPTY_ARRAY
250   else
251     locals_keys = locals.keys
252     locals_keys.sort!{|x, y| x.to_s <=> y.to_s}
253   end
254 
255   unless scope_class = @scope_class
256     scope_class = case scope
257     when Object
258       Module === scope ? scope : scope.class
259     else
260       # :nocov:
261       USE_BIND_CALL ? CLASS_METHOD.bind_call(scope) : CLASS_METHOD.bind(scope).call
262       # :nocov:
263     end
264   end
265 
266   evaluate_method(compiled_method(locals_keys, scope_class), scope, locals, &block)
267 end
precompiled(local_keys)

Generates all template source by combining the preamble, template, and postamble and returns a two-tuple of the form: [source, offset], where source is the string containing (Ruby) source code for the template and offset is the integer line offset where line reporting should begin.

Template subclasses may override this method when they need complete control over source generation or want to adjust the default line offset. In most cases, overriding the precompiled_template method is easier and more appropriate.

[show source]
    # File lib/tilt/template.rb
278 def precompiled(local_keys)
279   preamble = precompiled_preamble(local_keys)
280   template = precompiled_template(local_keys)
281   postamble = precompiled_postamble(local_keys)
282   source = String.new
283 
284   unless skip_compiled_encoding_detection?
285     # Ensure that our generated source code has the same encoding as the
286     # the source code generated by the template engine.
287     template_encoding = extract_encoding(template){|t| template = t}
288 
289     if template.encoding != template_encoding
290       # template should never be frozen here. If it was frozen originally,
291       # then extract_encoding should yield a dup.
292       template.force_encoding(template_encoding)
293     end
294   end
295 
296   source.force_encoding(template.encoding)
297   source << preamble << "\n" << template << "\n" << postamble
298 
299   [source, preamble.count("\n")+1]
300 end
precompiled_postamble(local_keys)
[show source]
    # File lib/tilt/template.rb
316 def precompiled_postamble(local_keys)
317   ''
318 end
precompiled_preamble(local_keys)
[show source]
    # File lib/tilt/template.rb
312 def precompiled_preamble(local_keys)
313   ''
314 end
precompiled_template(local_keys)

A string containing the (Ruby) source code for the template. The default Template#evaluate implementation requires either this method or the precompiled method be overridden. When defined, the base Template guarantees correct file/line handling, locals support, custom scopes, proper encoding, and support for template compilation.

[show source]
    # File lib/tilt/template.rb
308 def precompiled_template(local_keys)
309   raise NotImplementedError
310 end
prepare()

Do whatever preparation is necessary to setup the underlying template engine. Called immediately after template data is loaded. Instance variables set in this method are available when evaluate is called.

Empty by default as some subclasses do not need separate preparation.

[show source]
    # File lib/tilt/template.rb
235 def prepare
236 end
skip_compiled_encoding_detection?()
[show source]
    # File lib/tilt/template.rb
226 def skip_compiled_encoding_detection?
227   @skip_compiled_encoding_detection
228 end