Class Haml::Engine
In: lib/haml/engine.rb
Parent: Object

This is the class where all the parsing and processing of the Haml template is done. It can be directly used by the user by creating a new instance and calling to_html to render the template. For example:

  template = File.read('templates/really_cool_template.haml')
  haml_engine = Haml::Engine.new(template)
  output = haml_engine.to_html
  puts output

Methods

def_method   new   render   render_proc   to_html  

Included Modules

Precompiler

Attributes

options  [RW]  Allow reading and writing of the options hash
precompiled  [RW]  This string contains the source code that is evaluated to produce the Haml document.

Public Class methods

Creates a new instace of Haml::Engine that will compile the given template string when render is called. See README for available options.

[Source]

    # File lib/haml/engine.rb, line 36
36:     def initialize(template, options = {})
37:       @options = {
38:         :suppress_eval => false,
39:         :attr_wrapper => "'",
40:         :autoclose => ['meta', 'img', 'link', 'br', 'hr', 'input', 'area'],
41:         :filters => {
42:           'sass' => Sass::Engine,
43:           'plain' => Haml::Filters::Plain,
44:           'preserve' => Haml::Filters::Preserve,
45:           'redcloth' => Haml::Filters::RedCloth,
46:           'textile' => Haml::Filters::Textile,
47:           'markdown' => Haml::Filters::Markdown },
48:         :filename => '(haml)'
49:       }
50:       @options.rec_merge! options
51: 
52:       unless @options[:suppress_eval]
53:         @options[:filters].merge!({
54:           'erb' => ERB,
55:           'ruby' => Haml::Filters::Ruby
56:         })
57:       end
58:       @options[:filters].rec_merge! options[:filters] if options[:filters]
59: 
60:       if @options[:locals]
61:         warn "DEPRECATION WARNING:\nThe Haml :locals option is deprecated and will be removed in version 2.0.\nUse the locals option for Haml::Engine#render instead.\n"
62:       end
63: 
64:       @template = template.strip #String
65:       @to_close_stack = []
66:       @output_tabs = 0
67:       @template_tabs = 0
68:       @index = 0
69:       @flat_spaces = -1
70: 
71:       precompile
72:     rescue Haml::Error
73:       $!.backtrace.unshift "#{@options[:filename]}:#{@index}"
74:       raise
75:     end

Public Instance methods

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").

[Source]

     # File lib/haml/engine.rb, line 218
218:     def def_method(object, name, *local_names)
219:       method = object.is_a?(Module) ? :module_eval : :instance_eval
220: 
221:       object.send(method, "def #{name}(_haml_locals = {}); #{precompiled_with_ambles(local_names)}; end",
222:                   @options[:filename], 0)
223:     end

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.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.

[Source]

     # File lib/haml/engine.rb, line 117
117:     def render(scope = Object.new, locals = {}, &block)
118:       locals = (@options[:locals] || {}).merge(locals)
119:       buffer = Haml::Buffer.new(options_for_buffer)
120: 
121:       if scope.is_a?(Binding) || scope.is_a?(Proc)
122:         scope_object = eval("self", scope)
123:         scope = scope_object.instance_eval{binding} if block_given?
124:       else
125:         scope_object = scope
126:         scope = scope_object.instance_eval{binding}
127:       end
128: 
129:       set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
130: 
131:       scope_object.instance_eval do
132:         extend Haml::Helpers
133:         @haml_stack ||= Array.new
134:         @haml_stack.push(buffer)
135:         @haml_is_haml = true
136:       end
137: 
138:       eval(@precompiled, scope, @options[:filename], 0)
139: 
140:       # Get rid of the current buffer
141:       scope_object.instance_eval do
142:         @haml_stack.pop
143:         @haml_is_haml = false
144:       end
145: 
146:       buffer.buffer
147:     end

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.

[Source]

     # File lib/haml/engine.rb, line 171
171:     def render_proc(scope = Object.new, *local_names)
172:       if scope.is_a?(Binding) || scope.is_a?(Proc)
173:         scope_object = eval("self", scope)
174:       else
175:         scope_object = scope
176:         scope = scope_object.instance_eval{binding}
177:       end
178: 
179:       eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" +
180:            precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename], 0)
181:     end
to_html(scope = Object.new, locals = {}, &block)

Alias for render

[Validate]