watch this  

the official mrchucho blog

Rails and Templating

Posted 2005 Feb 14

There is a good post on Loud Thinking regarding Rails and its lack of a “templating” language.. which was one of my inital - I hate to use the word - complaints.

While I think that Ruby is certainly much better suited for co-existing inside the View than Java, I still think the approach that Tapestry uses (or even JSF) is preferable. It provides a nice decoupling in addition to helping during the prototyping phase. Of course, in most of my projects thus far, I’ve worn both the developer and designer hat—so I can’t speak to 37 signals’ workflow.

I stand by my claim that the less code in the HTML-portion of the View, the better—regardless of how readable the code is.

Update Read below for more thoughts on this—I tried to post this as a response the comments, but the HTML formatting was just too screwy…

When I think templating, I think of Tapestry, so here goes: Let’s say I have a table that I want to populate. During the prototyping phase, I create the HTML for the table in put in some mock-up data:
<pre><code>Employees.html
<table id="employees" jwcid="employees">
    <tr><th>Id</th><th>Name</th><th>Position</th></tr>
    <tr>
        <td>123</td><td>Joe Smith</td><td>Programmer</td>
    </tr>
    <tr>
        <td>456</td><td>Bob Jones</td><td>Designer</td>
    </tr>
</table>
</code>
So far, it’s all HTML - no code. The only thing that stands out is the “jwcid” attribute - that’s what ties the HTML table to the implementation. Now, in Tapestry, there’s a page specification that corresponds to the HTML page:
<pre><code>Employee.page
<component id="employee" type="contrib:Table">
    <binding name="source" expression="employeeList"></binding>
    <binding name="columns" expression="id,name,position"></binding>
</component>
</code>
In the Java code behind the page is a function, “getEmployeeList” that returns a collection of Employee models. The page, in turn, knows to use the id, name and position properties for the columns of the table. That’s it! And, we can leave the mockup data in place—everything between the opening and closing table tags is replaced at run-time.

Of course, this is a high-level explanation, but as you can see: there’s no code in the HTML and the View code itself just returns a List, it’s not concerned with how it is displayed, e.g. table or list or just a bunch of paragraphs! That’s pretty good decoupling! And it’s great during the prototype phase because you can tweak the layout (including mock-up data) outside of the application server and/or using WYSIWYG tool. And, even better, no major modification is necessary when the time comes to “wire” it up.

Lastly, to demonstrate your Rails example:
<pre><code>< % if @user.is_administrator? %>
  # show stuff that's only for administrators
< % end %>
</></></code>
In Tapestry:
<pre><code>.html
<div jwcid="adminStuff">
stuff for admins only
</div>
.page
<component id="adminStuff" type="Conditional">
     <binding name="condition" expression="isAdmin"></binding>
</component></code>
This is different from templating technologies like JSP or Velocity and is probably more akin to Perl’s HTML::Template.

Responses to "Rails and Templating"

David Heinemeier Hansson

2005 Feb 14 at 21:55

I think you’re missing the point of the post. The main point is that even if your logic looks like HTML tags, it’s still code. It’s still conditionals and loops.

Also, could you explain what decoupling a tag-based template language gives you? And in what way it helps you during the prototype phase? (I’m really interested, not just playing annoying ;)).

MrChucho

2005 Feb 15 at 03:17

I replied to your comment - at length :) - as an update to this post. I’d hoped the formatting would turn out better, but it still leaves something to be desired…

David Heinemeier Hansson

2005 Feb 15 at 11:30

Thanks for the clarification. It seems there are multiple desires in the Amrita-style camp. Some that prefer that the conditionals and loops are merely described on the tags themselves and some that like you want to merely tag it with an id and then do the logic elsewhere.

I must admit that the component/binding setup appears incredibly unattractive to me (the recent comments on the blog posting explains some of why), but obviously its very attractive to some. I’ll work harder to understand why.

Comments are now closed.
atom rss