Very often, partials need their own JavaScript. The best way to do this is with <% content_for :head do %> <%= javascript_include_tag ''myjsfile'' %> <% end %> The problem is that you can end up including the same JavaScript file more than once. This can break certain types of JS, install the same event listener twice, and other badness. The solution would be to use a Set to keep track of the files included. The tricky part? The partials need to add to the Set, but the layout head needs to be able to read it. The layout needs to read it *after* the partials have added to it. Doing this right is tricky. content_for does it, but I haven''t been able to duplicate it. Any ideas? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
This is just an idea off the top of my head, i.e. i haven''t tried it. Could you override the content_for method, (alias old_content_for ... yada yada). Your new content_for will keep an array just like you suggested and check if it''s been loaded already. If you do it like this you don''t have to worry about the scoping of your array which seems to be the issue you were having. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jimmy Kittiyachavalit
2006-Nov-29 19:44 UTC
Re: Best Way to Include JavaScript from partials
/app/helpers/application.rb: <code> def add_javascript(js_file) @additional_javascripts ||= [] @additional_javascripts << js_file end def import_additional_javascripts if @additional_javascripts javascript_include_tag *@additional_javascripts end end </code> /app/views/some_controller/some_action.rb: <code> <% add_javascript "path/to/js_file" %> </code> /app/views/layout/application.rb: <code> <head> <%= javascript_include_tag :defaults %> <%= import_additional_javascripts %> </head> </code> To make sure the same file is not required twice, you can use the Array#uniq method on the @additional_javascripts object. On 11/29/06, Robert James <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > Very often, partials need their own JavaScript. The best way to do this > is with > <% content_for :head do %> > <%= javascript_include_tag ''myjsfile'' %> > <% end %> > > The problem is that you can end up including the same JavaScript file > more than once. This can break certain types of JS, install the same > event listener twice, and other badness. > > The solution would be to use a Set to keep track of the files included. > The tricky part? The partials need to add to the Set, but the layout > head needs to be able to read it. The layout needs to read it *after* > the partials have added to it. Doing this right is tricky. content_for > does it, but I haven''t been able to duplicate it. > > Any ideas? > > -- > Posted via http://www.ruby-forum.com/. > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jimmy, I had tried something like that. The problem was that the method in the head is being called before the view has a chance to add the javascripts, and consequently is nil. Were you able to get what you wrote to work? Robert Jimmy Kittiyachavalit wrote:> /app/helpers/application.rb: > <code> > def add_javascript(js_file) > @additional_javascripts ||= [] > @additional_javascripts << js_file > end > > def import_additional_javascripts > if @additional_javascripts > javascript_include_tag *@additional_javascripts > end > end > </code> > > /app/views/some_controller/some_action.rb: > <code> > <% add_javascript "path/to/js_file" %> > </code> > > /app/views/layout/application.rb: > <code> > <head> > <%= javascript_include_tag :defaults %> > <%= import_additional_javascripts %> > </head> > </code> > > To make sure the same file is not required twice, you can use the > Array#uniq > method on the @additional_javascripts object.-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I have thought about this for a while. I''ve not implemented it, but it''s along the lines of the content_for method. This is untested and at the moment just my mind rambling in the application helper def demand_javascript( *list ) @demanded_javascripts ||= Set.new # find new items in list tmp = ( @demanded_javascripts | list ) - @demanded_javascripts content_for :javascripts do javascript_include_tag *tmp end @demanded_javascripts.add list end Then in your view you can call as many times as you like <% demand_javascript "my","javascript","files" %> I hope that works. I think I''ll give it a try when I get home. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jimmy Kittiyachavalit
2006-Nov-30 07:07 UTC
Re: Best Way to Include JavaScript from partials
Robert, Yes, I use this code regularly in all of my rails apps. As far as I know, the view code is always run before the layout code. If you tried something similar or tried the code I posted, and it failed, I would be willing to help you debug it, just tell me how it failed. Jimmy On 11/29/06, Robert James <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > Jimmy, > > I had tried something like that. The problem was that the method in the > head is being called before the view has a chance to add the > javascripts, and consequently is nil. Were you able to get what you > wrote to work? > > Robert > > > Jimmy Kittiyachavalit wrote: > > /app/helpers/application.rb: > > <code> > > def add_javascript(js_file) > > @additional_javascripts ||= [] > > @additional_javascripts << js_file > > end > > > > def import_additional_javascripts > > if @additional_javascripts > > javascript_include_tag *@additional_javascripts > > end > > end > > </code> > > > > /app/views/some_controller/some_action.rb: > > <code> > > <% add_javascript "path/to/js_file" %> > > </code> > > > > /app/views/layout/application.rb: > > <code> > > <head> > > <%= javascript_include_tag :defaults %> > > <%= import_additional_javascripts %> > > </head> > > </code> > > > > To make sure the same file is not required twice, you can use the > > Array#uniq > > method on the @additional_javascripts object. > > > -- > Posted via http://www.ruby-forum.com/. > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jimmy Kittiyachavalit wrote:> Robert, > Yes, I use this code regularly in all of my rails apps. As far as I > know, > the view code is always run before the layout code. If you tried > something > similar or tried the code I posted, and it failed, I would be willing to > help you debug it, just tell me how it failed. > > JimmyI found the problem I was having. The view code is run before the layout. However, I had some partials from within the layout add javascriipts. Partials in the layout are not run before the layout itself, and so they can''t add to the head. Is there any solution for this? Or should I just do these manually? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I have just released a really simple plugin for this. It ensures that there is no duplication of javascripts. Stylesheets can also be included similarly. You can get the lowdown at http://www.agilewebdevelopment.com/plugins/resource_on_demand In your head tag of the layout <%= include_on_demand %> anywhere in your views <% demand_javascript "some", "javascript", :defaults %> <% demand_stylesheet "a", "style", "sheet" %> This plugin is very simple but I hope useful :) Cheers Daniel On 11/30/06, Robert James <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > Jimmy Kittiyachavalit wrote: > > Robert, > > Yes, I use this code regularly in all of my rails apps. As far as I > > know, > > the view code is always run before the layout code. If you tried > > something > > similar or tried the code I posted, and it failed, I would be willing to > > help you debug it, just tell me how it failed. > > > > Jimmy > > I found the problem I was having. The view code is run before the > layout. However, I had some partials from within the layout add > javascriipts. Partials in the layout are not run before the layout > itself, and so they can''t add to the head. > > Is there any solution for this? Or should I just do these manually? > > -- > Posted via http://www.ruby-forum.com/. > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 11/30/06, Daniel N <has.sox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > I have just released a really simple plugin for this. It ensures that > there is no duplication of javascripts. Stylesheets can also be included > similarly. > > You can get the lowdown at > > http://www.agilewebdevelopment.com/plugins/resource_on_demand > > In your head tag of the layout > > <%= include_on_demand %> > > anywhere in your views > > <% demand_javascript "some", "javascript", :defaults %> > > <% demand_stylesheet "a", "style", "sheet" %> > > This plugin is very simple but I hope useful :) > > Cheers > DanielNot quite enough information. :( The svn is at http://svn.devjavu.com/liquid/resource_on_demand --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel ----- wrote:> I have just released a really simple plugin for this. It ensures that > there > is no duplication of javascripts. Stylesheets can also be included > similarly. > > You can get the lowdown at > > http://www.agilewebdevelopment.com/plugins/resource_on_demand >Excellent! Any solution to the problem I raised: demanding javascripts from partials called within the *layout* (not the view)? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/1/06, Robert James <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > > Daniel ----- wrote: > > I have just released a really simple plugin for this. It ensures that > > there > > is no duplication of javascripts. Stylesheets can also be included > > similarly. > > > > You can get the lowdown at > > > > http://www.agilewebdevelopment.com/plugins/resource_on_demand > > > > Excellent! > > Any solution to the problem I raised: demanding javascripts from > partials called within the *layout* (not the view)?I wouldn''t think it would make a difference. Does it not work in this situation? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/1/06, Daniel N <has.sox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > > On 12/1/06, Robert James <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > > > > > > Daniel ----- wrote: > > > I have just released a really simple plugin for this. It ensures that > > > there > > > is no duplication of javascripts. Stylesheets can also be included > > > similarly. > > > > > > You can get the lowdown at > > > > > > http://www.agilewebdevelopment.com/plugins/resource_on_demand > > > > > > > Excellent! > > > > Any solution to the problem I raised: demanding javascripts from > > partials called within the *layout* (not the view)? > > > I wouldn''t think it would make a difference. Does it not work in this > situation? >I would have thought that you could include the <%= include_on_demand %> in the head tag and then use <% demand_javascript "my_script" %> in you partial. I will check it when I get home (not for about 8 or 9 hours though! ) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/1/06, Daniel N <has.sox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > > On 12/1/06, Daniel N <has.sox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > > On 12/1/06, Robert James < rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > > > > > > > > > Daniel ----- wrote: > > > > I have just released a really simple plugin for this. It ensures > > > that > > > > there > > > > is no duplication of javascripts. Stylesheets can also be included > > > > similarly. > > > > > > > > You can get the lowdown at > > > > > > > > http://www.agilewebdevelopment.com/plugins/resource_on_demand > > > > > > > > > > Excellent! > > > > > > Any solution to the problem I raised: demanding javascripts from > > > partials called within the *layout* (not the view)? > > > > > > I wouldn''t think it would make a difference. Does it not work in this > > situation? > > > > I would have thought that you could include the > <%= include_on_demand %> in the head tag and then use > > <% demand_javascript "my_script" %> in you partial. > > I will check it when I get home (not for about 8 or 9 hours though! ) >Ok I''ve had a chance to play with it and I''ve found a way that it can be done. It''s a bit of hackery though. You can put a yield call in your head tag so that you can get javascripts there. But, before your yield in the head tag, you need to render your partials. You can put them elsewhere in your layout by including these into content_for blocks. In your layout (HTML interspersed where ever ) <% content_for :my_partial do %> <%= render :partial => ''my_partial'' -%> <% end %> <%= yield :javascripts %> <%= yield :my_partial %> In the context of the plugin that I released, if your interested. (I''ve changed the method names since last night. I wasn''t entirely satisfied with them) <% content_for :my_partial do %> <%= render :partial => ''my_partial'' -%> <% end %> <%= require_on_demand %> <%= yield :my_partial %> and then anywhere in your partial, or views <% require_javascript "my", "javascript", :defaults %> At least this works on edge ;) I hope that will get you going. Cheers Daniel --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel ----- wrote:> On 12/1/06, Daniel N <has.sox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > Ok I''ve had a chance to play with it and I''ve found a way that it can be > done. It''s a bit of hackery though. > > You can put a yield call in your head tag so that you can get > javascripts > there. But, before your yield in the head tag, you need to render your > partials. You can put them elsewhere in your layout by including these > into > content_for blocks.Great idea - thanks. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Friday 01 December 2006 08:25, Daniel N wrote:> In your layout (HTML interspersed where ever ) > > <% content_for :my_partial do %> > <%= render :partial => ''my_partial'' -%> > <% end %> > > <%= yield :javascripts %> > > <%= yield :my_partial %>This content_for and yield looks overly complicated to me. In particular, as content_for does not do much more than set an instance variable. A tiny bit of code in ApplicationHelper does all that''s necessary. Michael # app/helpers/application_helper.rb module ApplicationHelper def require_js(*js) @required_js ||= [] @required_js |= js end def require_css(*css) @required_css ||= [] @required_css |= css end def include_required_js javascript_include_tag(*@required_js) end def include_required_css stylesheet_link_tag(*@required_js) end end # app/views/layouts/application.rhtml <html> <head> <%= include_required_js %> <%= include_required_css %> </head> <body> <%= yield %> </body> </html> # app/views/whatever/index.rhtml <%= render :partial => ''part1'' %> <%= render :partial => ''part2'' %> # app/views/whatever/_part1.rhtml <% require_js ''this'' -%> <% require_css ''that'', ''another_one'' -%> Partial 1 # app/views/whatever/_part2.rhtml <% require_js ''this'', ''something_else'' -%> <% require_css ''that'' -%> Partial 2 -- Michael Schuerig mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org http://www.schuerig.de/michael/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 12/2/06, Michael Schuerig <michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org> wrote:> > > On Friday 01 December 2006 08:25, Daniel N wrote: > > > In your layout (HTML interspersed where ever ) > > > > <% content_for :my_partial do %> > > <%= render :partial => ''my_partial'' -%> > > <% end %> > > > > <%= yield :javascripts %> > > > > <%= yield :my_partial %> > > This content_for and yield looks overly complicated to me. In > particular, as content_for does not do much more than set an instance > variable. A tiny bit of code in ApplicationHelper does all that''s > necessary. > > Michael > > > # app/helpers/application_helper.rb > module ApplicationHelper > def require_js(*js) > @required_js ||= [] > @required_js |= js > end > > def require_css(*css) > @required_css ||= [] > @required_css |= css > end > > def include_required_js > javascript_include_tag(*@required_js) > end > > def include_required_css > stylesheet_link_tag(*@required_js) > end > end > > # app/views/layouts/application.rhtml > <html> > <head> > <%= include_required_js %> > <%= include_required_css %> > </head> > <body> > <%= yield %> > </body> > </html> > > # app/views/whatever/index.rhtml > <%= render :partial => ''part1'' %> > <%= render :partial => ''part2'' %> > > # app/views/whatever/_part1.rhtml > <% require_js ''this'' -%> > <% require_css ''that'', ''another_one'' -%> > Partial 1 > > # app/views/whatever/_part2.rhtml > <% require_js ''this'', ''something_else'' -%> > <% require_css ''that'' -%> > Partial 2Initially this was all I thought it was also. But when you have a partial in you layout it is not so simple. The partial in the layout does not seem to be processed prior to the layout being rendered. It seems to be rendered more inline than the view. Following your suggestion above, # app/views/layouts/application> > .rhtml > <html> > <head> > <%= include_required_js %> > <%= include_required_css %> > </head> > <body> > <%= yield %><%= render :partial => ''part3'' %> </body>> </html>Any javascript required in the part3 partial will not be added. This was the problem, that partials in the layout are not included. Also thanx for the |= I didn''t know about that one. Cheers Daniel --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---