Easily Maintainable & Designer-friendly ActionView Templates using MasterView & Liquid
Author: ceefour | Filed under: Beginner, HTML, Praises, Rails, Ruby, Tips, Web 2.0MasterView is a Rails plugin which allows to you design your layouts, templates, and partials easier: by editing them in one master template, and displaying them inline in other templates. Liquid is a template engine which have a more designer-friendly syntax, and is “safe” meaning that the template does not automatically have access to potentially dangerous functions. You can use both in the same Rails project, and they may make your Rails life much easier.
Note: I’ve been wanting to write this article for weeks, I hope I really can make it this time. I don’t want to be fully wordy as before, I’ll try to talk less this time.
Here’s our sample final output: (randomly taken from a template sample, I hope I won’t get a lawsuit for this)
Let’s get Liquid, from your Rails app directory:
cd vendor/plugins
svn export svn://home.leetsoft.com/liquid/trunk/liquid
To get the first fun, we’ll have to create our main controller, from your Rails app directory:
script/generate controller Main
We want to build the product list on the right, without layout yet. I’m not in the mood for test-driving development right now, so let’s just build the controller in app/controllers/main_controller.rb :
class MainController < ApplicationController
def index @products = [ {'title' => 'COMPAQ Armada 110', 'desc' => 'C-700, 12.1TFT, 64MB, 10GB, 24X, 56K, WME.', 'price' => '$835', 'img' => '/images/product_01.gif'}, {'title' => 'SONY VAIO - FX390K', 'desc' => 'PIII 1GB, 256MB, 30GB HD DVD-CDRW, 15.1TFT, 10/100, 56K, Win 2000,', 'price' => '$1,950', 'img' => '/images/product_02.gif'}, {'title' => 'Toshiba', 'desc' => 'C-700, 12.1TFT, 64MB, 10GB, 24X, 56K, WME.', 'price' => '$835', 'img' => '/images/product_01.gif'}, {'title' => 'Lenovo', 'desc' => 'PIII 1GB, 256MB, 30GB HD DVD-CDRW, 15.1TFT, 10/100, 56K, Win 2000,', 'price' => '$1,950', 'img' => '/images/product_02.gif'} ] render :partial => 'main/top_offers' end
end
Okay, we’ll also need the partial view in app/views/_top_offers.liquid :
<img src="/images/top_offers.gif" width="108" height="16"><br>
{% for product in products %} <img src="/images/line_02.gif" width="300" height="22"><br> <table width="300" border="0" cellspacing="0" cellpadding="0"> <tr valign="top"> <td width="130"><img src="{{product.img}}" width="117" height="90"></td> <td><font size="1" face="Verdana, Arial, Helvetica, sans-serif"><b>{{product.title}}</b><br> {{product.desc}}<br> <b><br> PRICE: <font color="#FF0000">{{product.price}}<br> <br> <a href="#" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image33','','/images/btn_buy_over.gif',1)"><img name="Image33" border="0" src="/images/btn_buy.gif" width="56" height="16"></a> </font></b></font></td> </tr> </table>{% endfor %}
As you can see Liquid syntax is pretty clean. Let’s see what this does:
To continue, let’s install MasterView, it’s very easy:
gem install -y masterview_gem_pack
After you create your Rails application, install the MasterView plugin:
script/generate masterview_plugin
Now you’re set. To verify your MasterView installation, you can point your browser to http://localhost:3000/masterview/ to open the MasterView Admin page.
UPDATE: By default the Admin page is enable in development mode and is only accessible by localhost, but this is configurable.
But I just want to get in quickly, let’s create the layout. MasterView’s way of writing templates and layouts is very different than Rails. You define the layout, template, and partials in one template file, and other templates that use the layout and partials should “import” the required templates. This can be a bit confusing at first, so let’s get to a concrete example.
Let’s create a MasterView template in app/views/dummy.html. Note that MasterView templates in .html, so it should be directly usable without configuration from any visual HTML such as Dreamweaver, Nvu, or Quanta. (on second thought, Nvu is too restrictive, and will rewrite the HTML mercilessly so it’s quite hard to use it to write MasterView templates, let alone eRuby templates!)
The one thing to notice from the above template is that the “html” element has a “mv:generate” attribute, that contains the generated layout filename. Note that by default, this file will be generated virtually, i.e., it will not exist on the filesystem but MasterView will make sure Rails will be able to use it.
For this layout I decided to have two different regions, the main content region on the left/center and the sidebar region on the right. The part of template code for that is this:
It still uses mv:generate attribute, this time to mark the content. The {{{}}} syntax is special to MasterView that enhances eRB so you can use embedded Ruby inside HTML templates. The second region is handled using content_for, so we don’t write an additional template for that.
We also need to modify our main_controller.rb :
class MainController < ApplicationController layout 'default'
def index @products = [ {'title' => 'COMPAQ Armada 110', 'desc' => 'C-700, 12.1TFT, 64MB, 10GB, 24X, 56K, WME.', 'price' => '$835', 'img' => '/images/product_01.gif'}, {'title' => 'SONY VAIO - FX390K', 'desc' => 'PIII 1GB, 256MB, 30GB HD DVD-CDRW, 15.1TFT, 10/100, 56K, Win 2000,', 'price' => '$1,950', 'img' => '/images/product_02.gif'}, {'title' => 'Toshiba', 'desc' => 'C-700, 12.1TFT, 64MB, 10GB, 24X, 56K, WME.', 'price' => '$835', 'img' => '/images/product_01.gif'}, {'title' => 'Lenovo', 'desc' => 'PIII 1GB, 256MB, 30GB HD DVD-CDRW, 15.1TFT, 10/100, 56K, Win 2000,', 'price' => '$1,950', 'img' => '/images/product_02.gif'} ] end
def dummy end
end
Didn’t change much, did it? The only changes were: layout was set, index action now renders the default view instead of rendering a partial, and added “dummy” action. Let’s see our dummy page with layout:
Alright, now we need to write the main index template in app/views/index.html :
<html mv:import="layouts/default.rhtml">
<div mv:generate="main/index.rhtml">
<h1>Cool!</h1><p>MasterView is great. And Liquid is too!</p>
{{{content_for :sidebar do}}} {{{= render :partial => 'main/top_offers'}}}{{{end}}}
</div>
</html>
Very short, huh? But this is actually all we need, although it’s not “proper” yet because it’s not in sync with the actual layout. To make visual designing easier, we should update this template (although MasterView will still work properly if you don’t). Open up the MasterView admin at http://localhost:3000/masterview/ and you’ll see that this template needs rebuilding:
By clicking “Rebuild”, the template will be updated with the original layout. At this point, opening http://localhost:3000/main/ will render the following, as seen in the first screenshot of this article:
Well, it’s done!
Conclusion
This article demonstrates the following:
- MasterView can be used to make maintenance and designing of Rails ActionView templates easier
- Liquid has prettier syntax than eRB (among other functions), non-evaling (“safe”), and works well with MasterView
- You can mix MasterView-generated templates and physical filesystem templates (the sidebar in this example just reused the Liquid template we had created before)
- MasterView has a user-friendly Admin interface that makes managing MasterView templates very easy
- Using either or both tools properly in your Rails application will boost your productivity and increase your enjoyment of developing Rails applications
Technorati : actionview, liquid, masterview, rails, ruby, rubyonrails, template, templates, web, web 2.0, web2, web2.0, wysiwyg
Del.icio.us : actionview, liquid, masterview, rails, ruby, rubyonrails, template, templates, web, web 2.0, web2, web2.0, wysiwyg
Related posts:
- How to Use ActionView Helpers in Your Rails Controller Sometimes when developing a Ruby on Rails web application,...
Related posts brought to you by Yet Another Related Posts Plugin.