Actually, the assigns didn't seem to be a major issue. I'm struggling a bit 
with the output buffering though.

Can I start a Work In Progress PR on GitHub? I have a few ideas for how to 
proceed, but I'd like to get some feedback soon :-)

On Wednesday, May 29, 2013 8:17:31 PM UTC+2, Daniel Schierbeck wrote:
>
> 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]
>> > 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].
>>> 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.
>>>  
>>>  
>>>
>>
>>

-- 
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