
Tailwind CSS's aspect ratio plugin relies on the `aspect-ratio` CSS property, which Safari 13 and 14 don't support. Use this plugin to add support!
Henry Bley-Vroman
Posted
A version of this post appeared on viget.com
ERB is the view templating language Viget's front-end developers use with Ruby On Rails. This primer is designed to bring new developers up to speed writing it.
Read more
This post is an iteration on ERB and Twig Cross-Reference for Front-End Development. That post is geared towards developers who want to translate their Twig knowledge to ERB, or vice versa. You may also be interested in Fundamental Twig for Front-End Development.
ERB (Embedded Ruby) is a feature of Ruby that lets you —you guessed it!— embed Ruby in other files. ERB files have the extension .<compiled_extension>.erb
. It is the language HAML and Slim are shorthand for. ERB is commonly used for templating Views in Rails apps — at Viget we use it when building large sites with custom CMSes. (If that's something you do, check out Colonel Kurtz, the block editor we often use for the client-facing admin area of Rails app sites.)
Because it can do anything Ruby can do, it's extremely powerful, has a much steeper learning curve than Twig, and can do a lot that isn't relevant to front-end templating. There's no cannonical ERB-for-front-end-developers documentation, and the Rails official documentation is immense and hard to dig through. Some resources if for learning ERB:
link...
and button_to
methods are essential.content tag
and tag
methods are useful.link_to
<%# … %>
erb
<%# comment %>Copied
=begin
…=end
the opening and closing tags must be at the start of the line
erb
<%=begin %>block comment(both lines of both the begin and end tags must be at the start of their lines)<%=end %>Copied
not
erb
<%=begin %>not a comment<%=end %>Copied
<%= … %>
erb
<%= "print this" %> <%# output: `"print this"` %><%= 1 + 2 %> <%# output: `3` %>Copied
<% … %>
erb
<% if … do %> … <% end %>Copied
if
and unless
erb
<%= 2 if true %> <%# output: `2` %><%= 2 if false %> <%# output: `nil` %><%= 2 unless true %> <%# output: `nil` %><%= 2 unless false %> <%# output: `2` %>Copied
if
…elsif
…end
erb
<%# assuming x, y, z, and n are defined %><% if x %>y<% elsif z == n %> <%# note the spelling of elsif %>0<% else %>1<% end %>Copied
ERB supports "condition ?
iftrue :
iffalse", and "ifselftrue ?:
otherwise".
Note that the "then" case :
must be provided
erb
<%# assuming x, y, z, and n are defined %><%# if x then y %><%# omitting the "else" will throw an error #><%= x ? y : '' %><%# if x is true, y. otherwise, if z equals n then 0. otherwise 1 %><%= x ? y : z == n ? 0 : 1 %><%# ternary operator: x if x is true, otherwise y %><%= x ?: y %>Copied
0
is True
in Boolean contexts
erb
<%= false ? 'truthy' : 'falsy' %> <%# output: `"falsy"` %><%= 0 ? 'truthy' : 'falsy' %> <%# output: `"truthy"` %>Copied
=
erb
<% var = 1 %><% anotherVar = 0 %><% falseVar = false %><%= 2 if var %> <%# output: `2` %><%= 2 if anotherVar %> <%# output: `2` %><%= 2 if falseVar %> <%# output: `` %><%= 2 unless falseVar %> <%# output: `2` %>Copied
Multi-line blocks of markup can stored in an identifier with content_for x do
…end
erb
<% content_for longVar do %><div>…</div><% end %><%= content_for(longVar) %>Copied
Note: content_for
is additive: each time you provide content for a given variable, that content is appeneded to what was there already. To use content_for
to overwrite a global variable, use the flush: true
option:
erb
<% content_for refreshedVar do %>a<% end %><% content_for refreshedVar, flush: true do %>b<% end %>Copied
defined?()
erb
<%# output: the content if `var` is defined %><% if defined?(var) %>…<% end %><%# output: `var` if `var` is defined, otherwise `fallback` %><%= defined?(var) ? var : fallback %>Copied
||=
, the OR Equal operator
erb
<%# output: `var` if it is defined and not nil and not false, otherwise `fallback` %><% var ||= fallback %><%=begin %> common front-end use cases:1. output a variable only if it is defined<%=end %><% var ||= nil %><%# set a variable with a fallback %><% x = y ||= nil %>Copied
#{var}
erb
<% x = 1 %><%= "this is interpolated: #{x}" %><%# output: `this is interpolated: 1` %>Copied
+
(plus). Note that to concatenate a string and a number in Ruby, the number must be converted to a string.
erb
<% string_variable = 'world' %><% number_variable = 2 %><%= 'hello ' + string_variable %> <%# output: `"hello world"` %><%= "example #{number_variable}" %> <%# output: `"example 2"` %><%= 'example ' + 3.to_s %> <%# output: `"example 3"` %>Copied
n.each do |i|
…end
erb
<% items = ['a', 'b', 'c'] %><%# output: `...` %><% [0..items.length].each do %>.<% end %><%# output: `a b c ` %><% items.each do |item| %><%= item %><% end %>Copied
n.each_with_index do |i, index|
…end
erb
<%# output: `0. a 1. b 2. c ` %><% items = ['a', 'b', 'c'] %><% items.each_with_index do |item,index| %><%= index %>. <%= item %><% end %>Copied
n.times do |i|
…end
erb
<%# output: `0 1 2 3 4 5 6 7 8 9` %><% 10.times do |i| %><%= i %> <% end %>Copied
.each_with_index
's index
is always 0-indexed, so add 1
erb
<% items.each_with_index do |item,index| %><%= index + 1 %>. <%= item %><% end %>Copied
n.times do |i|
…end
erb
<%# output: `1 2 3 4 5 6 7 8 9 10 ` %><% 10.times do |i| %><%= i %> <% end %>Copied
n.times do |i|
…end
erb
<% n = 3 %><%# output: `...` %><% n.times do %>.<% end %><%# output: `1 2 3 ` %><% n.times do |i| %><%= i %><% end %>Copied
There are several options for formatting an object's data, notably: simply outputting, .inspect
ing, and debug()
ing. For basic data-checking purposes in a view, the essential difference is debug()
returns YAML while inspect
and printing return strings.
erb
<%# for some object `posts` %><%= posts %><%= posts.inspect %><%= debug(posts) %>Copied
.slice(index)
, .slice(start,count)
erb
<%= [1,2,3,4].slice(1) %> <%# output: `2` %><%= [1,2,3,4].slice(1,2) %> <%# output: `[2,3]` %>Copied
count
items.take(count)
or .first(count)
erb
<%= [1,2,3,4].take(2) %> <%# output: `[1,2]` %><%= [1,2,3,4].first(2) %> <%# output: `[1,2]` %>Copied
If trim_mode
is set to -
, a -
in the closing erb
tag will trim trailing whitespace:
erb
<% something -%>1<%= something_else -%>2<% another_thing %>Copied
is equivalent to
erb
<% something %>1<%= something_else %>2<% another_thing %>Copied
Use a Symbol :property
to look up an operation on a Hash:
erb
<% myHash = {hello: 'world'} %><%= myHash[:hello] %> <%# output: "world" %>Copied
For a layout
file that pulls in page
: content_for
in child, yield
in parent
layouts/layout.html.erb
erb
<%= yield :myBlock %>Copied
views/page.html.erb
erb
<% content_for :myBlock do %>the content<% end %>Copied
layouts/layout.html.erb
erb
<% if content_for?(:my_content) %><%= yield :my_content %><% else %>default content<% end %>Copied
views/page.html.erb
erb
<% content_for :my_content do %>the content<% end %>Copied
render
will output the contents of another file
erb
<%= render 'path/to/x' %>Copied
To pass values to the rendered file, define them:
erb
<% a = 1 %><% b = 2 %><%= render 'path/to/x', a:a, b:b %> <%# in path/to/x a=1 and b=2 %>Copied
If the rendered file expects different variable names, use those:
erb
<% a = 1 %><% b = 2 %><%= render 'path/to/x', y:a, z:b %> <%# in path/to/x y=1 and z=2 %>Copied
Tailwind CSS's aspect ratio plugin relies on the `aspect-ratio` CSS property, which Safari 13 and 14 don't support. Use this plugin to add support!
Your comprehensive cross-reference guide for Twig front-end view templates.