Base class for template implementations. Subclasses must implement the prepare method and one of the evaluate or precompiled_template methods.
Template source; loaded from a file or given directly.
The name of the file where the template data was loaded from.
The line number in file where template data was loaded from.
A Hash of template engine specific options. This is passed directly to the underlying engine and is not used by the generic template interface.
The basename of the template file.
# File lib/tilt/template.rb, line 115 def basename(suffix='') File.basename(file, suffix) if file end
The filename used in backtraces to describe the template.
# File lib/tilt/template.rb, line 125 def eval_file file || '(__TEMPLATE__)' end
An empty Hash that the template engine can populate with various metadata.
# File lib/tilt/template.rb, line 131 def metadata if respond_to?(:allows_script?) self.class.metadata.merge(:allows_script => allows_script?) else self.class.metadata end end
The template file’s basename with all extensions chomped off.
# File lib/tilt/template.rb, line 120 def name basename.split('.', 2).first if basename 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, line 105 def render(scope=nil, locals={}, &block) scope ||= Object.new current_template = Thread.current[:tilt_current_template] Thread.current[:tilt_current_template] = self evaluate(scope, locals || {}, &block) ensure Thread.current[:tilt_current_template] = current_template end
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 lib/tilt/template.rb, line 147 def default_encoding @default_encoding end
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, line 166 def evaluate(scope, locals, &block) locals_keys = locals.keys locals_keys.sort!{|x, y| x.to_s <=> y.to_s} method = compiled_method(locals_keys) method.bind(scope).call(locals, &block) 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, line 182 def precompiled(local_keys) preamble = precompiled_preamble(local_keys) template = precompiled_template(local_keys) postamble = precompiled_postamble(local_keys) source = String.new # Ensure that our generated source code has the same encoding as the # the source code generated by the template engine. if source.respond_to?(:force_encoding) template_encoding = extract_encoding(template) source.force_encoding(template_encoding) template.force_encoding(template_encoding) end source << preamble << "\n" << template << "\n" << postamble [source, preamble.count("\n")+1] end
# File lib/tilt/template.rb, line 216 def precompiled_postamble(local_keys) '' end
# File lib/tilt/template.rb, line 212 def precompiled_preamble(local_keys) '' end
A string containing the (Ruby) source code for the template. The default #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, line 208 def precompiled_template(local_keys) raise NotImplementedError 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.
# File lib/tilt/template.rb, line 156 def prepare raise NotImplementedError end
@deprecated Use `.metadata` instead.
# File lib/tilt/template.rb, line 44 def default_mime_type metadata[:mime_type] end
@deprecated Use `.metadata = val` instead.
# File lib/tilt/template.rb, line 49 def default_mime_type=(value) metadata[:mime_type] = value end
An empty Hash that the template engine can populate with various metadata.
# File lib/tilt/template.rb, line 39 def metadata @metadata ||= {} 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.
# File lib/tilt/template.rb, line 60 def initialize(file=nil, line=1, options={}, &block) @file, @line, @options = nil, 1, {} [options, line, file].compact.each do |arg| case when arg.respond_to?(:to_str) ; @file = arg.to_str when arg.respond_to?(:to_int) ; @line = arg.to_int when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup when arg.respond_to?(:path) ; @file = arg.path when arg.respond_to?(:to_path) ; @file = arg.to_path else raise TypeError, "Can't load the template file. Pass a string with a path " + "or an object that responds to 'to_str', 'path' or 'to_path'" end end raise ArgumentError, "file or block required" if (@file || block).nil? # used to hold compiled template methods @compiled_method = {} # used on 1.9 to set the encoding if it is not set elsewhere (like a magic comment) # currently only used if template compiles to ruby @default_encoding = @options.delete :default_encoding # load template data and prepare (uses binread to avoid encoding issues) @reader = block || lambda { |t| read_template_file } @data = @reader.call(self) if @data.respond_to?(:force_encoding) if default_encoding @data = @data.dup if @data.frozen? @data.force_encoding(default_encoding) end if !@data.valid_encoding? raise Encoding::InvalidByteSequenceError, "#{eval_file} is not valid #{@data.encoding}" end end prepare end