Base class for template implementations. Subclasses must implement the prepare method and one of the evaluate or precompiled_template methods.
Methods
Public Class
Public Instance
- basename
- compiled_method
- compiled_path
- compiled_path=
- data
- eval_file
- file
- fixed_locals?
- line
- metadata
- name
- options
- render
Protected Instance
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] |
|
| 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 |
| 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
Use .metadata[:mime_type] instead.
# File lib/tilt/template.rb 45 def default_mime_type 46 metadata[:mime_type] 47 end
Use .metadata[:mime_type] = val instead.
# File lib/tilt/template.rb 50 def default_mime_type=(value) 51 metadata[:mime_type] = value 52 end
An empty Hash that the template engine can populate with various metadata.
# File lib/tilt/template.rb 40 def metadata 41 @metadata ||= {} 42 end
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. |
# 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
The basename of the template file.
# File lib/tilt/template.rb 138 def basename(suffix='') 139 File.basename(@file, suffix) if @file 140 end
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.
# 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
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.
# 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
The filename used in backtraces to describe the template.
# File lib/tilt/template.rb 150 def eval_file 151 @file || '(__TEMPLATE__)' 152 end
Whether the template uses fixed locals.
# File lib/tilt/template.rb 155 def fixed_locals? 156 @fixed_locals ? true : false 157 end
An empty Hash that the template engine can populate with various metadata.
# 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
The template file’s basename with all extensions chomped off.
# File lib/tilt/template.rb 143 def name 144 if bname = basename 145 bname.split('.', 2).first 146 end 147 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.
# 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
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.
# 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
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.
# 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
# File lib/tilt/template.rb 316 def precompiled_postamble(local_keys) 317 '' 318 end
# File lib/tilt/template.rb 312 def precompiled_preamble(local_keys) 313 '' 314 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, proper encoding, and support for template compilation.
# File lib/tilt/template.rb 308 def precompiled_template(local_keys) 309 raise NotImplementedError 310 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.
Empty by default as some subclasses do not need separate preparation.
# File lib/tilt/template.rb 235 def prepare 236 end
# File lib/tilt/template.rb 226 def skip_compiled_encoding_detection? 227 @skip_compiled_encoding_detection 228 end