Yield in Yield in Ruby ‘.erb’ Templates for Sinatra Web App
One of the most important parts in using templates in Ruby-Sinatra combination (or even Ruby-on-Rails) is how to use theyield
keyword effectively.
Below is most likely your barebone folder structure when you create a Ruby-Sinatra web app:
|- app
| |- controllers
| |- models
| |- views
|- config
| environment.rb
|- db
| |- migrate
|
config.ru
Gemfile
Rakefile
You have your application_controller.rb
file in the controllers
folder and your .erb
view files under views
directory. Let’s say you have the basic controller and layout.erb
with show.erb
. See the codes here:
# (assuming that you already have Gemfile, Rakefile, config.ru, environment.rb, and some other basic files)
Now you recognize the necessary yield
keyword appears in layout.erb
file to use this file as a background template for all other .erb
files (as you might know, Sinatra in default will look for this layout.erb
for this role). Because the controller, application_controller.rb
, calls the erb
method with an argument of :show
, the show.erb
file in the views
folder will be the block to fill in the place, yield
, in layout.erb
file. Here is the result:
Everyone knows this far! But, what I want to mention is, “Can we put another yield
in show.erb
?” My situation was that I had a show
page for posts, and each post had the comment section at the bottom. Something like this:
As you can see, the comment section is a totally separate one from the main post section. It is also from a different model/table in database. In other word, this comment section is working better, separately! So, what about having a post show
file have yield
in it so that a separate comments.erb
view file can fill that yield
portion in later. That is possible!
Let’s change our show.erb
file a little bit so that it may look like a blog post:
And, you have a separate comments.erb
file like this:
Do you think it will work?
This is what you will have with the codes we have so far. Why? In theory, a yield
takes a block, so the yield
in show.erb
file should take comments.erb
as its block! Right? Not at all!!! The yield
in show.erb
file never knew the existence of comments.erb
at all. Therefore, we have to let it know that a file called comments.erb
exists and is ready to fill in the yield
in it. Here’s how:
Do you see the additional part? Yes! We take another block, erb :comments
, for yield
in show.erb
. In this way, the yield
in show.erb
file now knows the existence of comments.erb
. Results?
As you may guess, we can do yield
in yield
in yield
in yield
in yield
… You know what I mean! Just in case, here is how:
So, next time you have a complex page in you Sinatra web app, use this technic! For better understanding, you can read Sinatra documentation and some good related articles like this one by Allyson Wesman. And, please know that you can even use name-tagged multiple yield
s, using Sinatra extension gem called ‘sinatra-contrib’ (please see the Sinatra Doc and a related article by Jake Trent). For a more complex example, you may try my TraVlog App in my Github repo.