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)
-
- compiler
Returns the value of attribute compiler.
-
- (String) indentation
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.
-
- parser
Returns the value of attribute parser.
Instance Method Summary (collapse)
-
- 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. -
- (Engine) initialize(template, options = {})
constructor
Precompiles the Haml template.
- - options_for_buffer
-
- (String) render(scope = Object.new, locals = {}, &block)
(also: #to_html)
Processes the template and returns the result as a string.
-
- (Proc) render_proc(scope = Object.new, *local_names)
Returns a proc that, when called, renders the template and returns the result as a string.
Methods included from Util
#av_template_class, #balance, #caller_info, #check_encoding, #check_haml_encoding, #contains_interpolation?, #def_static_method, #handle_interpolation, #html_safe, #human_indentation, #inspect_obj, #powerset, #rails_xss_safe?, #silence_warnings, #static_method_name, #unescape_interpolation
Constructor Details
- (Engine) initialize(template, options = {})
Precompiles the Haml template.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/haml/engine.rb', line 54
def initialize(template, options = {})
@options = Options.new(options)
@template = check_haml_encoding(template) do |msg, line|
raise Haml::Error.new(msg, line)
end
initialize_encoding options[:encoding]
@parser = @options.parser_class.new(@template, @options)
@compiler = @options.compiler_class.new(@options)
@compiler.compile(@parser.parse)
end
|
Instance Attribute Details
- compiler
Returns the value of attribute compiler
38 39 40 |
# File 'lib/haml/engine.rb', line 38
def compiler
@compiler
end
|
- (String) indentation
The indentation used in the Haml document, or nil
if the indentation is ambiguous (for example, for a single-level document).
36 37 38 |
# File 'lib/haml/engine.rb', line 36
def indentation
@indentation
end
|
- options
The Haml::Options instance. See the Haml options documentation.
29 30 31 |
# File 'lib/haml/engine.rb', line 29
def options
@options
end
|
- parser
Returns the value of attribute parser
39 40 41 |
# File 'lib/haml/engine.rb', line 39
def parser
@parser
end
|
Instance Method Details
- 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 by 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_
).
219 220 221 222 223 224 |
# File 'lib/haml/engine.rb', line 219
def def_method(object, name, *local_names)
method = object.is_a?(Module) ? :module_eval : :instance_eval
object.send(method, "def #{name}(_haml_locals = {}); #{compiler.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
|
- (String) render(scope = Object.new, locals = {}, &block) 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
or Proc
object, 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
or Proc
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.
110 111 112 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 138 |
# File 'lib/haml/engine.rb', line 110
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.is_a?(Proc)
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.instance_eval do
extend Haml::Helpers
@haml_buffer = buffer
end
begin
eval(@compiler.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_eval do
@haml_buffer = buffer.upper if buffer
end
end
|
- (Proc) render_proc(scope = Object.new, *local_names)
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.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/haml/engine.rb', line 165
def render_proc(scope = Object.new, *local_names)
if scope.is_a?(Binding) || scope.is_a?(Proc)
scope_object = eval("self", scope)
else
scope_object = scope
scope = scope_object.instance_eval{binding}
end
begin
eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" +
compiler.precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename], @options[:line])
rescue ::SyntaxError => e
raise SyntaxError, e.message
end
end
|