By all means! On Thursday, May 30, 2013, Daniel Schierbeck wrote:
> 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 i > > -- > 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:_e({}, > 'cvml', 'rubyonrails-core%[email protected]');>. > To post to this group, send email to > [email protected]<javascript:_e({}, 'cvml', > '[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.
