Table of Contents

View Screencast (Quicktime)
Right-click and choose Save As to save file to your computer


Sign Up Now!

If you aren’t already receiving our course lessons via email, sign up now to be sure you don’t miss anything.

Every few days, we’ll send you an email with a link to the next episode, plus a list of additional resources for advancing your knowledge.

There’s no cost and no obligation. And we’ll never share your email address with any third party.


We’ll send you the first lesson right away.


Want to help spread the word? We’d be grateful if you would include a link to the course in your blog, web site, or emails.

Clean-Up

14 comments

Goals

In this lesson we’re taking a break from adding features to do a little cleanup:

  • Get the page title logic out of the application layout
  • Add page titles for admin and login pages
  • Make navigation buttons indicate which is the current page
  • Add a ‘back to previous’ navigation link on subpages
  • Add a little styling to subnav links
  • Set the focus for the login field

Please note that, while we’ve tried to make these notes complete, they aren’t the full tutorial; that’s in the screencast, which you can access via the link on the left.

Setup

We begin with the code with which we ended Lesson 15. These zip files contain the beginning and ending states of the code:

Fix up Page Title Handling

Several lessons ago, as we were building the core of our content management system, we put a quick hack in the application layout (views/layouts/application.html.erb) that put this logic in the wrong place; we want to keep logic out of our views as much as practical. So let’s replace this line:

<title><%= @pagetitle || (@page && @page.title) || 'Learning Rails Sample Application' %></title>

with the much simpler:

<title><%= @pagetitle %></title>

Now we need to set this instance variable appropriately for each view. First, in the viewer_controller show method, insert the line (after @page is set):

@pagetitle = @page.title

That takes care of all pages that come from the content management system. Now we need to take care of the admin and login pages. Add to users_controller:

before_filter :set_pagetitle

def set_pagetitle
  @pagetitle = 'User Administration'
end

This before filter will run before every action, so the page title will be set (to the same thing) for all of them.

In page controller, we already made a very similar addition in a previous lesson, but we called it set_metadata, so for consistency we’ll rename it to set_pagetitle

Finally, the sessions controller needs some attention. Add to the (empty) new action in sessions_controller:

@pagetitle = 'Please Log In'

And after the else in the sessions_controller’s create method:

@pagetitle = "Login was not successful"

You could do more to customize page titles for the various admin pages, but this is enough for us.

Highlight Current Nav Button

Next problem: make the appropriate nav button highlight to indicate the current page.

First, we need to identify which nav button to highlight by using some Ruby code to conditionally insert an ID. We’ll insert the following code in the application layout, in the <li> tag that begins each nav button:

<li <%= "id = 'current'" if @page && @page == page %>>

Now we need a CSS rule, in public/stylesheets/learningrails.css, to style the button for the current page:

#navbar #current a {
    background-color: #000; 
}

Now the navigation button for the current page is highlighted.

Provide a Link Back to Parent Page

When we added subpages in the previous lesson, we didn’t provide any indication when you’re on a subpage as to what the parent page is. There’s several things we might do about this; here’s two possibilities:

We could use the subnav div area to show a “Return to About Us” link, for example, on subpages of About Us. To do so, replace the code at the top of views/viewer/show.html.erb with the following:

<% if !@subpages.empty? %>
  <div id='subnav'>
    <ul>
      <% for page in @subpages %>
        <li><%= link_to page.navlabel, view_page_path(page.name) %></li>
      <% end %>
  </div>
<% elsif @page.parent %>
  <div id='subnav'>
    <ul>
      <li><%= link_to "Return to #{@page.parent.navlabel}",
              view_page_path(@page.parent.name) %>
      </li>
    </ul>
  </div>
<% end %>

If there are subpages, then this code displays the subpage nav. If not, then if there is a parent page, it displays a link back to the parent page. (Note that you’d want to do something a little different if you had multiple levels of subpages.)

Now the subpages of About Us show the link back.

Add a Little Style

The subnav lists are pretty ugly, so let’s style them a little to make them look like buttons. Add the following to public/styles/learningrails.css:

#subnav {
    width: 160px;
    float: left;
    margin: 0 20px 50px -10px;
}
#subnav ul {
    list-style: none;
    font-weight: bold;
    font-size: 13px;
    margin: 0;
    padding: 0;
}
#subnav ul li {
    background-color: #999;
    border-bottom: 1px solid #333;
    border-top: 1px solid #333;
}
#subnav ul li a {
    padding: 5px 10px;
    display:block;
    color:white;
    text-decoration: none;
}
#subnav ul li a:hover {
    background-color: #333;
    color: #fff;
}

Retain Parent Button Highlight On Subpages

Another way we could indicate the parent page would be to keep its navigation button highlighted. We can do this with a small change to the current page id logic in the application layout, adding a test for the parent of the current page:

<li <%= "id = current" if @page && (@page == page or @page.parent == page) %>><%= link_to page.navlabel, view_page_path(page.name) %></li>

Now when you’re viewing one of the subpages of the About Us page, the About Us button is highlighted.

Note that we’ve let some logic creep back into our application controller here, but it is really presentational logic, so it doesn’t feel too bad.

Set Form Field Focus

One last bit of cleanup. On our login page, it’s annoying that you can’t just begin typing; neither of the form fields have focus until you click in one of them. We can fix that by adding a little bit of JavaScript to the bottom of views/sessions/new.html.erb:

<%= javascript_tag "$('login').focus()" %>

And now you can start typing as soon as the login page is displayed.

Moving On

We could go on for several more lessons tuning up our little content management system, but it’s time to move on. Next lesson, we’ll create the resources database and use that to drive the Resources page.


Add a Comment

Have a comment or question about this lesson? Add it here.






Comments on This Lesson

From: Alexander       Date: 07/02/08 08:08 AM

Subject: NoMethodError in Sessions#new

Hello:

Thanks for wonderful screen-casts and great tutorials.

As for this tutorial, I have question. Why do I get an exception error, in fact “You have a nil object when you didn’t expect it!”, after placing the dynamic links from the show.html.erb viewer, into the application.html.erb layer folder? Could this be routing problem?

Thanks for taking the time to answer my query.

Alex

From: Alexander       Date: 07/02/08 08:08 AM

Subject: NoMethodError in Sessions#new

Hello:

Thanks for wonderful screen-casts and great tutorials.

As for this tutorial, I have question. Why do I get an exception error, in fact “You have a nil object when you didn’t expect it!”, after placing the dynamic links from the show.html.erb viewer, into the application.html.erb layer folder? Could this be routing problem?

Thanks for taking the time to answer my query.

Alex

From: Robert       Date: 06/23/08 07:07 AM

Subject:

Thanks Christopher,

I reinstalled Quicktime as you suggested and all is fine. (I had an older version of Quicktime already on my computer but that didn’t work either. After updating to the latest version all worked well.)

Now I have some catching up to do!

Thanks again for your help. Robert

From: Christopher Haupt       Date: 06/22/08 08:20 PM

Subject: RE: No Audio on Lessons 15/16 (and probably later)

Glad they are helpful Robert. Perhaps the easiest thing to do would be to install Apple’s free iTunes player (which also installs Quicktime). If you already have it installed, try opening the MOV file in it instead of RealPlayer. That should get you going.

From: Robert       Date: 06/22/08 10:10 AM

Subject: No Audio on Lessons 15 & 16

Hi Christopher,

Thanks for all the work you and Michael have done in putting this course together for us. As a newcomer to Ruby & Rails, yours is a whole new world of potential and opportunity opening before me and know that many of us appreciate the help you are offering us.

My OS is Windows XP Home. My videos are being played on RealPlayer. It comes up automatically to play your videos and had been working fine until lesson 15. It has been my default player and I have not needed to change it until perhaps now. What should I be using?

Robert

From: Christopher Haupt       Date: 06/21/08 12:00 AM

Subject: RE: No Audio

Robert: Starting around episode 15 we switched around some of our audio encoder settings to get higher quality sounds and better compression. What OS and movie playing software are you using? On Windows and Mac, the latest Quicktimes should work fine. We are using AAC with no protections (no DRM).

From: Robert       Date: 06/20/08 08:20 PM

Subject: No Audio on Lessons 15 & 16

Something happened! I was viewing the screencasts fine up thru Lesson 14. Then lesson 15 would view with no audio. I was hoping that 16 would be back to normal, but it too is missing the sound portion. I can go back and play my older downloaded lessons like Lesson #14 and it plays fine.

If I re-download Lessons 15 & 16, they still have no sound! What happened?!

Thanks, Robert

From: Walter       Date: 06/05/08 08:20 PM

Subject: Update: Debugging Solution Found

Yesterday a user replied at railsforum that in using Restful Authentication, I have to give the attr_accessor the new variables that are accepted. Sure enough, by amending the line in user.rb with 3 new items at the end ie: attr_accessible :login, :email, :password, :password_confirmation, :first_name, :last_name, :exec_position …Worked. whew

Mental note: whenever data is in doubt, always check the model for authentication new or old behaviours

Cheers Walter

From: Walter       Date: 06/04/08 01:13 PM

Subject: Re: Debugging help

Thanks. Yes, I had restarted the server. Your code does show data being passed, but further along it doesn’t save the data for other views into @user. I’ll try other actions with their results later in the evening.

- !map:HashWithIndifferentAccess user: !map:HashWithIndifferentAccess password_confirmation: “12345” exec_position: bottle washer first_name: foo last_name: bar login: foobar password: “12345” email: foobar@email.com commit: Sign up authenticity_token: 44597daa797ed198645aeb027e706a00fab4fd4d action: create controller: users

From: Michael Slater       Date: 06/04/08 11:11 AM

Subject: Debugging help

Walter, what you’re doing should work. I took a look at your Railsforum post and I don’t immediately see what’s wrong.

Have you restarted the server since you made the changes? Not sure if you need to, but it never hurts.

To see what variables are actually reaching the view, add the following at the start of your user/create action:

render :inline =&gt; "&lt;%= debug params %&gt;" and return

From: Walter       Date: 06/04/08 10:10 AM

Subject: Own cleanup not showing up

see http://railsforum.com/viewtopic.php?id=18937 for details on issue. still can’t add new field data to @user from update action :(

From: Walter       Date: 06/04/08 07:07 AM

Subject: Own cleanup not showing up

Hi.

All I did was add some new columns (first_name, last_name) to the user table via a migration, ran rake db:migrate, and updated the user loop in the edit / show actions to see user.first_name etc.

However the new data in the fields are not being saved nor are they showing up in new pages. I can run script/console and save new information to an attribute, but outside no.

I thought that the update action with the @user.update_attributes(params[:user]) in the users_controller.rb was saving this new information?

Clearly I’ve missed a step, can anyone enlighten?

TIA Walter

From: Kenn       Date: 05/31/08 06:18 PM

Subject: typo

In (Provide Link To The Nav Bar) Section you list [&lt;li &lt;%= "id = 'current'"] and later in (retain parent button) you change it to ["id = current"]

From: andres       Date: 05/27/08 11:11 AM

Subject: Highlight Current Nav Button

Firt of all, sorry for my English. i’m from Spain and i have a low level of English.

Well, my question is: How can i Highlight Current Nav buttom when i’m in a subpages of a subpages?

example: cars ,old_cars ,old_yellow_cars

when i’m in “old_yellow_cars”, “cars” is not Highlight no?

thank you for the help

 

Hosting Provided By

EngineYard.com fully managed Rails hosting

Sponsored By

New Relic Rails Performance Monitoring

FiveRuns Tuneup

Peepcode Screencasts