Yield in Yield in Ruby ‘.erb’ Templates for Sinatra Web App

Jinook Jung
Level Up Coding
Published in
3 min readMar 6, 2021

--

YIELD/wait until a block is executed!!!

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:

Nicely done!

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?

Why, why, why?!? “no block given (yield)” hmm…

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?

Beautiful~

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 yields, 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.

--

--