Class: Haml::Engine
- Inherits:
-
Object
- Object
- Haml::Engine
- Includes:
- Precompiler
- 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
Constant Summary
Constants included from Util
Instance Attribute Summary
-
- (String) indentation
The indentation used in the Haml document, or
nilif the indentation is ambiguous (for example, for a single-level document). - - ({Symbol => Object}) options The options hash.
Instance Method Summary
-
- def_method(object, name, *local_names)
Defines a method on
objectwith the given name that renders the template and returns the result as a string. - - (Boolean) html4? Whether or not the format is HTML4.
- - (Boolean) html5? Whether or not the format is HTML5.
- - (Boolean) html? Whether or not the format is any flavor of HTML.
- - (Engine) initialize(template, options = {}) constructor Precompiles the Haml template.
- - ({Symbol => Object}) options_for_buffer protected Returns a subset of #options: those that Haml::Buffer cares about.
- - (String) precompiled The source code that is evaluated to produce the Haml document.
- - (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.
- - (Boolean) xhtml? Whether or not the format is XHTML.
Methods included from Util
#assert_html_safe!, #av_template_class, #def_static_method, #enum_with_index, #has?, #html_safe, #map_hash, #map_keys, #map_vals, #merge_adjacent_strings, #powerset, #rails_env, #rails_root, #rails_safe_buffer_class, #rails_xss_safe?, #ruby1_8?, #scope, #silence_warnings, #static_method_name, #to_hash
Constructor Details
- (Engine) initialize(template, options = {})
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 |
# 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,
}
unless ruby1_8?
@options[:encoding] = Encoding.default_internal || "utf-8"
end
@options.merge! options.reject {|k, v| v.nil?}
@index = 0
unless [:xhtml, :html4, :html5].include?(@options[:format])
raise Haml::Error, "Invalid 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
e.backtrace.unshift "#{@options[:filename]}:#{(e.line ? e.line + 1 : @index) + @options[:line] - 1}" if @index
raise
end
|
Instance Attribute Details
- (String) indentation
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
|
- ({Symbol => Object}) options
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 Haml::Helpers, and various instance variables are set (all prefixed with haml_).
263 264 265 266 267 268 |
# File 'lib/haml/engine.rb', line 263
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
|
- (Boolean) html4?
Whether or not the format is HTML4.
44 45 46 |
# File 'lib/haml/engine.rb', line 44
def html4?
@options[:format] == :html4
end
|
- (Boolean) html5?
Whether or not the format is HTML5.
49 50 51 |
# File 'lib/haml/engine.rb', line 49
def html5?
@options[:format] == :html5
end
|
- (Boolean) html?
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
|
- ({Symbol => Object}) options_for_buffer (protected)
Returns a subset of #options: those that Haml::Buffer cares about. All of the values here are such that when #inspect is called on the hash, it can be Kernel#evaled to get the same result back.
279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/haml/engine.rb', line 279
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
|
- (String) precompiled
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
|
- (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 Haml::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.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/haml/engine.rb', line 161
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
|
- (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.
213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/haml/engine.rb', line 213
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
|
- (Boolean) xhtml?
Whether or not the format is XHTML.
34 35 36 |
# File 'lib/haml/engine.rb', line 34
def xhtml?
not html?
end
|