Mizugumo is a gem designed to provide Rails with JavaScript and AJAX behavior that is:
-
absolutely seamless
-
completely unobtrusive - no markup whatsoever in your HTML and
-
gracefully-degrading: defaults to fully functional and sensible page-reload behavior when JavaScript is not available.
See a demo running at:
http://mizugumo-demo.lrdesign.com
Or download the code for the demo at:
https://github.com/LRDesign/mizugumo_demo
Mizugumo uses NinjaScript by Judson Lester to provide unobtrusive JS behaviors. For more info, see:
git@github.com:LRDesign/NinjaScript.git
In the current (early release) version, Mizugumo and NinjaScript have some limitations. Notably, in this version they will clobber the normal rails.js and prevent its behaviors from working. The installer will copy a jQuery-compatible version of rails.js that you should use instead if you depend on Rails’ default (semi-obtrusive) approaches to AJAX, link_to with :confirm =>‘Are you sure?’ and similar things working.
Mizugumo’s main features are:
-
Easy tools for installing NinjaScript
-
A Rails helper to automatically output <form>s instead of <a> tags when link_to is called with a :method other than GET. This allows these links to function as intended for users who lack JavaScript.
-
A default NinjaScript behavior (in your application.js) that automatically converts those forms back into the expected links when JavaScript is available, resulting in transparent usability for JS users.
-
A scaffold generator that builds both both AJAX behavior and standard “page-reload” behavior in the controller and view and adds NinjaScript behaviors to application.js to activate AJAX. Out of the box, your scaffolded controller will function as an AJAX controller when JS is available but will degrade properly when JS is not available.
Mizugumo is compatible with Rails >= 3.0.0. We have not tested it with any prior versions of Rails. If you use it with an earlier Rails and it works, let us know!
First, add Mizugumo to your gemfile:
gem 'mizugumo'
Second, install Mizugumo files:
rails generate mizugumo:install
The next step depends on whether you are running Rails 3.0.x or 3.1.x.
For 3.0.x, mizugumo will assume you are putting most of your application javascript code in public/javascripts/application.js. The installer will have created a Ninja.orders() block in which to place Ninjascript behavior. The last line of this block will be Ninja.go(), and that must remain the last line.
You will need to link to jQuery and NinjaScript in your application layout, and you may include the optional mizugumo.css. (a SASS version is installed to public/stylesheets/sass/mizugumo.sass).
Add these lines to your layout (in ERB):
<%= javascript_include_tag 'jquery-1.6.4.js' %> <%= javascript_include_tag 'jquery.ninja_script.js' %> <%= javascript_include_tag 'application.js' %> <%= stylesheet_link_tag 'mizugumo' %>
If using Haml, add these instead:
= javascript_include_tag 'jquery-1.6.4.js' = javascript_include_tag 'jquery.ninja_script.js' = javascript_include_tag 'application.js' = stylesheet_link_tag 'mizugumo'
NOTE: If you still have javascript_include_tag :defaults, you probably want to remove it. Ninjascript is meant to work with jQuery, and we don’t know what happens if you try to run it side-by-side with Prototype.
For 3.1.x, mizugumo uses the rails asset packager, so there is less for you to do. ninjascript.js, mizugumo.js, and a file called ninja_go.js are added to your app/assets/javascripts directory, and lines are added to you manifest (app/assets/javascripts/application.js) to ensure that they are loaded in the right order.
Rails’ concept of REST runs headlong into the desire to make a site degrade gracefully. Specifically, the link_to() helper, when passed a method other than ‘get’, outputs a link with a data-method attribute that won’t work when JS is absent. To wit: link_to(‘Delete Item’, @item, :method => ‘delete’) in Rails outputs this:
<a href='/items/1' data-method='delete'>Delete Item</a>
When JS isn’t available, this delete link acts as a show link. This is bad, bad, bad. What’s worse, Rails’ scaffold generator makes these exact links ubiquitous.
When Mizugumo is installed, that same helper instead outputs this:
<form action='/items/1' class="mizugumo_graceful_form"> <input type='hidden' name='_method' value='delete'> <input type='submit' value='Delete Item'> </form>
This gives the user a button instead of a form … but it works without JS running. Then, to give JS users the behavior the developer intended, Mizugumo appends this to your application.js:
Ninja.behavior({ '.mizugumo_graceful_form': Ninja.becomesLink })
This NinjaScript behavior converts that form back into a link. The JS user sees no difference whatsoever, but the link at least works for the non-JS user.
This behavior will work for :method => ‘put’ and :method => ‘post’ as well, and it supports links whose content is an image as well; creating an image submit button in the form rather than a text submit button.
WARNING: This cycle won’t work if your link has complex content with html structure; for example if you write
link_to('some <b>content</b><img src="foo">and text', @item, :method => 'delete' )
Mizugomo will not be able to preserve all that content through the degraded form. However, we think this is a rare case. If you aren’t passing :method to your link_to, mizugumo will ignore it entirely, so you can still create complex GET links.
Mizugumo ships with a scaffold generator that builds out-of-the-box AJAX/UJS scaffolds that degrade gracefully in the absence of JavaScript. To use it, add this to config/application.rb:
For ERB views:
config.generators do |g| g.scaffold_controller 'mizugumo:scaffold_controller' g.template_engine 'mizugumo:erb' g.assets 'mizugumo:js_assets' # Only needed for Rails 3.1, omit for Rails 3.0 end
For Haml views:
config.generators do |g| g.scaffold_controller 'mizugumo:scaffold_controller' g.template_engine 'mizugumo:haml' g.assets 'mizugumo:js_assets' # Only needed for Rails 3.1, omit for Rails 3.0 end
Run the scaffold generator as you would with any other Rails app. Mizugumo will generate both HTML views (in ERB or HAML), and JavaScript views (action.js.rb) for the actions in each controller, and will generate the NinjaScript code to allow your scaffold to function as an AJAX scaffold when Javascript is available.
In Rails 3.0, the NinjaScript code is injected into public/javascripts/application.js, inside the Ninja.orders() block created by the installer. In Rails 3.1, a new file with the code is created in app/assets/javascripts/<controller_name>.js.
NinjaScript’s development is modularized using the RequireJS library. One unfortunate side effect of RequireJS is that modules get loaded asynchronously, and so even if a file is required first, its code is not guaranteed to be available when you load a subsjquent file. So, if you required NinjaScript.js, and then began defining Ninja behaviors like so:
Ninja.behavior({ 'selector': Ninja.someCoolBehavior } )
It is possible that Ninja’s behaviors are not fully loaded, because RequireJS hasn’t finished loading them. Boo! So, Ninja.orders() is defined so to queue up all commands (behaviors and the “go”) command, so that they will get executed as soon as NinjaScript has finished loading.
-
Install MizugumoDemo and make sure that its tests still pass with your version of Mizugumo!
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
-
Fork the project
-
Start a feature/bugfix branch
-
Commit and push until you are happy with your contribution
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Use the GitHub issue tracker.
Copyright © 2011 Evan Dorn and Logical Reality Design. See LICENSE.txt for further details.
NinjaScript is copyright © 2011 Judson Lester and Logical Reality Design.
Web Development by Logical Reality Design: LRDesign.com