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.


Reply via email to