Best Way to Include JavaScript from partials

/app/helpers/application.rb: 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

/app/views/some_controller/some_action.rb: <% add_javascript “path/to/js_file” %>

/app/views/layout/application.rb:

<%= javascript_include_tag :defaults %> <%= import_additional_javascripts %>

To make sure the same file is not required twice, you can use the Array#uniq method on the @additional_javascripts object.

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.

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

Cheers Daniel

Not quite enough information. :frowning: The svn is at

http://svn.devjavu.com/liquid/resource_on_demand

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

I hope that will get you going.

Cheers Daniel

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

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

<%= include_required_js %> <%= include_required_css %> <%= yield %>

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

Initially 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

<%= include_required_js %> <%= include_required_css %> <%= yield %>
 <%= render :partial => 'part3' %>

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