Class: Haml::Engine
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 ⇒ {Symbol => Object}
The options hash.
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. -
#html4? ⇒ Boolean
Whether or not the format is HTML4.
-
#html5? ⇒ Boolean
Whether or not the format is HTML5.
-
#html? ⇒ Boolean
Whether or not the format is any flavor of HTML.
-
#initialize(template, options = {}) ⇒ Engine
constructor
Precompiles the Haml template.
- #options_for_buffer ⇒ {Symbol => Object} protected
-
#precompiled ⇒ String
The source code that is evaluated to produce the Haml document.
-
#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.
-
#xhtml? ⇒ Boolean
Whether or not the format is XHTML.
Methods included from Precompiler
#push_silent_with_haml_block_deprecation
Constructor Details
#initialize(template, options = {}) ⇒ Engine
Precompiles the Haml template.
72 73 74 75 76 77 78 79 80 81 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 |
# File 'lib/haml/engine.rb', line 72
def initialize(template, options = {})
@options = {
:suppress_eval => false,
:attr_wrapper => "'",
# Don't forget to update the docs in doc-src/HAML_REFERENCE.md
# if you update these
:autoclose => %w[meta img link br hr input area param col base],
:preserve => %w[textarea pre code],
:filename => '(haml)',
:line => 1,
:ugly => false,
:format => :xhtml,
:escape_html => false,
}
template = check_haml_encoding(template) do |msg, line|
raise Haml::Error.new(msg, line)
end
unless ruby1_8?
@options[:encoding] = Encoding.default_internal || template.encoding
@options[:encoding] = "utf-8" if @options[:encoding].name == "US-ASCII"
end
@options.merge! options.reject {|k, v| v.nil?}
@index = 0
unless [:xhtml, :html4, :html5].include?(@options[:format])
raise Haml::Error, "Invalid output format #{@options[:format].inspect}"
end
if @options[:encoding] && @options[:encoding].is_a?(Encoding)
@options[:encoding] = @options[:encoding].name
end
# :eod is a special end-of-document marker
@template = (template.rstrip).split(/\r\n|\r|\n/) + [:eod, :eod]
@template_index = 0
@to_close_stack = []
@output_tabs = 0
@template_tabs = 0
@flat = false
@newlines = 0
@precompiled = ''
@to_merge = []
@tab_change = 0
precompile
rescue Haml::Error => e
if @index || e.line
e.backtrace.unshift "#{@options[:filename]}:#{(e.line ? e.line + 1 : @index) + @options[:line] - 1}"
end
raise
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).
31 32 33 |
# File 'lib/haml/engine.rb', line 31
def indentation
@indentation
end
|
#options ⇒ {Symbol => Object}
The options hash. See the Haml options documentation.
24 25 26 |
# File 'lib/haml/engine.rb', line 24
def options
@options
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_
).
272 273 274 275 276 277 |
# File 'lib/haml/engine.rb', line 272
def def_method(object, name, *local_names)
method = object.is_a?(Module) ? :module_eval : :instance_eval
object.send(method, "def #{name}(_haml_locals = {}); #{precompiled_with_ambles(local_names)}; end",
@options[:filename], @options[:line])
end
|
#html4? ⇒ Boolean
Returns Whether or not the format is HTML4.
44 45 46 |
# File 'lib/haml/engine.rb', line 44
def html4?
@options[:format] == :html4
end
|
#html5? ⇒ Boolean
Returns Whether or not the format is HTML5.
49 50 51 |
# File 'lib/haml/engine.rb', line 49
def html5?
@options[:format] == :html5
end
|
#html? ⇒ Boolean
Returns Whether or not the format is any flavor of HTML.
39 40 41 |
# File 'lib/haml/engine.rb', line 39
def html?
html4? or html5?
end
|
#options_for_buffer ⇒ {Symbol => Object} (protected)
288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/haml/engine.rb', line 288
def options_for_buffer
{
:autoclose => @options[:autoclose],
:preserve => @options[:preserve],
:attr_wrapper => @options[:attr_wrapper],
:ugly => @options[:ugly],
:format => @options[:format],
:encoding => @options[:encoding],
:escape_html => @options[:escape_html],
}
end
|
#precompiled ⇒ String
The source code that is evaluated to produce the Haml document.
In Ruby 1.9, this is automatically converted to the correct encoding
(see the :encoding
option).
59 60 61 62 63 64 |
# File 'lib/haml/engine.rb', line 59
def precompiled
return @precompiled if ruby1_8?
encoding = Encoding.find(@options[:encoding])
return @precompiled.force_encoding(encoding) if encoding == Encoding::BINARY
return @precompiled.encode(encoding)
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
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.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/haml/engine.rb', line 170
def render(scope = Object.new, locals = {}, &block)
buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_buffer'), 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
eval(precompiled + ";" + precompiled_method_return_value,
scope, @options[:filename], @options[:line])
ensure
# Get rid of the current buffer
scope_object.instance_eval do
@haml_buffer = buffer.upper
end
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.
222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/haml/engine.rb', line 222
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
eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" +
precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename], @options[:line])
end
|
#xhtml? ⇒ Boolean
Returns Whether or not the format is XHTML.
34 35 36 |
# File 'lib/haml/engine.rb', line 34
def xhtml?
not html?
end
|