Professional Documents
Culture Documents
Overview
Writing Templates
o Using Text Transformation Methods
o Conventions for Template Files
o Using the ERB Library
o Running ERB in a Sandbox
o Suppressing Newlines
o A Longer Example
Running ERB from the Command-line
Overview
ERB (Embedded RuBy) is a feature of Ruby that enables you to conveniently generate any kind
of text, in any quantity, from templates. The templates themselves combine plain text with Ruby
code for variable substitution and flow control, which makes them easy to write and maintain.
Although ERB is most commonly seen generating Web pages, it is also used to produce XML
documents, RSS feeds, source code, and other forms of structured text file. It can be extremely
valuable when you need to create files which include many repetitions of a standard pattern, such
as unit test suites.
The main component of ERB is a library which you can call within your Ruby applications and
Rake tasks. This library accepts any string as a template, and imposes no limitations on the
source of the template. You may define a template entirely within your code, or store it in an
external location and load it as required. This means that you can keep templates in files, SQL
databases, or any other kind of storage that you want to use.
Ruby distributions also include a command-line utility that enables you to process templates that
are held in files without writing any additional code. Logically, this utility is called erb.
ERB is part of the Ruby standard library. You do not need to install any other software to use it.
Rails uses an improved version, called Erubis.
The supplied documentation for ERB provides a good introduction:
ri ERB
Writing Templates
ERB copies the text portions of the template directly to the generated document, and only
processes code that is identified by markers. Most ERB templates only use a combination of two
tag markers, each of which cause the enclosed code to be handled in a particular way.
A tag with an equals sign indicates that enclosed code is an expression, and that the renderer
should substitute the code element with the result of the code (as a string) when it renders the
template. Use an expression to embed a line of code into the template, or to display the contents
of a variable:
Hello, <%= @name %>.
Today is <%= Time.now.strftime('%A') %>.
Tags without the equals sign denote that the enclosed code is a scriptlet. Each scriptlet is caught
and executed, and the final result of the code is then injected in to the output at the point of the
scriptlet.
Scriptlets are most commonly used for embedding loops or conditional logic into templates:
<% for @item in @shopping_list %>
<%= @item %>
<% end %>
Notice that the scriptlets in this example enclose an expression. The scriptlets produce no text
themselves, but cause the enclosed expression to run multiple times, and the result of the
expression is written to the output each time.
Comment markers use a hash sign:
<%# This is just a comment %>
By default, a newline character is added to the page after the position of each tag. To suppress
this newline, use the optional parameter of ERB.new(), as explained below.
Rails extends ERB, so that you can suppress the newline simply by adding a trailing hyphen to
tags in Rails templates:
<% for @item in @items -%>
<%= @item %>
<% end -%>
will
will
will
will
be
be
be
be
To use these features your code must include the module ERB::Util.
Conventions for Template Files
2
A file that contains an ERB template may have any name, but it is the convention that the name
of file should end with the .erb extension. Rails requires template files to have the extension of
the output type, followed by .erb, so that a name like layout.html.erb indicates a HTML
template. Some applications use the extension .rhtml for HTML templates.
If you store templates in files, it is good practice to keep each template in a separate file.
Using the ERB Library
This is a very simple example:
require 'erb'
weekday = Time.now.strftime('%A')
simple_template = "Today is <%= weekday %>."
renderer = ERB.new(simple_template)
puts output = renderer.result()
ERB only processes the template when result is called. This means that the output will show the
values of variables as they are at the moment when the result is rendered, not when the ERB
object was defined.
The code shown above will fail almost anywhere other than in a simple script. ERB gets
variables from a Binding, an object that provides access to the instance methods and variables
that are owned by another object. If you do not specify a Binding, the result() method gets a
Binding from the top-level object, which will probably own very little. Fortunately, every Ruby
class has a private binding() instance method to provide Bindings that points to itself, so we can
easily extend any object to provide ERB with a Binding.
If the ERB object is enclosed in a method, and we want it to use the variables of the host object,
we get a Binding for the host like this:
class ShoppingList
attr_accessor :items, :template
def render()
renderer.result(binding)
end
end
To enable ERB to use the variables from a separate object, we must first ensure that it has a
public method to provide a Binding. We can then get a Binding at any later point:
class ShoppingList
attr_accessor :items
def initialize(items)
@items = items
end
Safe level 4 provides maximum isolation. At this level, the specified binding must be marked as
trusted for ERB to use it.
If you need to set the third or fourth parameters, but do not want ERB to run in a new thread, use
0 as the second parameter.
Suppressing Newlines
The third parameter of new specifies optional modifiers, most of which alter when newline
characters will be automatically added to the output. For example, ERB will not print newlines
after tags if you give > as the third parameter:
renderer = ERB.new(template, 3, '>')
A Longer Example
require 'erb'
def get_items()
['bread', 'milk', 'eggs', 'spam']
end
def get_template()
%{
Shopping List for <%= @date.strftime('%A, %d %B %Y') %>
You need to buy:
<% for @item in @items %>
<%= h(@item) %>
<% end %>
}
end
class ShoppingList
include ERB::Util
attr_accessor :items, :template, :date
def initialize(items, template, date=Time.now)
@date = date
@items = items
@template = template
end
def render()
ERB.new(@template).result(binding)
end
def save(file)
File.open(file, "w+") do |f|
f.write(render)
end
end
end
list = ShoppingList.new(get_items, get_template)
list.save(File.join(ENV['HOME'], 'list.html'))
The template can automatically use built-in Ruby classes, such as String and File. To allow it to
access standard or third-party libraries, use the -r option. This option works in the same way as
the require keyword. This example processes a template that uses the Abbrev and IPAddr
libraries:
erb -r abbrev -r ipaddr my-template.txt.erb
> new-file.txt
Use the -S option to specify a safe level that isolates the template processing:
erb -S 4 my-template.txt.erb > new-file.txt
Installing Rake
Like all good things Ruby, Rake is available as a Gem that you can install on your computer:
If youve already got your Ruby environment set up, then theres really nothing else much to say
about installation!
2
3
4
5
task :hello do
puts "Hello world!"
end
Firstly we have a task called default. All Rakefiles will have a default task. In this case, were
saying that when the default task is run, we should execute the hello task.
Secondly we have the hello task. When this task is run it will simply print Hello world! to the
screen.
If you save the Rakefile and run the following command from terminal, you should see the
correct output:
$ rake
Hello world!
1
2
3
task :ssh_into_server do
puts "ssh into server"
end
4
5
6
task :move_to_directory do
puts "cd to the correct directory"
end
7
8
9
10
task :pull_code do
puts "pulling code from Github"
end
11
12
13
14
task :get_dependencies do
puts "getting the dependencies"
end
15
16
task :migrate_the_database do
puts "migrating the database"
17
end
18
19
20
21
task :set_file_permissions do
puts "setting the file permissions"
end
22
23
24
25
task :symlink_the_new_version do
puts "symlinking the new version"
end
26
27
We can state that these tasks should be performed in the correct order by creating a new task that
has prerequisites.
1
2
end
Now with one single command we can completely automate the deployment of the website to the
production server:
$ rake deploy
Namespacing
Namespacing is also an important topic in Rake as bigger projects could potentially have rake
tasks that have conflicting names.
To solve this problem we can use namespaces. For example we might namespace our
deployment process from above like this:
namespace :ship_it do
task :ssh_into_server do
4
5
6
7
end
Now to run the deploy task you would include the namespace as part of the command:
$ rake ship_it:deploy
Describing tasks
When you are first getting to grips with an existing project, it can be useful to check out the
existing rake tasks to see what has been defined.
To list out the Rake tasks you can run the following command from terminal:
1$ rake --tasks
However, if you do that now you wont see any output. To provide additional help to the user we
can write a short description about the task:
task :ssh_into_server do
3
4
Now when you run the command again, you should see the following output:
$ rake tasks
rake ship_it:ssh_into_server
10
Install Bundler
The first thing we need to do is to install Bundler. Once again this should be pretty straight
forward if youve already got your Ruby environment set up:
If this is your first time creating a Gem you will be asked a couple of questions. The answers to
these questions dont really matter as we can change them later. We also wont be looking at
testing today, so you can just ignore the tests.
This will create the following files:
1 todo/Gemfile
2 todo/.gitignore
3 todo/lib/todo.rb
11
4 todo/lib/todo/version.rb
5 todo/todo.gemspec
6
7
todo/Rakefile
todo/README.md
todo/bin/console
8
9
todo/bin/setup
todo/LICENSE.txt
10
The Gemspec
The first file we will look at will be the todo.gemspec:
# coding: utf-8
require todo/version
5
6
7
8
9
Gem::Specification.new do |spec|
spec.name
= "todo"
spec.version
= Todo::VERSION
spec.authors
= ["Philip Brown"]
spec.email
= ["phil@ipbrown.com"]
10
11
12
13
14
15
16
spec.summary
= %q{TODO: Write a short summary, because
Rubygems requires one.}
spec.description
this line.}
spec.homepage
URL here."
spec.license
= "MIT"
17
12
18
19
20
21
22
23
24
25
26
27
28
29
30
31
spec.files
= `git ls-files -z`.split("\x0").reject { |f|
f.match(%r{^(test|spec|features)/}) }
spec.bindir
spec.executables
File.basename(f) }
= "exe"
= spec.files.grep(%r{^exe/}) { |f|
spec.require_paths = ["lib"]
32
spec.add_development_dependency "bundler", "~> 1.10"
spec.add_development_dependency "rake", "~> 10.0"
end
This file includes meta data about your Gem such as its name, description as well as details
about its author (you).
Next there are instructions for how the files should be read. You probably wont need to do
anything with these files unless you are doing something that requires extra files.
Finally we have the dependencies of the Gem. This Gem has no dependencies but if it did, they
would be listed here.
Dependencies can be either for development or for runtime. A development dependency would
be something like a testing framework. A runtime dependencies would be something that your
Gem needed to use into order work at runtime, for example an HTTP client.
These dependencies are also Gems made by other people and would be listed on Ruby Gems.
13
lib/todo/version.rb
lib/todo.rb
The version.rb file simply contains the version number of your Gem. Versioning is a very
important concept in the world of Open Source Software as it is the basis for including thirdparty code into your application.
1
2
3
module Todo
VERSION = "0.1.0"
end
The basic premise is that the version number should follow a consistent set of rules. So if your
Gem includes breaking changes, consumers of that Gem wont be affected until they choose to
be.
require "todo/version"
2
3
4
5
module Todo
# Your code goes here
end
By default this file simply contains an empty module named after your Gem as well as the
version file we just looked at.
This is the file that kicks off the execution of your Gem as it is what will be included by default.
14
For small Gems you might want to put everything in this one file. For example, if your Gem just
included a couple of methods or a couple of simple classes.
However, for bigger Gems you will want to break your code into different files and then require
them in this file.
15