Tutorial, Part 2

The next thing we’re going to do is create a view to display a list of blog entries. The first thing to do is simply create a template directory for entry-related views. On Unix, simply do:

~/blog $ mkdir templates/entry

Next, edit the file list.mab in the templates/entry directory. The “mab” extension is for Markaby templates. Waves supports both Markaby and Erubis templates (and you can easily add others), but we’re going to use Markaby for this particular template.

layout :default, :title => 'Blog Entries' do
  h1 'My Blog'
  @entries.each do |entry|
    view :entry, :summary, :entry => entry
  end
end

A few highlights of the techniques we’re using here:

Now, we have to go ahead and define the view we’ve invoked, so let’s do that. This time, we’ll edit the summary.mab file in templates/entry.

h2 do
  a @entry.title, :href => "/entry/#{@entry.name}" 
end
textile @entry.summary
a 'Read more ...', :href => "/entry/#{@entry.name}" 

Here we’ve used the built-in support for Textile formatting. The rest is pretty self-explanatory. You might be wondering about a few things, but let’s go ahead and start our application and see our new view.

~/blog $ waves-server
I, [2008-01-28T11:01:19.945459 #3755]  INFO -- : ** Waves Server Starting ...
I, [2008-01-28T11:01:20.059007 #3755]  INFO -- : ** Waves Server Running on 127.0.0.1:3000
I, [2008-01-28T11:01:20.059482 #3755]  INFO -- : Server started in 30 ms.

Now open your browser and go to the url ‘http://localhost:3000/entries’. You should see something that looks like this:

Let’s add a view for viewing the entire entry. This will look a lot like our summary entry. We’ll put it in the show.mab template:

layout :default, :title => @entry.title do
  h1 @entry.title
  textile @entry.content
end

Now let’s click on the “Read more …” link and see how it looks.

There we go! It’s worth pointing out that we haven’t yet needed to write a line of controller or model code. So far, Waves has been able to infer what we wanted by following a couple of simple conventions.

These conventions can be easily customized, but we’re getting ahead of ourselves a bit. We still don’t have a way to add a new entry. So let’s add a little form to the top of our list template. So now it will look like this:

layout :default, :title => 'Blog Entries' do
  h1 'My Blog'
  form :action => '/entries', :method => 'post' do
    label 'Name'
    input :type => :text, :name => 'entry.name'
    input :type => :submit, :value => 'Add'
  end
  @entries.each do |entry|
    view :entry, :summary, :entry => entry
  end
end

We’re following a REST-style interface here, using the same URL to add a new entry as we do to obtain a list of all entries. The difference is simply the method used in the request. To add a new entry, we use a POST. This says, create a new resource at the URL /entries. Which is exactly what will happen.

We still have to add another view to edit the entry we’ve created. Simple enough. Let’s call it editor.mab:

layout :default, :title => 'Edit Entry' do
  form :action => "/entry/#{@entry.name}/", :method => 'POST' do
    # fake an HTTP PUT
    input :name => '_method', :type => 'hidden', :value => 'put'
    label 'Title'; br
    input :type => :text, :value => @entry.title, :name => 'entry.title'; br
    label 'Summary'; br
    textarea @entry.summary, :name => 'entry.summary', :rows => 10, :cols => 80; br
    label 'Content'; br
    textarea @entry.content, :name => 'entry.content', :rows => 20, :cols => 80; br
    input :type => :submit, :value => 'Save'
  end
end

Now let’s add an entry using the form on our /entries page and then edit it. Let’s call this new entry ‘second-entry.’

Click save and you should now see the new entry displayed in the browser.

We still haven’t needed to create a model or controller. In Part 3 of our tutorial, we’ll take a look at what’s going on behind the scenes.