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
|
end
|
||||||
|
|
||||||
# Processes the template and returns the result as a string.
|
# 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)
|
def render(scope = Object.new, &block)
|
||||||
@buffer = Haml::Buffer.new(@options)
|
@buffer = Haml::Buffer.new(@options)
|
||||||
compile scope, &block
|
compile scope, &block
|
||||||
|
@ -86,13 +106,18 @@ module Haml
|
||||||
# The code in <tt>@precompiled</tt> populates
|
# The code in <tt>@precompiled</tt> populates
|
||||||
# <tt>@buffer</tt> with the compiled XHTML code.
|
# <tt>@buffer</tt> with the compiled XHTML code.
|
||||||
def compile(scope, &block)
|
def compile(scope, &block)
|
||||||
if Binding === scope
|
if scope.is_a?(Binding) || scope.is_a?(Proc)
|
||||||
scope_object = eval("self", scope)
|
scope_object = eval("self", scope)
|
||||||
|
scope = scope_object.instance_eval{binding} if block_given?
|
||||||
else
|
else
|
||||||
scope_object = scope
|
scope_object = scope
|
||||||
scope = scope.instance_eval{binding}
|
scope = scope_object.instance_eval{binding}
|
||||||
end
|
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
|
scope_object.extend Haml::Helpers
|
||||||
buffer = @buffer
|
buffer = @buffer
|
||||||
scope_object.instance_eval do
|
scope_object.instance_eval do
|
||||||
|
@ -100,12 +125,8 @@ module Haml
|
||||||
@haml_stack.push(buffer)
|
@haml_stack.push(buffer)
|
||||||
end
|
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
|
begin
|
||||||
eval(@precompiled, scope, '(haml-eval)', &block)
|
eval(@precompiled, scope, '(haml-eval)')
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
raise add_exception_info(e, scope_object)
|
raise add_exception_info(e, scope_object)
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,8 +11,8 @@ require 'haml/engine'
|
||||||
|
|
||||||
class EngineTest < Test::Unit::TestCase
|
class EngineTest < Test::Unit::TestCase
|
||||||
|
|
||||||
def render(text, options = {})
|
def render(text, options = {}, &block)
|
||||||
Haml::Engine.new(text, options).to_html(options.delete(:scope) || Object.new)
|
Haml::Engine.new(text, options).to_html(options.delete(:scope) || Object.new, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_empty_render_should_remain_empty
|
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",
|
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))
|
render("%p= upcase\n%p= @var\n%p= var", :scope => b))
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue