Embedded Ruby - ERB
Templates are pre-designed documents, that contain static content and slots for dynamic content.
Hi [USERNAME]
Thank you for registering at [PLATFORM_NAME]!
Use this token to confirm your email address
when you sign in for the first time:
[CONFIRMATION_TOKEN]
Have a great day!
The parts surrounded by []
are the slots for dynamic content, the rest is static content
In Ruby we can use Embedded Ruby, or ERB, to design such templates.
require "erb"
name = "Bill"
greeting_template = "Hi <%= name %> 👋"
ERB.new(greeting_template).result(binding) # => Hi Bill 👋
🥵
Why don't we use String interpolation?
name = "Bill"
"Hi #{name} 👋" # => Hi Bill 👋
💪
✋ String interpolation gets messy if we have more complex outputs.
name = "Bill"
movies = [
{ name: "Groundhog Day", year: 1993 },
{ name: "Lost In Translation", year: 2003 },
{ name: "Moonrise Kingdom", year: 2012 }
]
Target output
Hi Bill 👋
Do you want to watch a movie? Today we have:
* Groundhog Day (1993)
* Lost In Translation (2003)
* Moonrise Kingdom (2012)
- Your Cheap Video Network
output = "Hi #{name} 👋\n"
output << "\nDo you want to watch a movie? Today we have:\n\n"
movies.each do |movie|
output << "* #{movie[:name]} (#{movie[:year]})\n"
end
output << "\n- Your Cheap Video Network\n"
movies_template = %q{
Hi <%= name %>
Do you want to watch a movie? Today we have:
<% movies.each do |movie| %>
* <%= movie[:name] %> (<%= movie[:year] %>)
<% end %>
- Your Cheap Video Network
}
require "erb"
ERB.new(movies_template).result(binding)
We can use conditionals, loops, and other control structures to generate dynamic content
church_bell_template = %q{
<% hour.times do %>
DONG 🔔
<% end %>
<% if (6..12).cover?(hour) %>
Good morning <%= name %>
<% elsif (12..18).cover?(hour) %>
Good afternoon <%= name %>
<% else %>
Good day <%= name %>
<% end %>
}
require "erb"
hour = Time.now.hour # for example 8, at 08:00
name = "Bill"
ERB.new(church_bell_template).result(binding)
DONG 🔔
DONG 🔔
DONG 🔔
DONG 🔔
DONG 🔔
DONG 🔔
DONG 🔔
DONG 🔔
Good morning Bill
We can separate our code into different files, allowing us to focus on our application logic in one file and our presentation logic in another
name = "Bill"
lucky_numbers = (1..50).to_a.sample(6)
File: ./lucky_numbers.txt
Hi <%= name %> 👋
Today your lucky numbers are:
<% lucky_numbers.sort.each do |lucky_number| %>
* <%= lucky_number %>
<% end %>
Good luck! 🍀
(...this looks very similar to the email example at the beginning, remember?)
require "erb"
template = File.read("./lucky_numbers.txt")
ERB.new(template).result(binding)
Hi Bill 👋
Today your lucky numbers are:
* 10
* 12
* 23
* 33
* 39
* 45
Good luck! 🍀
ERB templates can be reused across different parts of our application.
Let's create an HTML template
File ./chores.html
<h1>Hi <%= username %> 👋</h1>
<p>Don't forget to do the following chores today:</p>
<ul>
<% chores.each do |chore| %>
<li><%= chore %></li>
<% end %>
</ul>
Remember, this is the presentation logic
Application logic
username = "Bill"
chores = [
"Call mom ☎️",
"Clean the bath 🫧",
"Walk the dog 🐕",
"Learn Spanish 🇪🇸"
]
Rendering
require "erb"
template = File.read("./chores.html")
ERB.new(template).result(binding)
HTML Output
<h1>Hi Bill 👋</h1>
<p>Don't forget to do the following chores today:</p>
<ul>
<li>Call mom ☎️</li>
<li>Clean the bath 🫧</li>
<li>Walk the dog 🐕</li>
<li>Learn Spanish 🇪🇸</li>
</ul>
What questions do you have?