Now, if you’ve been following this series of blogs so far you’ll have set up a neat little Rails development environment and created your first application–a little micro-blog that lets you add, show, edit and delete short posts. What we’re going to do as part of this blog is add some styling and formatting using layouts, view files and CSS. So, fire up Aptana and we’ll get started.
Remember, you can view the final application at http://gabber.d13design.co.uk/gabber/public/posts.
Editing the core markup
If you click in your project tree and open the “app/views” folder you’ll see that the scaffold we used in part 1 has automatically created a number of files for us:
>views
>layouts
>posts.html.erb
>posts
>edit.html.erb
>index.html.erb
>new.html.erb
>show.html.erb
First we’ll look at the file that’s been created in the “layouts” folder. A layout file, in this case “posts.html.erb”*, is kind of like a master template that defines how all pages are displayed. If you want every page within your application to conform to a template you can create an “application.html.erb” file. In this instance the layout will apply to all pages within “posts”. Open the file and we’ll examine its contents.
*Incidentally, I believe the “.html.erb” extension is specific to Rails v2 so, if you’re using an older version of rails your files may all have the “.rhtml” extension.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Posts: <%= controller.action_name %></title>
<%= stylesheet_link_tag 'scaffold' %>
</head>
<body>
<p style="color: green"><%= flash[:notice] %></p>
<%= yield %>
</body>
</html>
If we look at this template file you’ll see that it all looks pretty standard, until you get to the title tag. We can see that there’s a bit of rails code here setting the title to use a dynamic value–the action name of the current controller. This helps set the page title to something like “Posts: new”. On the next line you’ll see just how easy Rails makes it to create pages–this line of code adds all the html for embedding a stylesheet by the name of “scaffold.css”.
When we move down to the body we’ll see that there’s a paragraph of green text that will display any notices and another bit of rails code “<%= yield %>”–this is a marker to indicate where the content for each action will be displayed.
We can start to edit this template to add a title, some basic layout and a link to a better stylesheet. You should end up with a template like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Posts: <%= controller.action_name %></title>
<%= stylesheet_link_tag 'gabber' %>
</head>
<body>
<div id="header">
<h1>Gabber</h1>
<h2>A collaborative micro-blog</h2>
</div>
<div id="contents">
<div id="flashnotice">
<p><%= flash[:notice] %></p>
</div>
<div id="messages">
<%= yield %>
</div>
</div>
</body>
</html>
So now we have the main template HTML constructed we can start to create some styles. Create a new stylesheet (CSS file) in “public/stylesheets” and call it “gabber.css”. Add the following CSS and save the file (if you’d like to follow this tutorial to-the-letter then click here to download all of the image assets I used and save them into the “stylesheets” folder in your application).
Download Gabber files
body {
padding:20px;
background-color:#9cf;
background-image:url(body_bg.gif);
background-position:bottom right;
background-repeat:no-repeat;
font-family:"Palatino",Georgia,"Times New Roman",Times,serif;
color:#000;
}
div#header {
width:450px;
border:3px solid #fff;
padding:10px;
margin:0px auto;
background-image:url(header_bg.gif);
}
div#header h1 {
color:#fff;
font-size:46px;
text-align:right;
margin:4px;
}
div#header h2 {
color:#fff;
font-size:22px;
font-style:italic;
font-weight:normal;
text-align:right;
margin:4px;
}
div#contents {
width:456px;
padding:10px;
margin:10px auto;
}
Once you’ve saved your template file and CSS, refresh or run your application and you should see something like this.

Refining the homepage
So, we’ve now got a nice header and general layout applied to our application and it’s now time to refine how the homepage looks. As we want to edit the “index” of the “posts” directory, the view file we need to load is “app/views/posts/index.html.erb”. By opening this file you’ll see that, by default, the posts are being displayed in a table. Because our application is so simple I’ve removed this and re-jigged the markup to the following.
<% for post in @posts %> <div class="post"> <p><strong><%=h post.poster %> says</strong> “<%=h post.title %>”</p> <p class="postmeta"><%= link_to 'show', post %> | <%= link_to 'edit', edit_post_path(post) %> | <%= link_to 'delete', post, :confirm => 'Are you sure?', :method => :delete %></p> </div> <div class="clear"> </div> <% end %> <br /> <%= link_to 'New post', new_post_path %>
You should be able to tell quite easily what each snippet of Rails code is doing and you should, by refreshing your browser, get something like this:

Next, we’ll update our “gabber.css” file to include styles for the new elements we’ve added. Add the following to the end of the stylesheet and refresh your browser.
div.clear {
clear:both;
}
div.post {
background-color:#ff9;
background-image:url(post_bg.gif);
background-position:top left;
background-repeat:no-repeat;
padding:0px;
margin:0px;
height:100px;
}
div.post p {
margin:8px 8px 8px 100px;
padding:8px;
font-size:16px;
}
div.post p.postmeta {
font-size:12px;
text-align:right;
}
div.post a {
color:#333;
text-decoration:none;
}
div.post a:hover {
color:#000;
text-decoration:underline;
}

Changing the order of the page
If you’ve got more than one post on your micro-blog you’ll realise that the most recent posts are appearing at the bottom of the list–we want them at the top, just like Twitter. We can do this really easily by editing the posts controller (app/controllers/posts_controller.rb).
Look for where the “index” action is defined and you’ll see some code like this:
def index
@posts = Post.find(:all)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
end
end
You can see that one of the first lines is set to find all posts using the Post model. We can adjust this so that it finds all posts in reverse order.
@posts = Post.find(:all).reverse
Done, save the file and refresh the browser–you should now see your posts showing with the most recent first.
As well as reversing the order, I want to add a date stamp to each message (remember we added this to the Post model?). To this I’ll edit the “app/views/posts/index.html.erb” file and add the following line of code into the postmeta p tag:
<%=h post.created_at %>
I’ve also decided that I don’t want people to view, edit or delete posts so, for now, I’ll comment these links out of the html.
<p class="postmeta">posted <%=h post.created_at %><!--<%= link_to 'show', post %> | <%= link_to 'edit', edit_post_path(post) %> | <%= link_to 'delete', post, :confirm => 'Are you sure?', :method => :delete %>--></p>

Simplifying the user experience
Okay, so the micro-blog is running pretty well but the process of adding new posts is a bit of a pain:
- Click on “create new post”
- Create post
- Click to “submit post”
- View success response
- Click “back” to see the new post in the list
What we can do now is play about with the view files a little more and add the “create” form straight into the main page (just like twitter). We’ll also take it all a step further and look at using AJAX to add posts straight into the pile.
First, load up the view file for creating a new post (app/views/posts/new.html.erb) and copy all of the form code into your index view where you want the form to appear. This gives you an “index.html.erb” file like this:
<% form_for(@post) do |f| %> <p><b>Title</b> <%= f.text_field :title %></p> <p><b>Poster</b> <%= f.text_field :poster %></p> <p><%= f.submit "Create" %></p> <% end %> <hr/> <% for post in @posts %> <div class="post"> <p><strong><%=h post.poster %> says</strong> “<%=h post.title %>”</p> <p class="postmeta">posted <%=h post.created_at %></p> </div> <div class="clear"> </div> <% end %> <br /> <%= link_to 'New post', new_post_path %>
Now, if you try and run this you’ll get an error because this view doesn’t have a clue what “@post” is yet–we need to add this into our controller because the form is built specifically around the idea of creating a “post”. Open the “posts_controller.rb” file and make sure that the “index” definition looks like this:
def index
@post = Post.new
@posts = Post.find(:all).reverse
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
end
end
Save all your files and refresh your browser and you’ll see the form dropped into your index page. Also, now that the form is sat on your index page you can remove the “new post” link from the bottom of the index view. Add a bit more markup and styling and you’ll end up with an index page like this:

You’ll now notice that when you create a new post you’re taken, as before, to the screen showing your new post with a success message. What we ideally want is for the message to add itself straight to the top of the list. We’ll do this using AJAX.
When you create a new Rails application, the prototype (http://www.prototypejs.org/) Javascript libraries are added automatically. All we have to do is embed them into our layout file using the following code within the head (next to where the stylesheet tags are):
<%= javascript_include_tag :defaults %>
What we’re going to do now is set the page to update the entire stack of posts when a new one is added. To make sure this happens we need to wrap all of our posts (and new post form) in a DIV with a specific ID. We’ll do this in the index view file around the entire contents:
<div id="posts">
<div id="newpostform">
......
<div class="clear"> </div>
<% end %>
</div>
Next we need to update our “create new” form to make sure it’s set to use AJAX. To do this we need to re-write the form at the top of the index view file:
<div id="newpostform">
<h3>Create a new post</h3>
<%= form_remote_tag :url => {:action => 'create'}, :update => 'posts' %>
<p><b>Your message</b> <%= text_field_tag 'post[title]' %></p>
<p><b>Your name</b> <%= text_field_tag 'post[poster]' %></p>
<p><%= submit_tag 'Create' %></p>
</form>
</div>
Note the use of “form_remote_tag” rather than “form_tag”–that’s all you need to do to create an Ajax form! If you save and run your application you’ll now see that Ajax is doing its’ thing and your post stack is refreshing right before your eyes but, you’ll also notice, that the wrong HTML is being called into the “posts” div. We’ll now look at editing the create action (and its’ view files) to resolve this.
Open your posts controller and add in an extra line of code at the top of the file:
class PostsController < ApplicationController layout "posts", :except => :create
This tells your controller that the layout file to use for the controller is the “posts” layout except when dealing with the “create” action. Next, we need to adapt the “create” action so that it returns the correct HTML for updating our DIV. Scroll down to where the “create” action is defined and adjust it so that it looks like this:
def create
@post = Post.new(params[:post])
respond_to do |format|
if @post.save
@post = Post.new
@posts = Post.find(:all).reverse
format.html { render :action => "index" }
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end
What this code does is create a new post (using the Post model) giving it the parameters sent by our form. Next we have a little check–was the post saved correctly?
If the save is successful we do a similar kind of thing to our main index action, get the details for creating a form and get all previous posts in reverse order, we then use the index view to format the output.
If the save fails (which it won’t because we have no validation) we redirect to the “new” view and pass it some error messages to display.
Save all your files and run your application–you should now be able to add posts directly into the stack using Ajax.

Next we’ll add even more function to the application in the way of commenting and custom avatars!