#30
May 11, 2007

Pretty Page Title

If you are like me, you avoid creating page titles because it is kind of a pain. But in this episode I will show you a clean way to add titles to your pages.
Download (15.1 MB, 5:16)
alternative download for iPod & Apple TV (7.6 MB, 5:16)
# application_helper.rb
def title(page_title)
  content_for(:title) { page_title }
end
<!-- layouts/application.rhtml -->
<title>Shoppery - <%= yield(:title) || "The Place to Buy Stuff" %></title>

RSS Feed for Episode Comments 33 comments

1. InMan May 11, 2007 at 03:07

Used @page_title all the time :)


2. peanut May 11, 2007 at 05:57

This screencast is useful for me. Can you create screencast about using HTML Tidy in Ruby on Rails? Thank you!


3. Jake May 11, 2007 at 10:21

Great screencast! I took your idea one step further and had my title helper return either the set title or a default if one isn't already set when called with no arguments. That way I can call the helper to set the title, or call it w/ no arguments when I want to use the title.


4. Ryan Bates May 11, 2007 at 10:38

Great idea Jake. I normally don't like giving methods a dual purpose, but in this case I think it works very well.


5. Carlos May 11, 2007 at 12:38

Hi! Could you make a cast for i18n and l10n? would be nice!

thanks! congratulations!


6. Rob May 11, 2007 at 13:59

I was wondering why..

content_for(:title) { page_title }

works fine but

content_for :title { page_title }

doesn't - it gives a 500 error. Sorry.. I'm new to Rails/Ruby.


7. David Parker May 11, 2007 at 14:27

Another great tutorial Ryan!


8. Zach Inglis May 11, 2007 at 15:29

Rob,

He says so during the screencast. It's due to the syntax reading past :title, I believe.

So use it with brackets for now.


9. Ryan Bates May 11, 2007 at 16:49

Yep, Zach's correct. Ruby gets confused when you don't wrap the :title parameter in parentheses so it spits out a syntax error. I'm guessing it's because it thinks the {} brackets are trying to represent a hash not a block.

Same goes for later on in the video where I use parenthesis when calling yield(:title) while adding the || symbol. This is because Ruby doesn't know where to put the parenthesis, it could be here:

yield(:title || "foo")

or here:

yield(:title) || "foo"

It defaults to the first one (IIRC) so we need to clarify.

Whenever there's any doubt, wrap the parameters in parenthesis.


10. Pimpmaster May 11, 2007 at 18:01

This is one of my favorite screencasts. I just redid all my views and they sure look purty!

Cheers!


11. maze May 12, 2007 at 01:58

another great screencast! After every casts I have to go through all my code and change/implement what I've just learned ;-)

I'd like to see more casts where you use helper methods, cause I think they are useful but I don't know when...

cheers


12. Pimpmaster May 12, 2007 at 04:05

I just realized one caveat here. This particulat helper only takes a double-quoted string, so something like:

<%= title @article.title %>

Does not work because you will explicitly have to set it to a string

<%= title @article.title.to_s %>

This is not the case if you use the classic instance variable solution.


13. Pimpmaster May 12, 2007 at 08:29

Woops! Ignore those = on the ERB tags.


14. Ryan Bates May 12, 2007 at 08:48

@Pimpmaster, really? I've used non double quoted strings before. What kind of variable is @article.title? If it's not a string, that may be why. You may want to do the "to_s" conversion inside the title helper method.


15. Rafael May 12, 2007 at 10:30

Hi
thanks a lot for your work. Thats really what I was looking for, made a !little! donation today, hope that I can continue to donate :-D

Hopefully you have a lot of fun by doing that and you continue making such great "snippets".

greetinx


16. Ryan Bates May 12, 2007 at 10:35

Thanks for donating Rafael! It really helps. I enjoy making the screencasts as well.


17. Robin Curry May 12, 2007 at 15:34

Hey Ryan, love the screencasts. Quick question... I noticed in this one that as you typed keyboard shortcuts they were displayed in the upper right corner of the screen. Just wondering how you did that. Is this a feature of Textmate?


18. Ryan Bates May 12, 2007 at 22:39

I'm displaying the key commands with a little utility called KeyCastr.

http://stephendeken.net/software/keycastr/


19. Rafael May 13, 2007 at 02:43

Hi Ryan,
I would have a suggestion for a screencast.
How do you debug? With ruby-debug or breakpointer?
What is the better choice? There are topics, that breakpointer is deprecated, isn't it?
May this would be a topic for a Railscast

greetinx


20. Cameron Singe May 13, 2007 at 05:17

Great cast!

Looks forward to another one


21. Ryan Bates May 13, 2007 at 08:40

I used to use breakpointer a lot, but the recent Ruby releases broke it, so I'm currently getting by with just echoing variables to the log/view. I really need to learn ruby-debug, and once I do you can expect there to be an episode on it. Thanks for the suggestion.


22. Paul Newer May 13, 2007 at 09:56

It's the 13th! Do you know what that means?!?! Time for a new screencast! Whereisit whereisit whereisit....

Great screencast as always Ryan, I actually find myself enjoying yours more then peepcode, so be sure that I'm going to convert the money I would have spent on their screencasts into donation money for yourself, great work!


23. lisa Jun 01, 2007 at 15:11

I do:

<title><%= h @page_title || "Set title in: views/#{params[:controller]}/#{params[:action]}.rhtml" %></title>


24. Foobar Jun 09, 2007 at 03:45

why dont you set the title in the controller so it can be used by several views?


25. martin Jun 09, 2007 at 04:10

I agree with foobar, seting title in view is kind of wrong, logic should go in controller


26. Ryan Bates Jun 09, 2007 at 11:42

I see the title as view logic. The reason is because if a different controller action renders the same view, it doesn't have to set the title again.

For example, on the "new.rhtml" page you don't want to have to set the title in both the "new" action and the "create" action in the controller (in case the validation fails and the "new.rhtml" view is rendered again).

Now, if the title is complex obviously you don't want to put all that logic in the view. In that case it should be moved into a helper method.

I suppose this is personal preference, but I find placing it in the view is better.


27. Luke Cowell Sep 15, 2007 at 08:48

Great site. This could probably have the refactoring tag added t it.


28. Randy Oct 23, 2007 at 08:32

I've went a bit further: I have two helpers, access_denied() and action_denied() that put appropriate output; they now both have the title() call in them to set the title correctly, which is really nice. :)


29. Tim Gossett Jan 05, 2008 at 08:31

I was setting @page_title in my controllers until I saw this screencast... thanks, Ryan!

I like the idea of using content_for, but I'm not sure I can perform some logic on it like I can with an instance variable. I'm using the title method in application_helper.rb, only setting an instance variable instead of content_for.

In my application.html.erb, I do:

<title>
  <% if @page_title.nil? -%>
    example.com | an example site
  <% else -%>
    <%= @page_title %> | example.com
  <% end -%>
</title>

Can the same effect be achieved with content_for?


30. Ryan Bates Mar 03, 2008 at 20:14

@Tim, yep, actually content_for is just setting an instance variable in the background. I believe it's called @content_for_title (or whatever you pass to the method). You can reference this instance variable directly if you need, or just stick with yield(:title) which basically does the same thing.


31. Jeff Dean Apr 17, 2008 at 15:33

I like this method a lot - I just made one small change:

content_for(:title) { h(page_title) }

Adding the "h" method right to the helper ensures that no matter where I display it, it's safe. I often yield that title in a few other places, like in an h2 element somewhere on the page itself.


32. Silumesii Jul 20, 2008 at 15:23

@Jeff Dean, Thanks for the tip about the "h" method. I was getting XHTML warnings about my titles before and that cleaned them right up.

@Ryan Bates, I think I have learned more about Ruby and Ruby on Rails from you than anyone on the planet. Thanks!


33. Ben Bodien Aug 15, 2008 at 04:30

Very useful tip, thanks!


34. chovy Nov 09, 2008 at 14:09

You could use some valid defaults for a large site too:

controller.action_name.titlecase
controller.controller_name.titlecase

"Show Directories"
"Edit Directories"
etc. etc.


35. Adam Jun 28, 2009 at 05:48

Thanks for this! Great help.

I found myself in one application I am working on repeating the page title in the title block but also in the h1 element.

So I modified it slightly to help me with this: http://pastie.org/527089


36. Alexey Poimtsev Jul 17, 2009 at 04:47

hi Ryan,
plz have a look at plugin - http://github.com/kpumuk/meta-tags/tree/master, that uses idea from your railscast. Perfect thing :)


37. kucifoe Dec 08, 2009 at 03:04

Do you know:www.myuggonsale.com?


38. billymeltdown May 17, 2010 at 16:40

As a curious aside, the trick I like best here doesn't seem to be working for me in a new Rails 3 app:

yield(:title) || 'some default'

no longer works because content_for returns a blank string when there's nothing for it to do for the particular symbol. From the debugger:

(rdb:1) eval content_for(:title)
""

I'm not quite sure how to code up a better hack. The following came to mind:

%title= yield_or_default(:title, 'some default')

but then you end up trying to call yield in your helper method on a symbol and not a block and it just freaks out, because that's not your layout's yield!

def yield_or_default(symbol, default)
    output = yield(symbol) # blarf!
    output = default if output.blank?
    output
end


39. billymeltdown May 18, 2010 at 09:13

Come up with a decent work-around, here's a blog post explaining it:

http://www.zetetic.net/blog/2010/05/18/pretty-page-title-in-rails-3

And here's a straight gist:
http://gist.github.com/405129

Thanks again for all the Railscasts, Ryan!
Billy


40. gucci sneakers May 28, 2010 at 02:21

good idea,i like it


41. ugg boots china Jun 07, 2010 at 18:33

thanks for your posting…


42. tiffany notes Jul 30, 2010 at 00:48

Great site. This could probably have the refactoring tag added t it.


44. hair rollers Aug 08, 2010 at 22:19

Excellent article that will provide the incentive and basis for my works.I wonder if I can mention the article as a bibliographic reference in my work. Thanks!


45. free directory list Aug 11, 2010 at 22:07

Ryan, could you show the view that is calling this template?


46. free directory list Aug 11, 2010 at 22:07

Ryan, could you show the view that is calling this template?


47. free directory list Aug 11, 2010 at 22:07

Ryan, could you show the view that is calling this template?


48. buy jordans Aug 19, 2010 at 00:18

Excellent article that will provide the incentive and basis for my works.I wonder if I can mention the article as a bibliographic reference in my work. Thanks! good idea,i like it


49. louis vuitton shoes Aug 26, 2010 at 23:14

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


50. snow boots Aug 31, 2010 at 01:51

I took your idea one step further and had my title helper return either the set title or a default if one isn't already set when called with no arguments.


51. louis vuitton sunglasses Sep 01, 2010 at 21:24

Very good post. Made me realize I was totally wrong about this issue. I figure that one learns something new everyday. Mrs Right learned her lesson! Nice, informative website by the way.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source