Class: Haml::Engine

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 html4? html5? html? new render render_proc to_html xhtml?

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

new(template, options = {})

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

[Source]

         # File lib/haml/engine.rb, line 55
     55:     def initialize(template, options = {})
     56:       @options = {
     57:         :suppress_eval => false,
     58:         :attr_wrapper => "'",
     59:
     60:         # Don't forget to update the docs in lib/haml.rb if you update these
     61:         :autoclose => %w[meta img link br hr input area param col base],
     62:         :preserve => %w[textarea pre],
     63:
     64:         :filename => '(haml)',
     65:         :line => 1,
     66:         :ugly => false,
     67:         :format => :xhtml,
     68:         :escape_html => false
     69:       }
     70:       @options.merge! options
     71:       @index = 0
     72:
     73:       unless [:xhtml, :html4, :html5].include?(@options[:format])
     74:         raise Haml::Error, "Invalid format #{@options[:format].inspect}"
     75:       end
     76:
     77:       @template = template.rstrip + "\n-#\n-#"
     78:       @to_close_stack = []
     79:       @output_tabs = 0
     80:       @template_tabs = 0
     81:       @flat_spaces = -1
     82:       @flat = false
     83:       @newlines = 0
     84:       @precompiled = ''
     85:       @merged_text = ''
     86:       @tab_change  = 0
     87:
     88:       if @template =~ /\A(\s*\n)*[ \t]+\S/
     89:         raise SyntaxError.new("Indenting at the beginning of the document is illegal.", ($1 || "").count("\n"))
     90:       end
     91:
     92:       if @options[:filters]
     93:         warn "DEPRECATION WARNING:\nThe Haml :filters option is deprecated and will be removed in version 2.2.\nFilters are now automatically registered.\n"
     94:       end
     95:
     96:       precompile
     97:     rescue Haml::Error => e
     98:       e.backtrace.unshift "#{@options[:filename]}:#{(e.line ? e.line + 1 : @index) + @options[:line] - 1}" if @index
     99:       raise
    100:     end

### Public Instance methods

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

[Source]

         # File lib/haml/engine.rb, line 239
    239:     def def_method(object, name, *local_names)
    240:       method = object.is_a?(Module) ? :module_eval : :instance_eval
    241:
    242:       object.send(method, "def #{name}(_haml_locals = {}); #{precompiled_with_ambles(local_names)}; end",
    243:                   @options[:filename], @options[:line])
    244:     end

html4?()

True if the format is HTML4

[Source]

        # File lib/haml/engine.rb, line 37
    37:     def html4?
    38:       @options[:format] == :html4
    39:     end

html5?()

True if the format is HTML5

[Source]

        # File lib/haml/engine.rb, line 42
    42:     def html5?
    43:       @options[:format] == :html5
    44:     end

html?()

True if the format is any flavor of HTML

[Source]

        # File lib/haml/engine.rb, line 32
    32:     def html?
    33:       html4? or html5?
    34:     end

render(scope = Object.new, locals = {}, &block)

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 142
    142:     def render(scope = Object.new, locals = {}, &block)
    143:       buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_buffer'), options_for_buffer)
    144:
    145:       if scope.is_a?(Binding) || scope.is_a?(Proc)
    146:         scope_object = eval("self", scope)
    147:         scope = scope_object.instance_eval{binding} if block_given?
    148:       else
    149:         scope_object = scope
    150:         scope = scope_object.instance_eval{binding}
    151:       end
    152:
    153:       set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
    154:
    155:       scope_object.instance_eval do
    156:         extend Haml::Helpers
    157:         @haml_buffer = buffer
    158:       end
    159:
    160:       eval(@precompiled, scope, @options[:filename], @options[:line])
    161:
    162:       # Get rid of the current buffer
    163:       scope_object.instance_eval do
    164:         @haml_buffer = buffer.upper
    165:       end
    166:
    167:       buffer.buffer
    168:     end

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.

[Source]

         # File lib/haml/engine.rb, line 192
    192:     def render_proc(scope = Object.new, *local_names)
    193:       if scope.is_a?(Binding) || scope.is_a?(Proc)
    194:         scope_object = eval("self", scope)
    195:       else
    196:         scope_object = scope
    197:         scope = scope_object.instance_eval{binding}
    198:       end
    199:
    200:       eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" +
    201:            precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename], @options[:line])
    202:     end

to_html(scope = Object.new, locals = {}, &block)

Alias for render

xhtml?()

True if the format is XHTML

[Source]

        # File lib/haml/engine.rb, line 27
    27:     def xhtml?
    28:       not html?
    29:     end

[Validate]