Class Tilt::Template
In: lib/tilt.rb
Parent: Object

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

Methods

External Aliases

engine_initialized -> engine_initialized?

Attributes

data  [R]  Template source; loaded from a file or given directly.
engine_initialized  [RW] 
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

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.

[Source]

     # File lib/tilt.rb, line 80
 80:     def initialize(file=nil, line=1, options={}, &block)
 81:       @file, @line, @options = nil, 1, {}
 82: 
 83:       [options, line, file].compact.each do |arg|
 84:         case
 85:         when arg.respond_to?(:to_str)  ; @file = arg.to_str
 86:         when arg.respond_to?(:to_int)  ; @line = arg.to_int
 87:         when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup
 88:         else raise TypeError
 89:         end
 90:       end
 91: 
 92:       raise ArgumentError, "file or block required" if (@file || block).nil?
 93: 
 94:       # call the initialize_engine method if this is the very first time
 95:       # an instance of this class has been created.
 96:       if !self.class.engine_initialized?
 97:         initialize_engine
 98:         self.class.engine_initialized = true
 99:       end
100: 
101:       # used to hold compiled template methods
102:       @compiled_method = {}
103: 
104:       # used on 1.9 to set the encoding if it is not set elsewhere (like a magic comment)
105:       # currently only used if template compiles to ruby
106:       @default_encoding = @options.delete :default_encoding
107: 
108:       # load template data and prepare (uses binread to avoid encoding issues)
109:       @reader = block || lambda { |t| File.respond_to?(:binread) ? File.binread(@file) : File.read(@file) }
110:       @data = @reader.call(self)
111:       prepare
112:     end

Protected Class methods

Redefine itself to use method compilation the next time:

[Source]

     # File lib/tilt.rb, line 180
180:       def self.cached_evaluate(scope, locals, &block)
181:         method = compiled_method(locals.keys)
182:         method.bind(scope).call(locals, &block)
183:       end

Public Instance methods

The basename of the template file.

[Source]

     # File lib/tilt.rb, line 122
122:     def basename(suffix='')
123:       File.basename(file, suffix) if file
124:     end

The filename used in backtraces to describe the template.

[Source]

     # File lib/tilt.rb, line 132
132:     def eval_file
133:       file || '(__TEMPLATE__)'
134:     end

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

[Source]

     # File lib/tilt.rb, line 127
127:     def name
128:       basename.split('.', 2).first if basename
129:     end

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.

[Source]

     # File lib/tilt.rb, line 117
117:     def render(scope=Object.new, locals={}, &block)
118:       evaluate scope, locals || {}, &block
119:     end

Protected Instance methods

Process the template and return the result. The first time this method is called, the template source is evaluated with instance_eval. On the sequential method calls it will compile the template to an unbound method which will lead to better performance. In any case, template executation is guaranteed to be performed in the scope object with the locals specified and with support for yielding to the block.

[Source]

     # File lib/tilt.rb, line 178
178:     def cached_evaluate(scope, locals, &block)
179:       # Redefine itself to use method compilation the next time:
180:       def self.cached_evaluate(scope, locals, &block)
181:         method = compiled_method(locals.keys)
182:         method.bind(scope).call(locals, &block)
183:       end
184: 
185:       # Use instance_eval the first time:
186:       evaluate_source(scope, locals, &block)
187:     end

The compiled method for the locals keys provided.

[Source]

     # File lib/tilt.rb, line 242
242:     def compiled_method(locals_keys)
243:       @compiled_method[locals_keys] ||=
244:         compile_template_method(locals_keys)
245:     end

[Source]

     # File lib/tilt.rb, line 168
168:     def evaluate(scope, locals, &block)
169:       cached_evaluate(scope, locals, &block)
170:     end

Called once and only once for each template subclass the first time the template class is initialized. This should be used to require the underlying template library and perform any initial setup.

[Source]

     # File lib/tilt.rb, line 140
140:     def initialize_engine
141:     end

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.

[Source]

     # File lib/tilt.rb, line 198
198:     def precompiled(locals)
199:       preamble = precompiled_preamble(locals)
200:       template = precompiled_template(locals)
201:       magic_comment = extract_magic_comment(template)
202:       if magic_comment
203:         # Magic comment e.g. "# coding: utf-8" has to be in the first line.
204:         # So we copy the magic comment to the first line.
205:         preamble = magic_comment + "\n" + preamble
206:       end
207:       parts = [
208:         preamble,
209:         template,
210:         precompiled_postamble(locals)
211:       ]
212:       [parts.join("\n"), preamble.count("\n") + 1]
213:     end

Generates postamble code for the precompiled template source. The string returned from this method is appended to the precompiled template source.

[Source]

     # File lib/tilt.rb, line 237
237:     def precompiled_postamble(locals)
238:       ''
239:     end

Generates preamble code for initializing template state, and performing locals assignment. The default implementation performs locals assignment only. Lines included in the preamble are subtracted from the source line offset, so adding code to the preamble does not effect line reporting in Kernel::caller and backtraces.

[Source]

     # File lib/tilt.rb, line 230
230:     def precompiled_preamble(locals)
231:       locals.map { |k,v| "#{k} = locals[:#{k}]" }.join("\n")
232:     end

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, and support for template compilation when the scope object allows it.

[Source]

     # File lib/tilt.rb, line 221
221:     def precompiled_template(locals)
222:       raise NotImplementedError
223:     end

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.

Subclasses must provide an implementation of this method.

[Source]

     # File lib/tilt.rb, line 158
158:     def prepare
159:       if respond_to?(:compile!)
160:         # backward compat with tilt < 0.6; just in case
161:         warn 'Tilt::Template#compile! is deprecated; implement #prepare instead.'
162:         compile!
163:       else
164:         raise NotImplementedError
165:       end
166:     end

Like Kernel::require but issues a warning urging a manual require when running under a threaded environment.

[Source]

     # File lib/tilt.rb, line 145
145:     def require_template_library(name)
146:       if Thread.list.size > 1
147:         warn "WARN: tilt autoloading '#{name}' in a non thread-safe way; " +
148:              "explicit require '#{name}' suggested."
149:       end
150:       require name
151:     end

[Validate]