Class: Tilt::Template

Inherits:
Object
  • Object
show all
Defined in:
lib/tilt/template.rb

Overview

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file = nil, line = nil, options = nil) ⇒ Template

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.

Raises:

  • (ArgumentError)

82
83
84
85
86
87
88
89
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/tilt/template.rb', line 82

def initialize(file=nil, line=nil, options=nil)
  @file, @line, @options = nil, 1, nil

  process_arg(options)
  process_arg(line)
  process_arg(file)

  raise ArgumentError, "file or block required" unless @file || block_given?

  @options ||= {}

  # Force a specific scope class, instead of using the class of the provided
  # scope as the scope class.
  @scope_class = @options.delete :scope_class

  # Force the encoding of the input data
  @default_encoding = @options.delete :default_encoding

  # Skip encoding detection from magic comments and forcing that encoding
  # for compiled templates
  @skip_compiled_encoding_detection = @options.delete :skip_compiled_encoding_detection

  # Compiled path to use.  This must be specified as an option if
  # providing the :scope_class option and using fixed locals,
  # since template compilation occurs during initialization in that case.
  if compiled_path = @options.delete(:compiled_path)
    self.compiled_path = compiled_path
  end

  # load template data and prepare (uses binread to avoid encoding issues)
  @data = block_given? ? yield(self) : read_template_file

  if @data.respond_to?(:force_encoding)
    if default_encoding
      @data = _dup_string_if_frozen(@data)
      @data.force_encoding(default_encoding)
    end

    if !@data.valid_encoding?
      raise Encoding::InvalidByteSequenceError, "#{eval_file} is not valid #{@data.encoding}"
    end
  end

  set_fixed_locals
  prepare
  set_compiled_method_cache
end

Instance Attribute Details

#compiled_pathObject

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.


35
36
37
# File 'lib/tilt/template.rb', line 35

def compiled_path
  @compiled_path
end

#dataObject (readonly)

Template source; loaded from a file or given directly.


18
19
20
# File 'lib/tilt/template.rb', line 18

def data
  @data
end

#fileObject (readonly)

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


21
22
23
# File 'lib/tilt/template.rb', line 21

def file
  @file
end

#lineObject (readonly)

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


24
25
26
# File 'lib/tilt/template.rb', line 24

def line
  @line
end

#optionsObject (readonly)

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


29
30
31
# File 'lib/tilt/template.rb', line 29

def options
  @options
end

Class Method Details

.default_mime_typeObject

Use ‘.metadata` instead.


45
46
47
# File 'lib/tilt/template.rb', line 45

def default_mime_type
  [:mime_type]
end

.default_mime_type=(value) ⇒ Object

Use ‘.metadata = val` instead.


50
51
52
# File 'lib/tilt/template.rb', line 50

def default_mime_type=(value)
  [:mime_type] = value
end

.metadataObject

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


40
41
42
# File 'lib/tilt/template.rb', line 40

def 
  @metadata ||= {}
end

Instance Method Details

#basename(suffix = '') ⇒ Object

The basename of the template file.


138
139
140
# File 'lib/tilt/template.rb', line 138

def basename(suffix='')
  File.basename(@file, suffix) if @file
end

#compiled_method(locals_keys, scope_class = nil) ⇒ Object

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.


191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/tilt/template.rb', line 191

def compiled_method(locals_keys, scope_class=nil)
  if @fixed_locals
    if @scope_class
      return @compiled_method
    else
      key = scope_class
    end
  elsif @scope_class
    key = locals_keys.dup.freeze
  else
    key = [scope_class, locals_keys].freeze
  end

  LOCK.synchronize do
    if meth = @compiled_method[key]
      return meth
    end
  end
  meth = compile_template_method(locals_keys, scope_class)
  LOCK.synchronize do
    @compiled_method[key] = meth
  end
  meth
end

#eval_fileObject

The filename used in backtraces to describe the template.


150
151
152
# File 'lib/tilt/template.rb', line 150

def eval_file
  @file || '(__TEMPLATE__)'
end

#fixed_locals?Boolean

Whether the template uses fixed locals.

Returns:

  • (Boolean)

155
156
157
# File 'lib/tilt/template.rb', line 155

def fixed_locals?
  @fixed_locals ? true : false
end

#metadataObject

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


161
162
163
164
165
166
167
# File 'lib/tilt/template.rb', line 161

def 
  if respond_to?(:allows_script?)
    self.class..merge(:allows_script => allows_script?)
  else
    self.class.
  end
end

#nameObject

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


143
144
145
146
147
# File 'lib/tilt/template.rb', line 143

def name
  if bname = basename
    bname.split('.', 2).first
  end
end

#render(scope = nil, locals = nil, &block) ⇒ Object

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.


133
134
135
# File 'lib/tilt/template.rb', line 133

def render(scope=nil, locals=nil, &block)
  evaluate(scope || Object.new, locals || EMPTY_HASH, &block)
end