more info

Media72 Hosting Articles and Tips

Javascript auto include rails plugin

This plugin has been updated to include additional functionality.

We are very pleased to announce the javascript_auto_include plugin for ruby on rails written by our very own Jamie Dyer. This plugin automatically includes javascript code that is specific to a single view or controller which means you don’t have to pass anything to your template telling it which javascript files are needed for each page.

Working with unobtrusive javascript in Rails can be somewhat difficult. While Rails default javascript helpers are easy to use they produce javascript that is not unobtrusive.

When writing unobtrusive javascript in Rails it’s often necessary to include a javascript file that will be used by a single view or controller. This can become problematic, messy and very un-Rails like if not managed well.

With the Rails philosophy “convention over configuration” in mind I decided to create a plugin to automatically including javascript files that correspond to the view or controller name mirroring the view structure within the javascripts folder. The javascript_auto_include plugin is born and is probably among the smallest Rails plugins available, aren’t all the best plugins tiny?

To use the javascript_auto_include firstly install the plugin:


script/plugin install http://kernowsoul.com/svn/plugins/javascript_auto_include

Or if you run EDGE rails or rails 2.1 and above:


script/plugin install git://github.com/kernow/javascript_auto_include.git

The plugin will create the directory “views” within your javascripts directory in which you can place javascript files for auto inclusion. Using javascript_auto_include is simple, in the layout file add < %= javascript_auto_include_tags %> to the header.

There are two types of javascript includes, view specific, and controller specific. The first is achieved by creating a folder with the same name as a controller, inside this create a javascript file with the same name as a view. The second type, controller specific, are simply files inside the views folder with the same name as the controller. For example:


/public
  /javascripts
    /views
      articles.js # will be included in all views of the articles controller
      /users
        new.js # will be included in the new view of the users controller

The plugin will also include both controller and view specific javascript at the same time, in this example both users.js and new.js will be included when the new view is loaded.


/public
  /javascripts
    /views
      users.js
      /users
        new.js

If you have any comments or suggestions for improvements we would love to hear them. I may add a generator to make adding new javascript files easy.

15 Responses to “Javascript auto include rails plugin”

  1. Bogdan Says:

    Nice idea. I’ve been using something like this in my latest projects, but calling the folder behaviours and using a small helper to include the js’s with a call in the template.

    One problem that I’ve ran into is when you bind behaviours on form fields in your _form.html.erb partial. You would get duplicate content for your new.js and edit.js files. That’s why I’ve dropped for now the automatic inclusion of js files per controller and action and using simply content_for and yielding the @javascripts in the template.

    Any thoughts on solving this duplication problem?

  2. Media72 Says:

    @Bogdan: can you give an example? The javascript_auto_include is not partial aware so it will only include a maximum of 2 javascript files, one with the same name as the controller and one with the same name as the view. I don’t believe you will have the same problem with this plugin, but with the lack of an example it’s hard to say for sure.

  3. Nome do Jogo » Artigo » Rails Podcast Brasil - Episódio 17 Says:

    [...] Javascript auto include rails plugin [...]

  4. weepy Says:

    Hi – does this with a :cache option ?

  5. Media72 Says:

    @weepy: Yes it will work with most types of caching.

  6. Geoff Says:

    @Media72: I think Bogdan means he’s got some javascript form validation or something of that kind which is intended to be used with his _form that is rendered into his new and edit view templates. So in order to have the javascript appear and work for the form two copies of the validation code would need to exist in both public/javascripts/views/users/{new,edit}.js instead of just once in say _form.js

  7. Media72 Says:

    @Geoff & @ Bogdan: In the case of form partials the auto include only looks at the controller and view names when determining what to load, the plugin is not partial aware. You could either put your code in the controller JS file and have it loaded for all views of that controller, or you could create two files with the same code.

    If could be something to include in a future version that will in some way allow the inclusion of a single file in multiple views. Maybe something along the lines of public/javascripts/views/users/new|edit.js could be one way.

  8. masone Says:

    It would be great if it worked with .js.erb files too.

    Great plugin though. Absolutely what I was always looking for!

  9. Media72 Says:

    @masone: If you are using .js.erb files you can tell the controller which view/.js.erb file to render so there is no need to this plugin in that situation.

  10. masone Says:

    Yeah, but I can only render either a JS or a HTML response at once, right? I think with a JS hook in the respond_to block it only will render the js.erb if I explicitly request a JS via the content type header which is not exactly the case with the auto include plugin.

    So if I want to render a show.html.erb and a show.js.erb “at once” it won’t work or am I wrong?

  11. PICO Says:

    1 problem might be that you need to include some javascript at a certain point in a page, this solution wont help you with that. I’ve thought about this exact thing before, and I find that its just easier to have small pieces of javascript just on the view page where they belong. No big deal.

  12. Media72 Says:

    @PICO: Inline javascript is bad and IMO should be avoided at all costs. In fact I can’t think of any time I have needed to use inline javascript recently, or any reason why you would need to. This plugin was not designed, and never will include, support for inline javascript.

    I would suggest you look at the load events offered by most JS libraries and use this to add functionality to your pages.

  13. antipode Says:

    Awesome idea! I heard about this a while ago on the Rails Envy podcast. Now I’m planning to use your plugin in conjunction Dan Webb’s LowPro (http://www.danwebb.net/lowpro). I think that will be a good fit.

  14. Mark Says:

    In case somebody likes to use this plugin with the warbler-gem.
    I had to change the jsai_path in javascript_auto_include.rb to “#{JAVASCRIPTS_DIR}/views” to make it work with the ruby warbler-gem because the created war-file has a different directory-structure as the standard rails one.

  15. Tack Says:

    Neat! I’ve taken your idea and done a similar thing for stylesheets. Here’s what I’ve got so far:

    https://github.com/ajtack/css_auto_include

Leave a Reply

 

hedges