mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
A little more tweaking of Engine#compile.
git-svn-id: svn://hamptoncatlin.com/haml/trunk@643 7063305b-7217-0410-af8c-cdc13e5119b9
This commit is contained in:
parent
a56175f37a
commit
3e91e60400
2 changed files with 34 additions and 9 deletions
|
@ -72,6 +72,26 @@ module Haml
|
|||
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 context,
|
||||
# extending it with Haml::Helpers
|
||||
# and performing various other modifications.
|
||||
#
|
||||
# If a block is passed to render,
|
||||
# that block is run when +yield+ is called
|
||||
# within the template.
|
||||
#
|
||||
# Note that 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 <tt>eval("self", scope)</tt> 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.
|
||||
def render(scope = Object.new, &block)
|
||||
@buffer = Haml::Buffer.new(@options)
|
||||
compile scope, &block
|
||||
|
@ -86,13 +106,18 @@ module Haml
|
|||
# The code in <tt>@precompiled</tt> populates
|
||||
# <tt>@buffer</tt> with the compiled XHTML code.
|
||||
def compile(scope, &block)
|
||||
if Binding === scope
|
||||
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.instance_eval{binding}
|
||||
scope = scope_object.instance_eval{binding}
|
||||
end
|
||||
|
||||
scope_object.send(:instance_variable_set, '@_haml_locals', @options[:locals])
|
||||
set_locals = @options[:locals].keys.map { |k| "#{k} = @_haml_locals[#{k.inspect}]" }.join("\n")
|
||||
eval(set_locals, scope)
|
||||
|
||||
scope_object.extend Haml::Helpers
|
||||
buffer = @buffer
|
||||
scope_object.instance_eval do
|
||||
|
@ -100,12 +125,8 @@ module Haml
|
|||
@haml_stack.push(buffer)
|
||||
end
|
||||
|
||||
scope_object.send(:instance_variable_set, '@_haml_locals', @options[:locals])
|
||||
set_locals = @options[:locals].keys.map { |k| "#{k} = @_haml_locals[#{k.inspect}]" }.join("\n")
|
||||
eval(set_locals, scope)
|
||||
|
||||
begin
|
||||
eval(@precompiled, scope, '(haml-eval)', &block)
|
||||
eval(@precompiled, scope, '(haml-eval)')
|
||||
rescue Exception => e
|
||||
raise add_exception_info(e, scope_object)
|
||||
end
|
||||
|
|
|
@ -11,8 +11,8 @@ require 'haml/engine'
|
|||
|
||||
class EngineTest < Test::Unit::TestCase
|
||||
|
||||
def render(text, options = {})
|
||||
Haml::Engine.new(text, options).to_html(options.delete(:scope) || Object.new)
|
||||
def render(text, options = {}, &block)
|
||||
Haml::Engine.new(text, options).to_html(options.delete(:scope) || Object.new, &block)
|
||||
end
|
||||
|
||||
def test_empty_render_should_remain_empty
|
||||
|
@ -310,4 +310,8 @@ class EngineTest < Test::Unit::TestCase
|
|||
assert_equal("<p>THIS IS A STRING!</p>\n<p>Instance variable</p>\n<p>Local variable</p>\n",
|
||||
render("%p= upcase\n%p= @var\n%p= var", :scope => b))
|
||||
end
|
||||
|
||||
def test_yield_should_work_with_binding
|
||||
assert_equal("12\nFOO\n", render("= yield\n= upcase", :scope => "foo".instance_eval{binding}) { 12 })
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue