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
Constant Summary
Constants included from Precompiler
Precompiler::COMMENT, Precompiler::DIV_CLASS, Precompiler::DIV_ID, Precompiler::DOCTYPE, Precompiler::DOCTYPE_REGEX, Precompiler::ELEMENT, Precompiler::ESCAPE, Precompiler::FILTER, Precompiler::FLAT_SCRIPT, Precompiler::LITERAL_VALUE_REGEX, Precompiler::MID_BLOCK_KEYWORD_REGEX, Precompiler::MULTILINE_CHAR_VALUE, Precompiler::PLAIN_TEXT, Precompiler::SANITIZE, Precompiler::SCRIPT, Precompiler::SILENT_COMMENT, Precompiler::SILENT_SCRIPT, Precompiler::SPECIAL_CHARACTERS
Constants included from Util
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 ⇒ Hash<Symbol, Object>
The options hash.
-
#precompiled ⇒ String
The source code that is evaluated to produce the Haml document.
Instance Method Summary collapse
-
#def_method(object, name, *local_names) ⇒ Object
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.
-
#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 Util
#def_static_method, #enum_with_index, #has?, #map_hash, #map_keys, #map_vals, #merge_adjacent_strings, #powerset, #ruby1_8?, #scope, #static_method_name, #to_hash
Constructor Details
#initialize(template, options = {}) ⇒ Engine
Precompiles the Haml template.
64 65 66 67 68 69 70 71 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 |
# File 'lib/haml/engine.rb', line 64 def initialize(template, = {}) @options = { :suppress_eval => false, :attr_wrapper => "'", # Don't forget to update the docs in lib/haml.rb if you update these :autoclose => %w[meta img link br hr input area param col base], :preserve => %w[textarea pre], :filename => '(haml)', :line => 1, :ugly => false, :format => :xhtml, :escape_html => false } @options.merge! @index = 0 unless [:xhtml, :html4, :html5].include?(@options[:format]) raise Haml::Error, "Invalid format #{@options[:format].inspect}" 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 @temp_count = 0 if @options[:filters] warn <<END DEPRECATION WARNING: The Haml :filters option is deprecated and will be removed in version 2.2. Filters are now automatically registered. END end 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
#indentation ⇒ String
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 ⇒ Hash<Symbol, Object>
The options hash. See [the Haml options documentation](../Haml.html#haml_options).
24 25 26 |
# File 'lib/haml/engine.rb', line 24 def @options end |
#precompiled ⇒ String
The source code that is evaluated to produce the Haml document.
29 30 31 |
# File 'lib/haml/engine.rb', line 29 def precompiled @precompiled end |
Instance Method Details
#def_method(object, name, *local_names) ⇒ Object
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_`).
257 258 259 260 261 262 |
# File 'lib/haml/engine.rb', line 257 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.
49 50 51 |
# File 'lib/haml/engine.rb', line 49 def html4? @options[:format] == :html4 end |
#html5? ⇒ Boolean
Returns Whether or not the format is HTML5.
54 55 56 |
# File 'lib/haml/engine.rb', line 54 def html5? @options[:format] == :html5 end |
#html? ⇒ Boolean
Returns Whether or not the format is any flavor of HTML.
44 45 46 |
# File 'lib/haml/engine.rb', line 44 def html? html4? or html5? 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.responds_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.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/haml/engine.rb', line 154 def render(scope = Object.new, locals = {}, &block) buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_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, scope, @options[:filename], @options[:line]) # Get rid of the current buffer scope_object.instance_eval do @haml_buffer = buffer.upper end buffer.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.
207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/haml/engine.rb', line 207 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.
39 40 41 |
# File 'lib/haml/engine.rb', line 39 def xhtml? not html? end |