Kiss A simpler, smarter web application framework for Ruby

Templates

SECTIONS
Template Formats Where to Store Templates Basic Syntax Conditional Branches Loops Partial Templates Invoking Other Actions Linking to Other Actions

Template Formats

Most templates in web applications will be HTML. You should name your HTML templates with a .rhtml extension, which stands for Ruby HTML.

However, you can use other extensions for other formats, such as .xml (for XML data services) and .txt (for comma- or tab-delimited text). If you want to render to a format other than HTML, be sure to specify the extension to Kiss in one of three ways:

# in your action code
@extension = 'xml'

# or by calling render from your action code
render :extension => 'xml'

# or by including the extension in your request URL
http://localhost:4000/user/71279492/view_data.xml

Where to Store Templates

Like other MVC frameworks, Kiss is all about separating from business logic from presentation. But we don't think they actually need to be stored in separate places. It's quite common for a single developer to work on the business logic and the presentation layer. We think those belong in different files, business logic in pure Ruby, and presentation in Ruby-embedded HTML. We just don't think it makes a lot of sense to put those two files in different places, making the developer go hunting to find the template for an action, or to jump back and forth between them to make incremental improvements.

So we think you should put your templates in your actions directory, and we've made that the default behavior. Here's what that looks like:

actions/
  _action.rb
  _layout.rhtml
  index.rb
  index.rhtml
  login.rb
  login.rhtml
  logout.rb
  register.rb
  register.rhtml
...

It's pretty easy to tell the actions from the templates by looking at the file extension. Some editors including TextMate even give them different icons. If you're working on an action, or a template, the other corresponding file is easy to find; it'll be right next to the one you're editing. We think you'll like it.

But maybe you really want them to be separate. Maybe you have a separate team of web designers for doing the presentation layer, and you don't want to give them access to your action files. Or maybe you just got used to having a separate templates directory in Rails and really, really want it that way. No worries. Just create a directory named templates in your application directory, and add this line to your config/common.yml file:

:template_dir: templates

With that, you're all set to put your templates in the templates directory.

Note: There's another kind of template used for composing email messages, and they go in a different place. But we'll talk about that later.

Basic Syntax

Inserting Values From Ruby Expressions

Templates are just text files (typically HTML) with embedded Ruby commands. Here's an example:

<div class="name">
    <%= data.user.first_name %> <%= data.user.last_name %>
</div>

The <%= ... %> tag inserts the result of the Ruby expression inside.

To get data into our template, we have to export it from our action code. We described this in the Actions chapter, but here's a quick refresher:

# use the set method
set :color => 'red'

# or directly touch the data hash
data.color = 'red'

Basic Ruby Logic

We can also execute Ruby logic inside templates without inserting the result in-place, with the <% ... %> tag (with no =). For example:

<ol>
<% for user in data.users %>
  <li><%= user.first_name</li>
<% end %>
</ol>

You should keep the business logic of your application in your action and model code. But you can use basic logic statements to add control flow to your template, as shown below.

Conditional Branches

if ... else

<% if data.user.state == 'MI' %>
  Prices do not include 6% Michigan sales tax.
<% else %>
  No sales tax added for customers outside Michigan.
<% end %>

case

<% case data.color
when 'red' %>
  People who like red are vibrant, creative, and passionate.
<% when 'blue' %>
  People who like blue are dependable and caring.
<% else %>
  Do you really believe your favorite color means anything?
<% end %>

Loops

for ... in

When inside a for loop in a Kiss template, you can access an iterator object to get information about the loop. The iterator variable is named with a _loop suffix, as shown here:

<% for user in data.users %>
  <td><%= user_loop.count %></td>
  <td><%= user.first_name %> <%= user.last_name %></td>
<% end %>

The iterator object is based on the loop iterator in Perl's Template Toolkit by Andy Wardley. The available methods are:

while 

Here we use a while loop to traverse a linked list:

<% while list_node %>
    <%= list_node.value %><br/>
    <% list_node = list_node.next %>
<% end %>

Partial Templates

Partial templates (sometimes called simply "partials") are stored in the same directory as templates. You should name each partial template file with a leading slash, as this prevents Kiss from serving the file directly in response to an HTTP request. (Action names must start with a letter, and users are not allowed to make requests to template names that start with an underscore.)

insert

The insert method inserts a file in place, raw, without processing any embedded Ruby:

<%= insert('_store_policies.html') %>

process

The insert method process the specified file to interpret any embedded Ruby, and inserts the result in-place:

<%= process('_user_info_partial.rhtml') %>

You can also pass in additional values for the partial template's data hash:

<%= process('_user_info_partial.rhtml'), :data => { :user_id => data.user.id } %>

Invoking Other Actions

You can also execute business logic from another action and insert the result in-place in a template, using the invoke method:

<%= invoke('/item/' + item_number + '/add_to_cart', :params => [ :quantity => 1 ] %>

In the above example, we called the /item/add_to_cart action, with an embedded argument item_number, and a quantity parameter of 1.

Linking to Other Actions

To allow the user to navigate from one page to another, you'll need to add links to your template. If the target action is in the same directory as the current (origin) action, then you can use the target action's short name:

<a href="edit">Edit Item Data</a>
<a href="delete">Delete This Item</a>

You can specify a relative path to go deeper or higher in the actions hierarchy:

<a href="../customers/list">Customers</a>

Or you can specify an absolute URL by starting with the app keyword, which gives the root URL of your application:

<a href="<%= app %>/logout">Sign Out</a>