Hi, I''m finding it difficult to use partials. Getting them to work seems to be a matter of trial and (mostly) error. I had one working nicely, then changed the name of the partial and it doesn''t work anymore - the parameter passing is broken. The API docs are pretty bare, and even contains a mistake, which is a shame, because the parameter passing appears to rely on some undocumented magic. OK. If someone can fully explain partials in reply to this email, I''ll submit a patch documenting them in the source code. You can''t say fairer than that! Cheers, Gavin
How about whoever is explaining them just puts it up on the website and posts the link here. =] On Apr 6, 2005 9:35 AM, Gavin Sinclair <gsinclair-81uBx+iSpXA0n/F98K4Iww@public.gmane.org> wrote:> > Hi, > > I''m finding it difficult to use partials. Getting them to work seems > to be a matter of trial and (mostly) error. I had one working nicely, > then changed the name of the partial and it doesn''t work anymore - the > parameter passing is broken. The API docs are pretty bare, and even > contains a mistake, which is a shame, because the parameter passing > appears to rely on some undocumented magic. > > OK. If someone can fully explain partials in reply to this email, > I''ll submit a patch documenting them in the source code. You can''t say > fairer than that! > > Cheers, > Gavin > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- - Ramin http://www.getintothis.com/blog _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
On Wednesday, April 6, 2005, 11:35:34 PM, Gavin wrote:> OK. If someone can fully explain partials in reply to this email, > I''ll submit a patch documenting them in the source code. You can''t say > fairer than that!Surely _someone_ wants to help document Rails simply by emailing what they already know? Please? You only have to write informally. Gavin
On Apr 7, 2005 1:35 AM, Gavin Sinclair <gsinclair-81uBx+iSpXA0n/F98K4Iww@public.gmane.org> wrote:> Hi, > > I''m finding it difficult to use partials. Getting them to work seems > to be a matter of trial and (mostly) error. I had one working nicely, > then changed the name of the partial and it doesn''t work anymore - the > parameter passing is broken. The API docs are pretty bare, and even > contains a mistake, which is a shame, because the parameter passing > appears to rely on some undocumented magic.They''re little snippets of HTML that you include in to your main code using render_partial, allowing for code reuse. They can''t access local scope variables, but class scope ones are fine. The file names start with an underscore, but that''s not mentioned in the code, eg render_partial("item") uses views/currentcontroller/_item.rhtml, render_partial("othercontroller/item") uses views/othercontroller/_item.rhtml render_partial_collection takes the name of the partial and an object that can be enumerated. For every item in the object it calls the partial with a variable the same as the name of the partial, containing the current item in the object. eg. render_partial_collection(''item'', @things) works like @things.each do |item| #here you include _item.rhtml, which then has the variable item to work with end Hope this helps a bit. -- Phillip Hutchings http://www.sitharus.com/ sitharus-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org / sitharus-QrR4M9swfipWk0Htik3J/w@public.gmane.org
On Thursday, April 7, 2005, 2:05:11 PM, Phillip wrote:> On Apr 7, 2005 1:35 AM, Gavin Sinclair > <gsinclair-81uBx+iSpXA0n/F98K4Iww@public.gmane.org> wrote: >> Hi, >> >> I''m finding it difficult to use partials. Getting them to work seems >> to be a matter of trial and (mostly) error. I had one working nicely, >> then changed the name of the partial and it doesn''t work anymore - the >> parameter passing is broken. The API docs are pretty bare, and even >> contains a mistake, which is a shame, because the parameter passing >> appears to rely on some undocumented magic.> They''re little snippets of HTML that you include in to your main code > using render_partial, allowing for code reuse. They can''t access local > scope variables, but class scope ones are fine. The file names start > with an underscore, but that''s not mentioned in the code, eg > render_partial("item") uses views/currentcontroller/_item.rhtml, > render_partial("othercontroller/item") uses > views/othercontroller/_item.rhtml> [snip render_partial_collection]> Hope this helps a bit.That''s a very good start. Now, how does the partial access the data it needs? Say the view is rendering a list of todos: <% for item in @todos %> <%= render_partial "item_summary", ... %> <% end %> The partial "item_summary looks like this: <h4><%= item.description %></h4> <%= item.priority %>, <%= item.due_date %> Questions: * what goes into the "..." in the view such that the partial can use the todo item? * does anything in the partial need to change so that connection can be made? Gavin
> That''s a very good start. Now, how does the partial access the data it > needs?The partial has access to the calling class variables, as it''s called inside the class.> Say the view is rendering a list of todos: > > <% for item in @todos %> > <%= render_partial "item_summary", ... %> > <% end %> > > The partial "item_summary looks like this: > > <h4><%= item.description %></h4> > <%= item.priority %>, <%= item.due_date %>That won''t work - as I said before, the partial does not seem to have access to the local variables - item is a local variable - but it does have access to the instance variables. Change the code to this: <% for @item in @todos > <%= render_partial "item_summary" %> <% end %> and the partial should be this <h4><%= @item.description %></h4> <%= @item.priority %>, <%= @item.due_date %> -- Phillip Hutchings http://www.sitharus.com/ sitharus-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org / sitharus-QrR4M9swfipWk0Htik3J/w@public.gmane.org
On Thursday, April 7, 2005, 3:44:13 PM, Phillip wrote:>> >> The partial "item_summary looks like this: >> >> <h4><%= item.description %></h4> >> <%= item.priority %>, <%= item.due_date %>> That won''t work - as I said before, the partial does not seem to have > access to the local variables - item is a local variable - but it does > have access to the instance variables. Change the code to this:> <% for @item in @todos > > <%= render_partial "item_summary" %> > <% end %>> and the partial should be this > <h4><%= @item.description %></h4> > <%= @item.priority %>, <%= @item.due_date %>OK, that will work. But I have an aesthetic objection to using instance variables where they would normally be local variables. Is there a way I can use the arguments to render_partial to make this work in another way? render_partial has the following signature: render_partial(partial_path, object = nil, local_assigns = {}) What do ''object'' and ''local_assigns'' mean? Gavin
> OK, that will work. But I have an aesthetic objection to using > instance variables where they would normally be local variables. Is > there a way I can use the arguments to render_partial to make this > work in another way? render_partial has the following signature: > > render_partial(partial_path, object = nil, local_assigns = {}) > > What do ''object'' and ''local_assigns'' mean?http://rails.rubyonrails.com/classes/ActionView/Partials.html Apparently the ''object'' is passed through as a local variable. It has the same name as the partial, so if your partial was _item.rhtml and you called render_partial ''item'', stuff you could access stuff through the variable item. -- Phillip Hutchings http://www.sitharus.com/ sitharus-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org / sitharus-QrR4M9swfipWk0Htik3J/w@public.gmane.org
On Thursday, April 7, 2005, 3:59:29 PM, Phillip wrote:>> OK, that will work. But I have an aesthetic objection to using >> instance variables where they would normally be local variables. Is >> there a way I can use the arguments to render_partial to make this >> work in another way? render_partial has the following signature: >> >> render_partial(partial_path, object = nil, local_assigns = {}) >> >> What do ''object'' and ''local_assigns'' mean?> http://rails.rubyonrails.com/classes/ActionView/Partials.htmlThat doesn''t explain ''object'' well, and doesn''t explain ''local_assigns'' at all, which is why I''m asking these questions - so I can submit a patch to improve the docs :)> Apparently the ''object'' is passed through as a local variable. It has > the same name as the partial, so if your partial was _item.rhtml and > you called render_partial ''item'', stuff you could access stuff through > the variable item.So the partial can have an automatic local variable of the same name as the partial. This seems very flimsy to me. Building on the example I gave before, say I have three partials to display a todo item in different ways: _item_brief.rhtml _item_verbose.rhtml _item_full_and_colorful.rhtml That seems reasonable to me. The view can choose which partial it will render based on the user''s preferences. Now, those are reasonable names for partials, but they are horrible names for variables. Don''t get me wrong, I love the Rails magic, but this particular magic is misguided IMO. The calling convention I''d prefer is this: render_partial ''item_verbose'', :item => item Forget the automatic creation of a local variable; just create the variables that are specified. It''s not much more keyboarding, but it''s much clearer. I haven''t been able to get ''local_assigns'' working in any way, however. Anyway, does anyone have any comments on this, or clarifications of how ''local_assigns'' works? Thanks very much for your help so far, Phillip. Gavin
> > http://rails.rubyonrails.com/classes/ActionView/Partials.html > > That doesn''t explain ''object'' well, and doesn''t explain > ''local_assigns'' at all, which is why I''m asking these questions - so I > can submit a patch to improve the docs :)There were a couple of things there, but rather obscure. If you read render_partial_collection there were some hints.> > Apparently the ''object'' is passed through as a local variable. It has > > the same name as the partial, so if your partial was _item.rhtml and > > you called render_partial ''item'', stuff you could access stuff through > > the variable item. > > So the partial can have an automatic local variable of the same name > as the partial. This seems very flimsy to me. Building on the > example I gave before, say I have three partials to display a todo > item in different ways: > > _item_brief.rhtml > _item_verbose.rhtml > _item_full_and_colorful.rhtml > > That seems reasonable to me. The view can choose which partial it > will render based on the user''s preferences. Now, those are > reasonable names for partials, but they are horrible names for > variables. Don''t get me wrong, I love the Rails magic, but this > particular magic is misguided IMO.I agree, it''s quite confusing.> The calling convention I''d prefer is this: > > render_partial ''item_verbose'', :item => item > > Forget the automatic creation of a local variable; just create the > variables that are specified. It''s not much more keyboarding, but > it''s much clearer. > > I haven''t been able to get ''local_assigns'' working in any way, > however. > > Anyway, does anyone have any comments on this, or clarifications of > how ''local_assigns'' works?Looking at the source, that''s what it does, but you need to use strings as keys. render_partial(''item'', nil, {"stuff"=>stuff}) looks like it''ll work, or in low-formatting terms, render_partial ''item'', nil, "stuff"=>stuff You may be able to drop the nil, but I''m not too sure. -- Phillip Hutchings http://www.sitharus.com/ sitharus-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org / sitharus-QrR4M9swfipWk0Htik3J/w@public.gmane.org
On Thursday, April 7, 2005, 4:38:30 PM, Phillip wrote:>> > http://rails.rubyonrails.com/classes/ActionView/Partials.html >> >> That doesn''t explain ''object'' well, and doesn''t explain >> ''local_assigns'' at all, which is why I''m asking these questions - so I >> can submit a patch to improve the docs :)> There were a couple of things there, but rather obscure. If you read > render_partial_collection there were some hints.Ah, thanks. I''ll read that bit more closely. I must say, I don''t find render_partial_collection very attractive. When looking at a code example, I can''t understand what all the parameters mean, so I tend to avoid it.>> [...] >> The calling convention I''d prefer is this: >> >> render_partial ''item_verbose'', :item => item >> >> Forget the automatic creation of a local variable; just create the >> variables that are specified. It''s not much more keyboarding, but >> it''s much clearer. >> >> I haven''t been able to get ''local_assigns'' working in any way, >> however. >> >> Anyway, does anyone have any comments on this, or clarifications of >> how ''local_assigns'' works?> Looking at the source, that''s what it does, but you need to use > strings as keys. render_partial(''item'', nil, {"stuff"=>stuff}) looks > like it''ll work, or in low-formatting terms, render_partial ''item'', > nil, "stuff"=>stuff> You may be able to drop the nil, but I''m not too sure.I doubt you can drop the nil; although I guess it''s possible Ruby-wise. My examination of the source code so far suggests you can''t, though. So ''local_assigns'' works like I expected, but didn''t work because the keys (counter-intuitively) must be strings. I''ll test that out in my code, and get on with the documentation. Cheers, Gavin
Hi! On Thu, 07 Apr 2005, Gavin Sinclair wrote the following:> So ''local_assigns'' works like I expected, but didn''t work because the > keys (counter-intuitively) must be strings. I''ll test that out in my > code, and get on with the documentation.I can''t get it to work... take a look at the following code snippets: in my controller: ---- def create_with_ajax @tag = Tag.new(@params[:tag]) @tag.save list render_partial ''shared/tag_list'', @tags, {''current'' => @tag} end ---- and in my view I would like to access ''current'', I tried: ---- <%= @current.name %> ---- (tag has an attribute ''name'') but that doesn''t work... (returns an error) any help appreciated! kind regards Wolfgang
> I can''t get it to work... > take a look at the following code snippets: > > in my controller: > ---- > def create_with_ajax > @tag = Tag.new(@params[:tag]) > @tag.save > list > render_partial ''shared/tag_list'', @tags, {''current'' => @tag} > end > ---- > > and in my view I would like to access ''current'', I tried: > ---- > <%= @current.name %> > ---- > (tag has an attribute ''name'') > > but that doesn''t work... (returns an error) > any help appreciated!You access current as ''current'', so try dropping the @. -- rick http://techno-weenie.net
Hi! On Thu, 07 Apr 2005, Rick Olson wrote the following:> > in my controller: > > ---- > > def create_with_ajax > > @tag = Tag.new(@params[:tag]) > > @tag.save > > list > > render_partial ''shared/tag_list'', @tags, {''current'' => @tag} > > end > > ---- > > > > and in my view I would like to access ''current'', I tried: > > ---- > > <%= @current.name %> > > ---- > > (tag has an attribute ''name'') > > > > but that doesn''t work... (returns an error) > > any help appreciated! > > You access current as ''current'', so try dropping the @. >doesn''t work either, I already checked that before... that returns: ---- undefined local variable or method `current'' for #<ActionView::Base:0xb7539db0> ---- bye Wolfgang
> doesn''t work either, I already checked that before... that returns: > ---- > undefined local variable or method `current'' for > #<ActionView::Base:0xb7539db0> > ---- > > bye > Wolfgangthis isn''t an answer to your question but it is a solution to the problem. in the view : <%= render_partial ''partial_with_a_very_long_name'', @some_var %> in the partial : <% obj = partial_with_a_very_long_name %> <tr><td><%= obj.name %></td><td><%= obj.some_attibute %></td></tr> hth
Gavin Sinclair wrote:> That doesn''t explain ''object'' well, and doesn''t explain > ''local_assigns'' at all, which is why I''m asking these questions - so I > can submit a patch to improve the docs :)render_partial munges its path, munges a target object into a local var to the partial name, and calls render. render handles the template rendering and local_assigns (a hash of var name and value pairs evaluated in a binding passed to erb). Path munging: ''foo'' -> ''controller/_foo'' ''shared/foo'' -> ''shared/_foo'' If path not present, prefix with path to controller templates and underscore template name. If path present, underscore the last component. Target object munging: render_partial ''foo'', nil sets foo = instance_variable_get("@foo") render_partial ''foo'', bar sets foo = bar Local assigns are pairs of string names and their values. Assigns are evaluated in a binding that''s passed to erb. All too much munging! The naming is also unworkable: render_partial ''partial_with_descriptive_name'' expects me to work with that variable? No thanks. I prefer render. It''s clear and direct: render ''controller/_foo'', ''foo'' => @foo This is the case render_partial is optimized for, collapsing to just render_partial ''foo'' But it leaves what''s actually going on up to the imagination. In more complex scenarios, render is simpler: render ''path/to/fragment/_sidebar'', ''heading'' => ''Hallo.'', ''items'' => items The partial would be: render_partial ''path/to/fragment/sidebar'', nil, ''heading'' => ''Hallo.'', ''items'' => items Thanks for patching the docs. I just glanced at the source and there are 30 lines of docs for 40 lines of code. jeremy
I think the confusing part here is the naming conventions used in Rails. The way I use partials, the "partial" is a single object (or part) of the page as a whole, so using a name like ''tag_list'' causes confusion. The magic local variable is the tricky part, but this is easier to explain when you treat a partial as a single item: In your example Wolfgang, why not just do this: ---- def create_with_ajax @tag = Tag.new(@params[:tag]) @tag.save list render_partial ''shared/partials/tag'', @tag end ---- ---- <%= tag.name %> ---- Partials are just that, a single part of the page as a whole... so think of them as such when you name them and hopefully it''ll make more sense. Hope this helps, Ben On Apr 7, 2005 8:45 AM, Wolfgang Klinger <wolfgang-qRyVSpHmpvQsV2N9l4h3zg@public.gmane.org> wrote:> > Hi! > > On Thu, 07 Apr 2005, Rick Olson wrote the following: > > > in my controller: > > > ---- > > > def create_with_ajax > > > @tag = Tag.new(@params[:tag]) > > > @tag.save > > > list > > > render_partial ''shared/tag_list'', @tags, {''current'' => @tag} > > > end > > > ---- > > > > > > and in my view I would like to access ''current'', I tried: > > > ---- > > > <%= @current.name %> > > > ---- > > > (tag has an attribute ''name'') > > > > > > but that doesn''t work... (returns an error) > > > any help appreciated! > > > > You access current as ''current'', so try dropping the @. > > > > doesn''t work either, I already checked that before... that returns: > ---- > undefined local variable or method `current'' for > #<ActionView::Base:0xb7539db0> > ---- > > bye > Wolfgang > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Hi! On Thu, 07 Apr 2005, Ben Schumacher wrote the following:> def create_with_ajax > @tag = Tag.new(@params[:tag]) > @tag.save > list > render_partial ''shared/partials/tag'', @tag > end > ---- > > ---- > <%= tag.name %> > ---- > > Partials are just that, a single part of the page as a whole... so > think of them as such when you name them and hopefully it''ll make more > sense.Ok, that works, now I''m a bit confused... I have access to every instance variable (@xy) in the partial view, now what''s about ''object'' and ''local_assigns''? (as Gavin already asked) I think that''s the real question in this thread but nobody can give an answer, where''s the author of this code, what did he think when he wrote that? Enlighten us! :-) anyway... thanks Ben, bye Wolfgang ps: tag_list _is_ only a part of the website ;-)
On Friday, April 8, 2005, 1:35:43 AM, Jeremy wrote:> Thanks for patching the docs. I just glanced at the source and there > are 30 lines of docs for 40 lines of code.Ain''t touched it yet. Those are the docs I''m hoping to patch :) Your explanation was first-rate, so you''ll find the new docs rather ... familiar :) Gavin
On Wednesday, April 6, 2005, 11:35:34 PM, Gavin wrote:> OK. If someone can fully explain partials in reply to this email, > I''ll submit a patch documenting them in the source code. You can''t say > fairer than that!Nearly finished. You can see the docs (all comments welcome) at http://www.pointstorm.com/~gavin/partials-doc/classes/ActionView/Partials.html One last thing, however. Can anyone explain the third parameter in this? render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {}) Thanks, Gavin
According to the documentation, local_assigns is a hash, in the form of ''name'' => object, in which the object specfied becomes available as a local variable in the view. So if I had this (not a great example, mind you): <% @category.children.each do |child| %> <%= render_partial(''categories/child'', @child, ''parent'' => @category %> <% end %> I would expect to be able to access @category as parent in the template. <div><%= parent.name %> > <%= child.name %></div> Make sense? Cheers, bs. On Apr 8, 2005 3:06 AM, Gavin Sinclair <gsinclair-81uBx+iSpXA0n/F98K4Iww@public.gmane.org> wrote:> On Wednesday, April 6, 2005, 11:35:34 PM, Gavin wrote: > > > OK. If someone can fully explain partials in reply to this email, > > I''ll submit a patch documenting them in the source code. You can''t say > > fairer than that! > > Nearly finished. You can see the docs (all comments welcome) at > > http://www.pointstorm.com/~gavin/partials-doc/classes/ActionView/Partials.html > > One last thing, however. Can anyone explain the third parameter in > this? > > render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {}) > > Thanks, > Gavin > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On Saturday, April 9, 2005, 12:09:01 AM, Ben wrote:> According to the documentation, local_assigns is a hash, [...] > Make sense?Makes sense, but the question was about ''partial_spacer_template'', not ''local_assigns'' :) What does the ''partial_spacer_template'' parameter mean in this method signature? def render_partial_collection( partial_name, collection, partial_spacer_template = nil, local_assigns = { ) Cheers, Gavin
On Apr 8, 2005 10:06 AM, Gavin Sinclair <gsinclair-81uBx+iSpXA0n/F98K4Iww@public.gmane.org> wrote:> One last thing, however. Can anyone explain the third parameter in > this? > > render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {}) >partial_spacer_template is the template, if any, to render in between each partial. e.g. to output a bunch of paragraphs with a <hr /> in between, you''d have a partial which outputs the paragraph and another one which ouputs the <hr /> - the spacer template. I''m not sure if the spacer''s name needs to start with _ or not