Part 2 of this series focused on routing and expanding our application to serve back HTML responses. In this post, we’ll start to think about separation of responsibilities between our core routing logic and our views. We’ll introduce a library
ERB that will help us turn Ruby code into HTML. Finally, we’ll update our application code to include view templates.
Right now in our code, we’re including HTML directly inside the string that we’re returning as the response. We’re including dynamic content in that string by using string interpolation. But if we want to take advantage of the separation of concern that view templates gives us, how do we incorporate them into our application? Before we answer that question, we’ll take a quick detour and study a popular Ruby templating library.
There are many view templating libraries and options, but in this application we’ll use a templating engine called Embedded Ruby or ERB. ERB allows us to embed Ruby directly into HTML — hence “Embedded” Ruby. The ERB library can process a special syntax that mixes Ruby into HTML, and produces a final 100% HTML string. That’s all it does.
In our application, we’ll be using ERB in conjunction with separate view template files —
.erb files. But before we work with files, let’s try out the ERB templating engine in IRB.
To use ERB, first we must:
- Create an ERB template object and pass in a string using the special syntax that mixes Ruby with HTML.
- Invoke the ERB instance method
result, which will give us a 100% HTML string.
The end result is that we can use ERB to convert a string with Ruby mixed with HTML into a string that is 100% HTML.
Let’s hop into IRB and try all of this out:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Note that we’re instantiating a new
ERB template object with Ruby and HTML mixed together. Note also that we’re using the
<%= %> special syntax to let ERB know how to process this mixed content.
We’re using the method
random_number to get some dynamic content, and then invoking that method by using the ERB syntax
<%= %>. The final output from ERB is pure HTML.
<%= %> are ERB tags that are used to execute Ruby code that is embedded within a string. There are two varieties: one that doesn’t have an equal sign, and one that does.
<%= %>– will evaluate the embedded Ruby code, and include its return value in the HTML output. A method invocation, for example, would be a good candidate for this tag.
<% %>– will only evaluate the Ruby code, but not include the return value in the HTML output. You’d use this tag for evaluating Ruby but don’t want to include its return value in the final string. A method definition, for example, would be a good use case for this tag.
ERB can also be used to process entire files, and not just strings. Just like the strings that contained a mix of Ruby and HTML, ERB files also follow the same format. ERB files need to end with an
.erb extension and use the same special tags to embed Ruby. Let’s say we had a file called
example.erb that looked like the below.
1 2 3 4 5 6 7
If we had an
.rb file in the same directory as the
example.erb file above, we could process that
erb file like this:
1 2 3 4 5
The result would be a 100% HTML string that looks something like
<html><body><h4>Hello, my name is jill</h4></body></html>. Of course, the name would change every time since it is dynamic content. Note: if you’re following along, you might see some extra newline characters (
\n) in the final string; that’s ok, and can be ignored for now.
That’s a quick overview of how to work with ERB. Now let’s take a look at how to use ERB with files to make our Rack web application more flexible and accommodating using view templates.
Adding in View Templates
To start off, we’ll create a view template for the information we wish to display to the user. This will be the default view template for our application. Let’s call it,
index.erb. We also have to include the same message we’ve been using for our root route: “Hello World!”.
1 2 3 4 5
We want some organization within our application, so for now, we’ll put all view templates in the
views folder. This folder should be located at the top-level of our application, along with
Our application should now look like this:
1 2 3 4 5 6 7 8
Now that we have our
index.erb view template, we need to read it into our application and use it. We can treat it just like any other file and use the
.read method from the Ruby
And after we have our view template in string format, we can pass it into an
ERB object and use that as a way to get our response body. Lines 7-9 below show this in code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Just as we did earlier from IRB, we take a string value (the contents of
index.erb) and pass that in
ERB.new. Then, we can use the
#result method to get a 100% HTML string output for the response body. The difference this time is that we’re getting that string value from a file, the view template.
We’ve set up all that we need to use a view template as our response body. Now, let’s run our application and see if we get the correct response (make sure to first restart the server):
1 2 3 4 5 6 7 8 9 10 11 12 13
For this particular page, we don’t actually need ERB. There isn’t any dynamic content related to our index page. Yet, we’ll need it for the routes that require dynamic data, so to keep everything consistent, we’ll be using
.erb files for all our other routes. This also leaves options open for us; if we want to add dynamic content to
index.erb later, then we can easily do so.
If you’d like to see what it looks like with a browser, you can navigate your browser to
localhost:9595 and you should see the following (notice the text is now a
In this post, we’ve set up our application to use a view template. Now, our main application file used for routing doesn’t get bogged down as much by view related code in the root route. Yet, take a look at our other two routes. Our application code could get very messy, depending on the size of the response we want to potentially return. Separating our view related code to their own files really helps in keeping our code base more manageable. In part 4 of this series, we’ll continue to build up our application and then start extracting common code in order to plant the seeds for our very own web development framework.