That's my biggest worry as well. I'll give it a shot - I have an idea for how I can cut the problem into smaller steps.
On Wednesday, May 29, 2013 7:38:13 PM UTC+2, Jeremy Kemper wrote: > > Go for it, Daniel! > > I think you'll find that handling references to local & instance vars is > the fly in the ointment. Method-missing doesn't cut it since it's very low > precedence compared to a real local var. > > > On Wed, May 29, 2013 at 7:41 AM, Daniel Schierbeck > <[email protected]<javascript:> > > wrote: > >> Hi guys, >> >> I think this may be too daunting a task, but I'd like to propose a change >> to the way views are rendered in Rails. >> >> Currently, a template handler converts a template to a string containing >> Ruby code, which then gets evaluated in a context that has certain >> variables present. The code is actually stored as a method on a module as >> far as I can see. >> >> This is all well and good, but I'm interested in using multi-gets to >> efficiently cache the rendering of a collection of objects. Right now I see >> no easy way to do it in PartialRenderer, since the state of the rendering >> is shared between each render. The current code is something like this: >> >> collection.map do |object| >> locals[as] = object >> template.render(view, locals) # returns a string. >> end >> >> I think the code would be more robust, maintainable, and generally just >> easier to work with if the compiled views were instead classes that looked >> like this: >> >> class SomeAnonymousCompiledView >> def initialize(context, locals = {}) >> @context, @locals = context, locals >> end >> >> def render >> output_buffer = "" >> output_buffer << "<h1>I was rendered by ERB!</h1>" >> output_buffer << some_local >> output_buffer >> end >> >> # Template handlers can optionally define a cache_key method. This >> could e.g. >> # encapsulate the stuff currently handled by Cache Digests, but could >> also use >> # the locals. >> def cache_key >> @locals[:fiddle] >> end >> >> def method_missing(*args) >> # This could be a way to handle local lookups. >> end >> end >> >> The project I'm working on, Curly, is a template handler that has a >> built-in concept of presenters. Say there's a template >> "posts/show.html.curly" containing the following: >> >> <h1>{{title}}</h1> >> >> It would have a matching presenter in >> "app/presenters/posts/show_presenter.rb": >> >> class Posts::ShowPresenter < Curly::Presenter >> presents :post # the controller would assign @post >> >> def title # the return value is inserted in the template when rendered >> post.title >> end >> >> # Right now Curly generates code that checks the cache key and uses >> # Action View's existing cache system with the given key. This cannot >> work >> # when rendering a collection, unfortunately. >> def cache_key >> post >> end >> end >> >> I'd love to have my template handler generate the following class: >> >> class CompiledPostsShowView >> def initialize(context, locals = {}) >> @context, @locals = context, locals >> end >> >> def render >> @rendered ||= "<h1>#{presenter.title}</h1>" >> end >> >> # This would be used automatically by Rails if defined. >> def cache_key >> presenter.cache_key >> end >> >> private >> >> def presenter >> @presenter ||= >> Curly.presenter_for_path(@context.virtual_path).new(@context, @locals) >> end >> end >> >> By wrapping each instance of a rendering in an object, we can encapsulate >> and carry around the state, reusing the cache key in multiple locations. >> >> I'm not sure how easy it would be to retrofit this on top of ERB, but it >> should be possible. >> >> I'd be willing to put in the work, I just want to know if this is >> something Core is interested in. >> >> Cheers, >> Daniel (@dasch) >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby on Rails: Core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> To post to this group, send email to >> [email protected]<javascript:> >> . >> Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en >> . >> For more options, visit https://groups.google.com/groups/opt_out. >> >> >> > > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
