Implementing locals for ERB templates

1 view
Skip to first unread message

francois.beausoleil

unread,
Jul 1, 2008, 2:46:10 AM7/1/08
to sinatrarb
Hi all!

HAML templates support locals out of the box. Unfortunately, ERB
templates do not. I have most of the solution working. The only
thing that doesn't work right now is layout rendering. Can anybody
spot my mistake ?

http://pastie.org/225387

class RenderContext
def initialize(parent_context)
@erb_parent_context = parent_context
end

def method_missing(*args, &block)
@erb_parent_context.send(*args, &block)
end
end

def render_erb(content, options = {})
context = RenderContext.new(self)
metaclass = class << context; self; end

instance_variables.each do |key|
next if %w(@request @response @route_params).include?(key)
context.instance_variable_set(key,
instance_variable_get(key))
end
(options[:locals] || Hash.new).each do |key, value|
metaclass.send(:attr_reader, key)
context.instance_variable_set("@#{key}", value)
end

::ERB.new(content).result(context.send(:binding))
end


Thanks !
François

Chris Schneider

unread,
Jul 1, 2008, 12:11:22 PM7/1/08
to sina...@googlegroups.com
I actually implemented exactly this a while back.  If you are using the gem, you wouldn't see it, since it came after that release.

You can see my patch here:

http://github.com/bmizerany/sinatra/commit/dc6e32a5cea29e9055463f6eff84f2b829a19c1c

We take totally different approaches to the problem.  Basically, I let ERB compile to ruby code, then I tweak the ruby code, then eval the whole bundle.  You seem to mess with the environment a bit more, and avoid that source hacking stuff I did.  I don't like some of the hard coded "@request, @response @route_params" stuff you have to specifically exclude, seems brittle (and easy to miss later).  Also, my approach doesn't require any method_missing magic, or the RenderContext class at all.

Either way, if you aren't using edge, go do so.  It's much better and further along than the gem is, and it has this already implemented.

- Chris Schneider

francois.beausoleil

unread,
Jul 2, 2008, 11:14:34 AM7/2/08
to sinatrarb
Hello Chris,

On 1 juil, 12:11, "Chris Schneider" <jerk...@gmail.com> wrote:
> http://github.com/bmizerany/sinatra/commit/dc6e32a5cea29e9055463f6eff...

Your code looks cleaner to me. For your suggestion to use edge, I
will do so.

Thanks!
François

Reply all
Reply to author
Forward
0 new messages