-
-
Save lenary/119874 to your computer and use it in GitHub Desktop.
# stolen from http://github.com/cschneid/irclogger/blob/master/lib/partials.rb | |
# and made a lot more robust by me | |
# this implementation uses erb by default. if you want to use any other template mechanism | |
# then replace `erb` on line 13 and line 17 with `haml` or whatever | |
module Sinatra::Partials | |
def partial(template, *args) | |
template_array = template.to_s.split('/') | |
template = template_array[0..-2].join('/') + "/_#{template_array[-1]}" | |
options = args.last.is_a?(Hash) ? args.pop : {} | |
options.merge!(:layout => false) | |
locals = options[:locals] || {} | |
if collection = options.delete(:collection) then | |
collection.inject([]) do |buffer, member| | |
buffer << erb(:"#{template}", options.merge(:layout => | |
false, :locals => {template_array[-1].to_sym => member}.merge(locals))) | |
end.join("\n") | |
else | |
erb(:"#{template}", options) | |
end | |
end | |
end |
Really? You're sure you didn't do != haml "footer"
by accident?
ahh - sorry it's included, but how can I pass arguments like for lang and use it in the footer.haml
!= haml :footer, :locals => { :lang => :en }
instance variables set in a route/before filter/view will also be available
Many thanks guys - I think it's working fine.
You can also abstract the calls to the template engines by passing the engine name and then looking up the method on self:
self.method(engine).call
Then you would call the method like this:
=partial(:item, :haml, :collection => @items)
Here is the updated method:
module Sinatra::Partials
def partial(template, engine, *args)
template_array = template.to_s.split('/')
template = template_array[0..-2].join('/') + "/_#{template_array[-1]}"
options = args.last.is_a?(Hash) ? args.pop : {}
options.merge!(:layout => false)
locals = options[:locals] || {}
if collection = options.delete(:collection) then
collection.inject([]) do |buffer, member|
buffer << self.method(engine).call(:"#{template}", options.merge(:layout =>
false, :locals => {template_array[-1].to_sym => member}.merge(locals)))
end.join("\n")
else
self.method(engine).call(:"#{template}", options)
end
end
end
So I'm not sure about including this amendment, but people can use it if they want to.
I have various issues with it, first of all being the additional complexity it adds to the code, and second being the approach of .method(:name).call(*args)
above .send(:name, *args)
(yes, not sure why i prefer the second, does anyone have any well-founded opinions?)
Iain Barnett (@yb66) made a gem of this code - https://github.com/yb66/Sinatra-Partial - with some improvements . I might submit a pull request later this week with some of my ideas about how we can get over the selection of template renderers.
You could also call Sinatra's render
method directly, some things like inline markaby or auto-detecting content-types (irrelevant for partials) just won't work.
@rkh that's actually what i was planning on doing, though I didn't know a render
method existed, so I was going to write my own. Time to dive into the sinatra source
I spent some time studying base.rb before making my implementation, and I considered using render directly, but it I personally did not like the idea of bypassing the built-in template rendering methods.
Excellent! I will be switching my current project over to using the gem. Thanks for all of the great work!
..and Im getting this way just "footer" as a string, parsed in my footer