John Finley
Posted on November 29, 2022
Adding dynamic page titles to your Rails web application can be a great way to give your page a more professional look. It is actually very easy to change the page title and I'm going to show you how. In this tutorial, I am going to assume that you know how to create a new rails app as well as the basics of using the terminal.
In this tutorial I am using Rails version 7.0.4 and Ruby version 2.7.4.
I've also added this to a Github repository in case you wanted to clone the code and follow along.
https://github.com/jfinley6/rails-dynamic-page-title-tutorial
Scaffolding/Routes/Seeds
After making a new app and navigating into the folder there are several things we need do to do to before we show off our functionality. First we're going to create a scaffold which will generate our controller, model, and views. I've decided to name it Book and give our model a title, author, and pages attributes.
ā books git:(main) ā rails g scaffold Book title author genre pages:integer
If you've done this correctly, you should see the following output in your terminal.
invoke active_record
create db/migrate/20221128223152_create_books.rb
create app/models/book.rb
invoke test_unit
create test/models/book_test.rb
create test/fixtures/books.yml
invoke resource_route
route resources :books
invoke scaffold_controller
create app/controllers/books_controller.rb
invoke erb
create app/views/books
create app/views/books/index.html.erb
create app/views/books/edit.html.erb
create app/views/books/show.html.erb
create app/views/books/new.html.erb
create app/views/books/_form.html.erb
create app/views/books/_book.html.erb
invoke resource_route
invoke test_unit
create test/controllers/books_controller_test.rb
create test/system/books_test.rb
invoke helper
create app/helpers/books_helper.rb
invoke test_unit
invoke jbuilder
create app/views/books/index.json.jbuilder
create app/views/books/show.json.jbuilder
create app/views/books/_book.json.jbuilder
Next you're going to want to run your pending migration to create the Books table.
ā books git:(main) ā rails db:migrate
== 20221128223152 CreateBooks: migrating ======================================
-- create_table(:books)
-> 0.0026s
== 20221128223152 CreateBooks: migrated (0.0026s) =============================
Once this is done, we're going to want to create some books for our views as well as change the index page for our website.
First go to your config > routes.rb file and make sure it looks like the routes.rb file below. This is going to tell Rails which route we should take when the URL ends in "/". In this case, our home page will render the app > views > books > index.html.erb file.
Secondly we can edit our db > seeds.rb file with a couple books to populate our page.
#routes.rb
Rails.application.routes.draw do
root "books#index"
resources :books
end
#seeds.rb
Book.create(title: "Fellowship of the Ring", author: "J.R.R. Tolkien", genre: "Fantasy/Adventure", pages: 423)
Book.create(title: "Heir to the Empire", author: "Timothy Zahn", genre: "Science Fiction", pages: 528)
Book.create(title: "Mistborn: The Final Empire", author: "Brandon Sanderson", genre: "Fantasy", pages: 672)
Views
Now that we've got our routes setup, we can take a look at our views. We'll be looking at two files, app > views > books > index.html.erb and show.html.erb. I've modified the styling slightly and removed the delete, edit and new book links for simplicity. The code below is exactly what I have in each respective view.
<%# index.html.erb %>
<p style="color: green"><%= notice %></p>
<h2 style="text-align: center">All Books</h2>
<div id="books" style="display: flex; flex-direction: column; align-items: center">
<% @books.each do |book| %>
<div style="border-style: solid; width: 300px; text-align: center; margin-bottom: 5px">
<%= render book %>
<p>
<%= link_to "Show this book", book %>
</p>
</div>
<% end %>
</div>
<%#= show.html.erb %>
<p style="color: green"><%= notice %></p>
<div style="display: flex; flex-direction: column; align-items: center">
<%= render @book %>
<%= link_to "Back to books", books_path, style: "text-align: left" %>
</div>
We also want to go to app > views > layouts > application.html.erb and replace the contents of our title tag with the following code. The yield keyword identifies a section where content from the view should be inserted. We can give it a symbol name and now the page title will display to whatever value :title is assigned.
<%= yield :title %>
Now we can go into our show.html.erb and add the following at the top of the file. content_for is how you specify which content is going to be rendered into which content area. In this case, we are assigning a value to :title.
<% content_for :title do %>
<%= @book.title %>
<% end %>
Now, depending on which "Show this book" you click, it will display the name of the book in the browser tab. You can also add this to index.html.erb or any other view where you want the page title to reflect the content on the page.
Adding a Helper Method
We can also simplify this by adding a helper method. I've added the following to app > helpers > books_helper.rb
module BooksHelper
def title(title)
content_for :title, title
end
end
Now we can replace our previous content_for code in show.html.erb.
<%= title @book.title %>
This will call the title helper method and achieve the same thing we had before. This allows us to reuse the same code over and over and reduce the amount of code that we need.
Conclusion
Using yield and content_for is a great way to have dynamic page titles. Depending on which view we are rendering, we can change what content is being rendered which is great for our page title. Now we can give unique page titles for all our views and give our website an added professional feel. If you have any questions about I'd be happy to try my and answer!
Posted on November 29, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.