Class: Haml::Engine
- Inherits:
-
Object
- Object
- Haml::Engine
- Extended by:
- Forwardable
- Includes:
- Util
- Defined in:
- lib/haml/engine.rb
Overview
This is the frontend for using Haml programmatically. It can be directly used by the user by creating a new instance and calling #render to render the template. For example:
template = File.read('templates/really_cool_template.haml')
haml_engine = Haml::Engine.new(template)
output = haml_engine.render
puts output
Instance Attribute Summary collapse
-
#indentation ⇒ String
The indentation used in the Haml document, or
nil
if the indentation is ambiguous (for example, for a single-level document). -
#options
The Haml::Options instance.
Instance Method Summary collapse
-
#compiler
Deprecated API for backword compatibility.
-
#def_method(object, name, *local_names)
Defines a method on
object
with the given name that renders the template and returns the result as a string. -
#initialize(template, options = {}) ⇒ Engine
constructor
Precompiles the Haml template.
-
#options_for_buffer
-
#render(scope = Object.new, locals = {}, &block) ⇒ String
(also: #to_html)
Processes the template and returns the result as a string.
-
#render_proc(scope = Object.new, *local_names) ⇒ Proc
Returns a proc that, when called, renders the template and returns the result as a string.
Methods included from Util
#balance, #check_encoding, #check_haml_encoding, #contains_interpolation?, #handle_interpolation, #html_safe, #human_indentation, #inspect_obj, #rails_xss_safe?, #silence_warnings, #unescape_interpolation
Constructor Details
#initialize(template, options = {}) ⇒ Engine
Precompiles the Haml template.
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/haml/engine.rb', line 54
def initialize(template, options = {})
# Reflect changes of `Haml::Options.defaults` to `Haml::TempleEngine` options, but `#initialize_encoding`
# should be run against the arguemnt `options[:encoding]` for backward compatibility with old `Haml::Engine`.
options = Options.defaults.dup.tap { |o| o.delete(:encoding) }.merge!(options)
@options = Options.new(options)
@template = check_haml_encoding(template) do |msg, line|
raise Haml::Error.new(msg, line)
end
@temple_engine = TempleEngine.new(options)
@temple_engine.compile(@template)
end
|
Instance Attribute Details
#indentation ⇒ String
The indentation used in the Haml document,
or nil
if the indentation is ambiguous
(for example, for a single-level document).
39 40 41 |
# File 'lib/haml/engine.rb', line 39
def indentation
@indentation
end
|
#options
The Haml::Options instance. See the Haml options documentation.
32 33 34 |
# File 'lib/haml/engine.rb', line 32
def options
@options
end
|
Instance Method Details
#compiler
Deprecated API for backword compatibility
69 70 71 |
# File 'lib/haml/engine.rb', line 69
def compiler
@temple_engine
end
|
#def_method(object, name, *local_names)
Defines a method on object
with the given name
that renders the template and returns the result as a string.
If object
is a class or module,
the method will instead be defined as an instance method.
For example:
t = Time.now
Haml::Engine.new("%p\n Today's date is\n .date= self.to_s").def_method(t, :render)
t.render #=> "<p>\n Today's date is\n <div class='date'>Fri Nov 23 18:28:29 -0800 2007</div>\n</p>\n"
Haml::Engine.new(".upcased= upcase").def_method(String, :upcased_div)
"foobar".upcased_div #=> "<div class='upcased'>FOOBAR</div>\n"
The first argument of the defined method is a hash of local variable names to values.
However, due to an unfortunate Ruby quirk,
the local variables which can be assigned must be pre-declared.
This is done with the local_names
argument.
For example:
# This works
obj = Object.new
Haml::Engine.new("%p= foo").def_method(obj, :render, :foo)
obj.render(:foo => "Hello!") #=> "<p>Hello!</p>"
# This doesn't
obj = Object.new
Haml::Engine.new("%p= foo").def_method(obj, :render)
obj.render(:foo => "Hello!") #=> NameError: undefined local variable or method `foo'
Note that Haml modifies the evaluation context
(either the scope object or the self
object of the scope binding).
It extends Helpers, and various instance variables are set
(all prefixed with haml_
).
223 224 225 226 227 228 |
# File 'lib/haml/engine.rb', line 223
def def_method(object, name, *local_names)
method = object.is_a?(Module) ? :module_eval : :instance_eval
object.send(method, "def #{name}(_haml_locals = {}); #{@temple_engine.precompiled_with_ambles(local_names)}; end",
@options.filename, @options.line)
end
|
#options_for_buffer
44 45 46 |
# File 'lib/haml/engine.rb', line 44
def options_for_buffer
@options.for_buffer
end
|
#render(scope = Object.new, locals = {}, &block) ⇒ String Also known as: to_html
Processes the template and returns the result as a string.
scope
is the context in which the template is evaluated.
If it’s a Binding
, Haml uses it as the second argument to Kernel#eval
;
otherwise, Haml just uses its #instance_eval
context.
Note that Haml modifies the evaluation context
(either the scope object or the self
object of the scope binding).
It extends Helpers, and various instance variables are set
(all prefixed with haml_
).
For example:
s = "foobar"
Haml::Engine.new("%p= upcase").render(s) #=> "<p>FOOBAR</p>"
# s now extends Haml::Helpers
s.respond_to?(:html_attrs) #=> true
locals
is a hash of local variables to make available to the template.
For example:
Haml::Engine.new("%p= foo").render(Object.new, :foo => "Hello, world!") #=> "<p>Hello, world!</p>"
If a block is passed to render,
that block is run when yield
is called
within the template.
Due to some Ruby quirks,
if scope
is a Binding
object and a block is given,
the evaluation context may not be quite what the user expects.
In particular, it’s equivalent to passing eval("self", scope)
as scope
.
This won’t have an effect in most cases,
but if you’re relying on local variables defined in the context of scope
,
they won’t work.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/haml/engine.rb', line 113
def render(scope = Object.new, locals = {}, &block)
parent = scope.instance_variable_defined?(:@haml_buffer) ? scope.instance_variable_get(:@haml_buffer) : nil
buffer = Haml::Buffer.new(parent, @options.for_buffer)
if scope.is_a?(Binding)
scope_object = eval("self", scope)
scope = scope_object.instance_eval{binding} if block_given?
else
scope_object = scope
scope = scope_object.instance_eval{binding}
end
set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
scope_object.extend(Haml::Helpers)
scope_object.instance_variable_set(:@haml_buffer, buffer)
begin
eval(@temple_engine.precompiled_with_return_value, scope, @options.filename, @options.line)
rescue ::SyntaxError => e
raise SyntaxError, e.message
end
ensure
# Get rid of the current buffer
scope_object.instance_variable_set(:@haml_buffer, buffer.upper) if buffer
end
|
#render_proc(scope = Object.new, *local_names) ⇒ Proc
Returns a proc that, when called, renders the template and returns the result as a string.
scope
works the same as it does for render.
The first argument of the returned proc is a hash of local variable names to values.
However, due to an unfortunate Ruby quirk,
the local variables which can be assigned must be pre-declared.
This is done with the local_names
argument.
For example:
# This works
Haml::Engine.new("%p= foo").render_proc(Object.new, :foo).call :foo => "Hello!"
#=> "<p>Hello!</p>"
# This doesn't
Haml::Engine.new("%p= foo").render_proc.call :foo => "Hello!"
#=> NameError: undefined local variable or method `foo'
The proc doesn’t take a block; any yields in the template will fail.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/haml/engine.rb', line 164
def render_proc(scope = Object.new, *local_names)
if scope.is_a?(Binding)
scope_object = eval("self", scope)
else
scope_object = scope
scope = scope_object.instance_eval{binding}
end
begin
str = @temple_engine.precompiled_with_ambles(local_names)
eval(
"Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {}; #{str}}\n",
scope,
@options.filename,
@options.line
)
rescue ::SyntaxError => e
raise SyntaxError, e.message
end
end
|