| Class | Haml::Engine |
| In: |
lib/haml/engine.rb
|
| Parent: | Object |
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
Precompiles the Haml template.
@param template [String] The Haml template @param options [Hash<Symbol, Object>] An options hash;
see {file:HAML_REFERENCE.md#haml_options the Haml options documentation}
@raise [Haml::Error] if there‘s a Haml syntax error in the template
# File lib/haml/engine.rb, line 70
70: def initialize(template, options = {})
71: @options = {
72: :suppress_eval => false,
73: :attr_wrapper => "'",
74:
75: # Don't forget to update the docs in lib/haml.rb if you update these
76: :autoclose => %w[meta img link br hr input area param col base],
77: :preserve => %w[textarea pre],
78:
79: :filename => '(haml)',
80: :line => 1,
81: :ugly => false,
82: :format => :xhtml,
83: :escape_html => false,
84: }
85: unless ruby1_8?
86: @options[:encoding] = Encoding.default_internal || "utf-8"
87: end
88: @options.merge! options
89: @index = 0
90:
91: unless [:xhtml, :html4, :html5].include?(@options[:format])
92: raise Haml::Error, "Invalid format #{@options[:format].inspect}"
93: end
94:
95: if @options[:encoding] && @options[:encoding].is_a?(Encoding)
96: @options[:encoding] = @options[:encoding].name
97: end
98:
99: # :eod is a special end-of-document marker
100: @template = (template.rstrip).split(/\r\n|\r|\n/) + [:eod, :eod]
101: @template_index = 0
102: @to_close_stack = []
103: @output_tabs = 0
104: @template_tabs = 0
105: @flat = false
106: @newlines = 0
107: @precompiled = ''
108: @to_merge = []
109: @tab_change = 0
110: @temp_count = 0
111:
112: precompile
113: rescue Haml::Error => e
114: e.backtrace.unshift "#{@options[:filename]}:#{(e.line ? e.line + 1 : @index) + @options[:line] - 1}" if @index
115: raise
116: end
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_`).
@param object [Object, Module] The object on which to define the method @param name [String, Symbol] The name of the method to define @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
# File lib/haml/engine.rb, line 262
262: def def_method(object, name, *local_names)
263: method = object.is_a?(Module) ? :module_eval : :instance_eval
264:
265: object.send(method, "def #{name}(_haml_locals = {}); #{precompiled_with_ambles(local_names)}; end",
266: @options[:filename], @options[:line])
267: end
@return [Boolean] Whether or not the format is HTML4.
# File lib/haml/engine.rb, line 44
44: def html4?
45: @options[:format] == :html4
46: end
@return [Boolean] Whether or not the format is HTML5.
# File lib/haml/engine.rb, line 49
49: def html5?
50: @options[:format] == :html5
51: end
The source code that is evaluated to produce the Haml document.
In Ruby 1.9, this is automatically converted to the correct encoding (see {file:HAML_REFERENCE.md#encoding-option the `:encoding` option}).
@return [String]
# File lib/haml/engine.rb, line 59
59: def precompiled
60: return @precompiled if ruby1_8?
61: return @precompiled.encode(Encoding.find(@options[:encoding]))
62: 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.
@param scope [Binding, Proc, Object] The context in which the template is evaluated @param locals [Hash<Symbol, Object>] Local variables that will be made available
to the template
@param block [to_proc] A block that can be yielded to within the template @return [String] The rendered template
# File lib/haml/engine.rb, line 159
159: def render(scope = Object.new, locals = {}, &block)
160: buffer = Haml::Buffer.new(scope.instance_variable_get('@haml_buffer'), options_for_buffer)
161:
162: if scope.is_a?(Binding) || scope.is_a?(Proc)
163: scope_object = eval("self", scope)
164: scope = scope_object.instance_eval{binding} if block_given?
165: else
166: scope_object = scope
167: scope = scope_object.instance_eval{binding}
168: end
169:
170: set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
171:
172: scope_object.instance_eval do
173: extend Haml::Helpers
174: @haml_buffer = buffer
175: end
176:
177: eval(precompiled, scope, @options[:filename], @options[:line])
178:
179: # Get rid of the current buffer
180: scope_object.instance_eval do
181: @haml_buffer = buffer.upper
182: end
183:
184: buffer.buffer
185: 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.
@param scope [Binding, Proc, Object] The context in which the template is evaluated @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc @return [Proc] The proc that will run the template
# File lib/haml/engine.rb, line 212
212: def render_proc(scope = Object.new, *local_names)
213: if scope.is_a?(Binding) || scope.is_a?(Proc)
214: scope_object = eval("self", scope)
215: else
216: scope_object = scope
217: scope = scope_object.instance_eval{binding}
218: end
219:
220: eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" +
221: precompiled_with_ambles(local_names) + "}\n", scope, @options[:filename], @options[:line])
222: end
@return [Boolean] Whether or not the format is XHTML.
# File lib/haml/engine.rb, line 34
34: def xhtml?
35: not html?
36: end
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#eval`ed to get the same result back.
See {file:HAML_REFERENCE.md#haml_options the Haml options documentation}.
@return [Hash<Symbol, Object>] The options hash
# File lib/haml/engine.rb, line 278
278: def options_for_buffer
279: {
280: :autoclose => @options[:autoclose],
281: :preserve => @options[:preserve],
282: :attr_wrapper => @options[:attr_wrapper],
283: :ugly => @options[:ugly],
284: :format => @options[:format],
285: :encoding => @options[:encoding],
286: }
287: end