ERB and Twig Cross-Reference for Front-End Development

Your comprehensive cross-reference guide for Twig and ERB front-end view templates.

A version of this article appeared on viget.com

Two entire flowering plants, a yellow crocus (Crocus species) and a herb Paris (Paris quadrifolia). Colour nature print by A. Auer, c. 1853
Two entire flowering plants, a yellow crocus (Crocus species) and a herb Paris (Paris quadrifolia). Colour nature print by A. Auer, c. 1853. Auer, Alois, 1813-1869. Public Domain Mark. Source: Wellcome Collection.

Read more

This post is geared towards developers who want to translate their Twig knowledge to ERB, or vice versa. If you’re only interested in one language or the other, check out Fundamental ERB for Front-End Development or Fundamental Twig for Front-End Development.

Contents

Introduction

Twig and ERB are the two front-end templating languages I use most when developing websites. Here I document the ways each write just about everything to build views: comments, conditionals, variables and undefined variables, interpolation, loops and the loop index, slicing, handling whitespace, retrieving an keyed values, and templating with blocks and partials. If you’re familiar with one of Twig or ERB, use this as a cross-reference to translate your knowledge of the one language into the other. If you haven’t used either, this should get you up and running quickly. Read on to learn more about ERB and Twig, or skip ahead to the reference section.

What is Twig?

Twig is SensioLabs’ Django- / Jinja-like templating language for PHP. The recommended extension for Twig files is .twig, .<compiled_extension>.twig is useful, and .html —though inaccurate— is common in front-end templating. It’s used by SensioLabs’ Symfony; by Drupal 8, which is built on Symfony; and by Craft CMS.

Twig is a great language for building web front ends: it is full-featured without having more than one person could hope to learn, it reads fairly closely to English, and it has great official documentation. Twig is especially notable for its powerful support for complex inheritance across templates. Check out the use tag, the embed tag, and the block() function.

Twig even has Javascript implementations, making it easy to fit into projects built on the JS ecosystem. A quick overview to help you pick the one that best suits yours needs:

  • Mozilla’s Nunjucks is officially “jinja2 inspired” but it has [often followed Twig’s lead](https://github.com/mozilla/nunjucks/issues?utf8=✓&q=is%3Aissue is%3Aclosed twig ). If you use Gulp in your build tools, you can use gulp-nunjucks.
  • Twig.js is a popular JS port of Twig that sees more active development than Nunjucks does. It does not reach full parity with Twig (as of this writing Twig.js notably still has some bugs with Twig’s embed tag) but it currently comes closer than Nunjucks does and, since its goal is to duplicate Twig, it likely always will. The Twig.js Gulp plugin is gulp-twig.
  • Twing is a Twig engine for Node.js written in TypeScript which aims to always maintain complete parity with Twig. It is described as “a maintainability-first engine that passes 100% of the TwigPHP integration tests, is as close as possible to its code structure and expose an as-close-as-possible API.” Because Twing is able to essentially reuse much of Twig’s codebase, adding new features as they are merged into Twig is straightforward. Twing is the youngest of these projects… Twig users, show it your love! gulp-twing lets you use Twing with Gulp.

To learn Twig, read through the official documentation, and try things out in twigfiddle.

What is ERB?

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.

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:

Reference

Delimiters

Comments

Inline comments

  • ERB: <%# … %>

    erb
    erb
    <%# comment %>
    erb
    <%# comment %>
  • Twig: {# … #}

    twig
    twig
    {# comment #}
    twig
    {# comment #}

Block comments

  • ERB: =begin=end

    the opening and closing tags must be at the start of the line

    erb
    erb
    <%
    =begin %>
    block comment
    (both lines of both the begin and end tags must be at the start of their lines)
    <%
    =end %>
    erb
    <%
    =begin %>
    block comment
    (both lines of both the begin and end tags must be at the start of their lines)
    <%
    =end %>

    not

    erb
    erb
    <%
    =begin %>
    not a comment
    <%
    =end %>
    erb
    <%
    =begin %>
    not a comment
    <%
    =end %>
  • Twig: {# … #}

    twig
    twig
    {#
    block comment
    #}
    twig
    {#
    block comment
    #}

    or

    twig
    twig
    not a comment {# block
    comment #} not a comment
    twig
    not a comment {# block
    comment #} not a comment

Outputting values

  • ERB: <%= … %>

    erb
    erb
    <%= "print this" %> <%# output: `"print this"` %>
    <%= 1 + 2 %> <%# output: `3` %>
    erb
    <%= "print this" %> <%# output: `"print this"` %>
    <%= 1 + 2 %> <%# output: `3` %>
  • Twig: {{ }}

    twig
    twig
    {{ "print this" }} {# output: `print this` #}
    {{ 1 + 2 }} {# output: `3` #}
    twig
    {{ "print this" }} {# output: `print this` #}
    {{ 1 + 2 }} {# output: `3` #}

Execution (Control Code)

  • ERB: <% … %>

    erb
    erb
    <% ifdo %> … <% end %>
    erb
    <% ifdo %> … <% end %>
  • Twig: {% … %}

    twig
    twig
    {% if … %} … {% endif %}
    twig
    {% if … %} … {% endif %}

Conditionals

Single-statement conditionals

  • ERB: if and unless

    erb
    erb
    <%= 2 if true %> <%# output: `2` %>
    <%= 2 if false %> <%# output: `nil` %>
    <%= 2 unless true %> <%# output: `nil` %>
    <%= 2 unless false %> <%# output: `2` %>
    erb
    <%= 2 if true %> <%# output: `2` %>
    <%= 2 if false %> <%# output: `nil` %>
    <%= 2 unless true %> <%# output: `nil` %>
    <%= 2 unless false %> <%# output: `2` %>

Multi-statement conditionals

  • ERB: ifelsifend

    erb
    erb
    <%# assuming x, y, z, and n are defined %>
    <% if x %>
    y
    <% elsif z == n %> <%# note the spelling of elsif %>
    0
    <% else %>
    1
    <% 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 %>
  • Twig: ifelseifendif

    twig
    twig
    {% if x %}
    y
    {% elseif z == n %}{# note the spelling of elseif #}
    0
    {% else %}
    1
    {% endif %}
    twig
    {% if x %}
    y
    {% elseif z == n %}{# note the spelling of elseif #}
    0
    {% else %}
    1
    {% endif %}

Conditionals with logical operators

Both ERB and Twig support “condition ? iftrue : iffalse”, and “ifselftrue ?: otherwise”.

  • ERB. Note that the “then” case : must be provided

    erb
    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 %>
    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 %>
  • Twig

    twig
    twig
    {# assuming x, y, z, and n are defined and/or Twig's strict variables option is turned off #}
    {# if x then y #}
    {{ 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 }}
    twig
    {# assuming x, y, z, and n are defined and/or Twig's strict variables option is turned off #}
    {# if x then y #}
    {{ 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 }}

Truth and falsity of zero in Boolean contexts

  • ERB: 0 is True in Boolean contexts

    erb
    erb
    <%= false ? 'truthy' : 'falsy' %> <%# output: `"falsy"` %>
    <%= 0 ? 'truthy' : 'falsy' %> <%# output: `"truthy"` %>
    erb
    <%= false ? 'truthy' : 'falsy' %> <%# output: `"falsy"` %>
    <%= 0 ? 'truthy' : 'falsy' %> <%# output: `"truthy"` %>
  • Twig: as in PHP generally, 0 is False in Boolean contexts

    twig
    twig
    {{ false ? 'truthy' : 'falsy' }} {# output: `falsy` #}
    {{ 0 ? 'truthy' : 'falsy' }} {# output: `falsy` #}
    twig
    {{ false ? 'truthy' : 'falsy' }} {# output: `falsy` #}
    {{ 0 ? 'truthy' : 'falsy' }} {# output: `falsy` #}

Defining variables

  • ERB: =

    erb
    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` %>
    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` %>
  • Twig: set

    twig
    twig
    {% set var = 1 %}
    {% set anotherVar = 0 %}
    {% set falseVar = false %}
    {{ var ? 2 }} {# output: `2` #}
    {{ anotherVar ? 2 }} {# output: null - Twig, unlike PHP, equates 0 with falsehood #}
    {{ falseVar ? '' : 2 }} {# output `2` #}
    twig
    {% set var = 1 %}
    {% set anotherVar = 0 %}
    {% set falseVar = false %}
    {{ var ? 2 }} {# output: `2` #}
    {{ anotherVar ? 2 }} {# output: null - Twig, unlike PHP, equates 0 with falsehood #}
    {{ falseVar ? '' : 2 }} {# output `2` #}

    Twig can define multiple variables in a single call — just keep in mind that developers not used to this might overlook the multiple declarations!

    twig
    twig
    {% set x, y, z = 1, 2, 3 %}
    twig
    {% set x, y, z = 1, 2, 3 %}

    (A value must be explicitly provided for each variable: {% set x, y = 1 %} will error.)

Line breaks within a variable’s value

  • ERB: multi-line blocks of markup can stored in an identifier with content_for x doend

    erb
    erb
    <% content_for longVar do %>
    <div>
    </div>
    <% end %>
    <%= content_for(longVar) %>
    erb
    <% content_for longVar do %>
    <div>
    </div>
    <% end %>
    <%= content_for(longVar) %>

    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
    erb
    <% content_for refreshedVar do %>
    a
    <% end %>
    <% content_for refreshedVar, flush: true do %>
    b
    <% end %>
    erb
    <% content_for refreshedVar do %>
    a
    <% end %>
    <% content_for refreshedVar, flush: true do %>
    b
    <% end %>
  • Twig: use the set tag’s form set xendset to capture chunks of text

    twig
    twig
    {% set longVar %}
    <div>
    </div>
    {% endset %}
    {{ longVar }}
    twig
    {% set longVar %}
    <div>
    </div>
    {% endset %}
    {{ longVar }}

Dealing with undefined variables

  • ERB:

    • defined?()

      erb
      erb
      <%# output: the content if `var` is defined %>
      <% if defined?(var) %>
      <% end %>
      <%# output: `var` if `var` is defined, otherwise `fallback` %>
      <%= defined?(var) ? var : fallback %>
      erb
      <%# output: the content if `var` is defined %>
      <% if defined?(var) %>
      <% end %>
      <%# output: `var` if `var` is defined, otherwise `fallback` %>
      <%= defined?(var) ? var : fallback %>
    • ||=, the OR Equal operator

      erb
      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 %>
      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 %>
  • Twig:

    • is defined

      Especially useful when Twig’s strict variables option is turned on, in which case referring to an undefined variable will throw an error.

      twig
      twig
      {# output: Twig_Error_Runtime: Variable "x" does not exist. #}
      {{ x }}
      {# output: the content if var is defined #}
      {% if var is defined %}
      {% endif %}
      {# output: `advance` if var is defined, otherwise `fallback` #}
      {{ var is defined ? advance : fallback }}
      twig
      {# output: Twig_Error_Runtime: Variable "x" does not exist. #}
      {{ x }}
      {# output: the content if var is defined #}
      {% if var is defined %}
      {% endif %}
      {# output: `advance` if var is defined, otherwise `fallback` #}
      {{ var is defined ? advance : fallback }}
    • ??, the null coalescing operator

      twig
      twig
      {# output: `var` if it is defined and not null, otherwise `fallback` #}
      {{ var ?? fallback }}
      {# common use cases:
      1. output a variable only if it is defined #}
      {{ var ?? null }}
      {# set a variable with a fallback #}
      {% set x = y ?? null %}
      twig
      {# output: `var` if it is defined and not null, otherwise `fallback` #}
      {{ var ?? fallback }}
      {# common use cases:
      1. output a variable only if it is defined #}
      {{ var ?? null }}
      {# set a variable with a fallback #}
      {% set x = y ?? null %}

Variable interpolation

  • ERB: #{var}

    erb
    erb
    <% x = 1 %>
    <%= "this is interpolated: #{x}" %><%# output: `this is interpolated: 1` %>
    erb
    <% x = 1 %>
    <%= "this is interpolated: #{x}" %><%# output: `this is interpolated: 1` %>
  • Twig: #{var}

    twig
    twig
    {% set x = 1 %}
    {{ "this is interpolated #{x}" }}{# output: `this is interpolated: 1` #}
    twig
    {% set x = 1 %}
    {{ "this is interpolated #{x}" }}{# output: `this is interpolated: 1` #}

Concatenation

  • ERB: + (plus). Note that to concatenate a string and a number in Ruby, the number must be converted to a string.

    erb
    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"` %>
    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"` %>
  • Twig: ~ (tilde). Note that strings and numbers can be freely concatenated.

    twig
    twig
    {% set string_variable = 'world' %}
    {% set number_variable = 2 %}
    {{ 'hello ' ~ string_variable }} {# output: `hello world` #}
    {{ "example #{number_variable}" }} {# output: `example 2` #}
    {{ 'example ' ~ 3 }} {# output: `example 3` #}
    twig
    {% set string_variable = 'world' %}
    {% set number_variable = 2 %}
    {{ 'hello ' ~ string_variable }} {# output: `hello world` #}
    {{ "example #{number_variable}" }} {# output: `example 2` #}
    {{ 'example ' ~ 3 }} {# output: `example 3` #}

Iteration (loops)

Iterating over items

  • ERB: n.each do |i|end

    erb
    erb
    <% items = ['a', 'b', 'c'] %>
    <%# output: `...` %>
    <% [0..items.length].each do %>.<% end %>
    <%# output: `a b c ` %>
    <% items.each do |item| %>
    <%= item %>
    <% end %>
    erb
    <% items = ['a', 'b', 'c'] %>
    <%# output: `...` %>
    <% [0..items.length].each do %>.<% end %>
    <%# output: `a b c ` %>
    <% items.each do |item| %>
    <%= item %>
    <% end %>
  • Twig: for i in nendfor

    twig
    twig
    {% set items = ['a','b','c'] %}
    {# output: `...` #}
    {% for i in 0..items.length %}.{% endfor %}
    {# output: `a b c ` #}
    {% for item in items %}
    {{item}}
    {% endfor %}
    twig
    {% set items = ['a','b','c'] %}
    {# output: `...` #}
    {% for i in 0..items.length %}.{% endfor %}
    {# output: `a b c ` #}
    {% for item in items %}
    {{item}}
    {% endfor %}

Using the loop index, 0-indexed

  • ERB:

    • n.each_with_index do |i, index|end

      erb
      erb
      <%# output: `0. a 1. b 2. c ` %>
      <% items = ['a', 'b', 'c'] %>
      <% items.each_with_index do |item,index| %>
      <%= index %>. <%= item %>
      <% end %>
      erb
      <%# output: `0. a 1. b 2. c ` %>
      <% items = ['a', 'b', 'c'] %>
      <% items.each_with_index do |item,index| %>
      <%= index %>. <%= item %>
      <% end %>
    • n.times do |i|end

      erb
      erb
      <%# output: `0 1 2 3 4 5 6 7 8 9` %>
      <% 10.times do |i| %><%= i %> <% end %>
      erb
      <%# output: `0 1 2 3 4 5 6 7 8 9` %>
      <% 10.times do |i| %><%= i %> <% end %>
  • Twig: loop.index0

    twig
    twig
    {% for item in items %}
    {{loop.index0}}. {{item}}
    {% endfor %}
    twig
    {% for item in items %}
    {{loop.index0}}. {{item}}
    {% endfor %}

Using the loop index, 1-indexed

  • ERB:

    • .each_with_index’s index is always 0-indexed, so add 1

      erb
      erb
      <% items.each_with_index do |item,index| %>
      <%= index + 1 %>. <%= item %>
      <% end %>
      erb
      <% items.each_with_index do |item,index| %>
      <%= index + 1 %>. <%= item %>
      <% end %>
    • n.times do |i|end

      erb
      erb
      <%# output: `1 2 3 4 5 6 7 8 9 10 ` %>
      <% 10.times do |i| %><%= i %> <% end %>
      erb
      <%# output: `1 2 3 4 5 6 7 8 9 10 ` %>
      <% 10.times do |i| %><%= i %> <% end %>
  • Twig: loop.index

    twig
    twig
    {% for item in items %}
    {{loop.index}}. {{item}}
    {% endfor %}
    twig
    {% for item in items %}
    {{loop.index}}. {{item}}
    {% endfor %}

Iterating a certain number of times

  • ERB: n.times do |i|end

    erb
    erb
    <% n = 3 %>
    <%# output: `...` %>
    <% n.times do %>.<% end %>
    <%# output: `1 2 3 ` %>
    <% n.times do |i| %>
    <%= i %>
    <% end %>
    erb
    <% n = 3 %>
    <%# output: `...` %>
    <% n.times do %>.<% end %>
    <%# output: `1 2 3 ` %>
    <% n.times do |i| %>
    <%= i %>
    <% end %>
  • Twig: for i in nendfor

    twig
    twig
    {% set items = ['a','b','c'] %}
    {# output: `...` #}
    {% for i in 0..items.length %}.{% endfor %}
    {# output: `a b c ` #}
    {% for item in items %}
    {{item}}
    {% endfor %}
    twig
    {% set items = ['a','b','c'] %}
    {# output: `...` #}
    {% for i in 0..items.length %}.{% endfor %}
    {# output: `a b c ` #}
    {% for item in items %}
    {{item}}
    {% endfor %}

Inspecting data

  • ERB: several options for formatting an object’s data, notably: simply outputting, .inspecting, 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
    erb
    <%# for some object `posts` %>
    <%= posts %>
    <%= posts.inspect %>
    <%= debug(posts) %>
    erb
    <%# for some object `posts` %>
    <%= posts %>
    <%= posts.inspect %>
    <%= debug(posts) %>
  • Twig:

    • The |json_encode() filter formats an object’s data.

      twig
      twig
      {# for some object `posts` #}
      {{ posts|json_encode }}
      twig
      {# for some object `posts` #}
      {{ posts|json_encode }}
    • The dump() function outputs information about a variable.

      twig
      twig
      {# for some object `posts` #}
      {{ dump(posts) }}
      twig
      {# for some object `posts` #}
      {{ dump(posts) }}

      Note: dump must be enabled. Some implementations make it available out of the box (for example, Craft CMS in dev mode).

Slicing

  • ERB: .slice(index), .slice(start,count)

    erb
    erb
    <%= [1,2,3,4].slice(1) %> <%# output: `2` %>
    <%= [1,2,3,4].slice(1,2) %> <%# output: `[2,3]` %>
    erb
    <%= [1,2,3,4].slice(1) %> <%# output: `2` %>
    <%= [1,2,3,4].slice(1,2) %> <%# output: `[2,3]` %>
  • Twig: |slice(start,count) or [start:count]

    twig
    twig
    {{ [1,2,3,4]|slice(1) }} {# output: `Array` #}
    {{ [1,2,3,4]|slice(1,2) }} {# output: `Array` #}
    twig
    {{ [1,2,3,4]|slice(1) }} {# output: `Array` #}
    {{ [1,2,3,4]|slice(1,2) }} {# output: `Array` #}

    Note: The output of the above Twig examples is Array, because in Twig the output of {{ [anArray] }} is Array. If you need to print an array, use |json_encode:

    twig
    twig
    {{ [1,2,3,4]|slice(1)|json_encode() }} {# output: `[2,3,4]` #}
    {{ [1,2,3,4]|slice(1,2)|json_encode() }} {# output: `[2,3]` #}
    twig
    {{ [1,2,3,4]|slice(1)|json_encode() }} {# output: `[2,3,4]` #}
    {{ [1,2,3,4]|slice(1,2)|json_encode() }} {# output: `[2,3]` #}

    In execution, no special steps are necessary:

    twig
    twig
    {% set myArray = [1,2,3,4] %}
    twig
    {% set myArray = [1,2,3,4] %}

Shorthand to slice the first count items

  • ERB: .take(count) or .first(count)

    erb
    erb
    <%= [1,2,3,4].take(2) %> <%# output: `[1,2]` %>
    <%= [1,2,3,4].first(2) %> <%# output: `[1,2]` %>
    erb
    <%= [1,2,3,4].take(2) %> <%# output: `[1,2]` %>
    <%= [1,2,3,4].first(2) %> <%# output: `[1,2]` %>
  • Twig: [:count]

    twig
    twig
    {{ [1,2,3,4][:2]|json_encode() }} {# output: `[1,2]` #}
    twig
    {{ [1,2,3,4][:2]|json_encode() }} {# output: `[1,2]` #}

Shorthand for everything after the start item

  • Twig: [start:]

    twig
    twig
    {{ [1,2,3,4][2:]|json_encode() }} {# output: `[3,4]` #}
    twig
    {{ [1,2,3,4][2:]|json_encode() }} {# output: `[3,4]` #}

Trimming whitespace

  • ERB

    If trim_mode is set to -, a - in the closing erb tag will trim trailing whitespace:

    erb
    erb
    <% something -%>
    1
    <%= something_else -%>
    2
    <% another_thing %>
    erb
    <% something -%>
    1
    <%= something_else -%>
    2
    <% another_thing %>

    is equivalent to

    erb
    erb
    <% something %>1
    <%= something_else %>2
    <% another_thing %>
    erb
    <% something %>1
    <%= something_else %>2
    <% another_thing %>
  • Twig

    Trim leading or trailing whitespace by adding a - inside in an opening or close delimiter, respectively:

    twig
    twig
    {% something -%}
    1
    {%- something_else -%}
    2
    {%- last_thing %}
    twig
    {% something -%}
    1
    {%- something_else -%}
    2
    {%- last_thing %}

    is equivalent to

    twig
    twig
    {% something %}1{% something_else %}2{% last_thing %}
    twig
    {% something %}1{% something_else %}2{% last_thing %}

Trimming space between HTML elements

  • Twig

    Twig doesn’t care what language you are compiling to, but it does provide a special spaceless tag for use with HTML.

    twig
    twig
    {% spaceless %}
    <div>…</div>
    <span>…</span>
    {% endspaceless %}
    twig
    {% spaceless %}
    <div>…</div>
    <span>…</span>
    {% endspaceless %}

    is equivalent to

    twig
    twig
    <div>…</div><span>…</span>
    twig
    <div>…</div><span>…</span>

    Note that this spaceless has limited powers:

    • it isn’t recursive

      twig
      twig
      {% spaceless %}
      <div>
      <div>
      </div>
      <div>
      <span>…</span>
      {% endspaceless %}
      twig
      {% spaceless %}
      <div>
      <div>
      </div>
      <div>
      <span>…</span>
      {% endspaceless %}

      is equivalent to

      twig
      twig
      <div><div>
      </div><div><span>…</span>
      twig
      <div><div>
      </div><div><span>…</span>
    • and content between HTML tags will disrupt it

      twig
      twig
      {% spaceless %}
      <div>…</div>
      sorry, spaceless
      <span>…</span>
      {% endspaceless %}
      twig
      {% spaceless %}
      <div>…</div>
      sorry, spaceless
      <span>…</span>
      {% endspaceless %}

      is equivalent to

      twig
      twig
      <div>…</div>
      sorry, spaceless
      <span>…</span>
      twig
      <div>…</div>
      sorry, spaceless
      <span>…</span>

Keyed values

  • ERB:

    Use a Symbol :property to look up an operation on a Hash:

    erb
    erb
    <% myHash = {hello: 'world'} %>
    <%= myHash[:hello] %> <%# output: "world" %>
    erb
    <% myHash = {hello: 'world'} %>
    <%= myHash[:hello] %> <%# output: "world" %>
  • Twig:

    Use dot notation or subscript syntax to access attributes of a variable:

    twig
    twig
    {% set myVar = {hello: 'world'} %}
    {{ myVar.hello }} {# output: world #}
    {{ myVar['hello'] }} {# output: world #}
    twig
    {% set myVar = {hello: 'world'} %}
    {{ myVar.hello }} {# output: world #}
    {{ myVar['hello'] }} {# output: world #}

Vertical inheritance

For a layout file that pulls in page:

  • ERB: content_for in child, yield in parent

    layouts/layout.html.erb

    erb
    erb
    <%= yield :myBlock %>
    erb
    <%= yield :myBlock %>

    views/page.html.erb

    erb
    erb
    <% content_for :myBlock do %>
    the content
    <% end %>
    erb
    <% content_for :myBlock do %>
    the content
    <% end %>
  • Twig: block + extends in child, block in parent.

    layout.html.twig

    twig
    twig
    {% block myBlock '' %}
    {# or #}
    {% block myBlock %}{% endblock %}
    {# or #}
    {% block myBlock %}{% endblock myBlock %}
    twig
    {% block myBlock '' %}
    {# or #}
    {% block myBlock %}{% endblock %}
    {# or #}
    {% block myBlock %}{% endblock myBlock %}

    page.html.twig

    twig
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock %}
    the content
    {% endblock %}
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock %}
    the content
    {% endblock %}

    or if all the content is a variable x, page.html.twig

    twig
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock x %}
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock x %}

    or if all the content is a single string, page.html.twig

    twig
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock "#{x} content" %}
    {# or #}
    {% extends 'layout.html.twig' %}
    {% block myBlock x ~ "content" %}
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock "#{x} content" %}
    {# or #}
    {% extends 'layout.html.twig' %}
    {% block myBlock x ~ "content" %}

    or if all the content is a single literal string, page.html.twig

    twig
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock 'the content' %}
    {# or #}
    {% block myBlock "the content" %}
    twig
    {% extends 'layout.html.twig' %}
    {% block myBlock 'the content' %}
    {# or #}
    {% block myBlock "the content" %}

Vertical inheritance with default content in the parent

  • ERB

    layouts/layout.html.erb

    erb
    erb
    <% if content_for?(:my_content) %>
    <%= yield :my_content %>
    <% else %>
    default content
    <% end %>
    erb
    <% if content_for?(:my_content) %>
    <%= yield :my_content %>
    <% else %>
    default content
    <% end %>

    views/page.html.erb

    erb
    erb
    <% content_for :my_content do %>
    the content
    <% end %>
    erb
    <% content_for :my_content do %>
    the content
    <% end %>
  • Twig

    main.html.twig

    twig
    twig
    {% block content %}
    default content
    {% block sub_content '' %}
    {% endblock %}
    twig
    {% block content %}
    default content
    {% block sub_content '' %}
    {% endblock %}

    override-content.html.twig

    twig
    twig
    {% extends 'main.html.twig' %}
    {% block content %}
    the content
    {% endblock %}
    twig
    {% extends 'main.html.twig' %}
    {% block content %}
    the content
    {% endblock %}

    Result of override-content.html.twig:

    default content
    default content

    override-subcontent.html.twig

    twig
    twig
    {% extends 'main.html.twig' %}
    {% block subcontent %}
    the sub-content
    {% endblock %}
    twig
    {% extends 'main.html.twig' %}
    {% block subcontent %}
    the sub-content
    {% endblock %}

    Result of override-subcontent.html.twig:

    default content
    the sub-content
    default content
    the sub-content

Using partials

  • ERB:

    render will output the contents of another file

    erb
    erb
    <%= render 'path/to/x' %>
    erb
    <%= render 'path/to/x' %>

    To pass values to the rendered file, define them:

    erb
    erb
    <% a = 1 %>
    <% b = 2 %>
    <%= render 'path/to/x', a:a, b:b %> <%# in path/to/x a=1 and b=2 %>
    erb
    <% a = 1 %>
    <% b = 2 %>
    <%= render 'path/to/x', a:a, b:b %> <%# in path/to/x a=1 and b=2 %>

    If the rendered file expects different variable names, use those:

    erb
    erb
    <% a = 1 %>
    <% b = 2 %>
    <%= render 'path/to/x', y:a, z:b %> <%# in path/to/x y=1 and z=2 %>
    erb
    <% a = 1 %>
    <% b = 2 %>
    <%= render 'path/to/x', y:a, z:b %> <%# in path/to/x y=1 and z=2 %>
  • Twig:

    • include tag

      twig
      twig
      {% include 'path/to/x' %}
      twig
      {% include 'path/to/x' %}
    • include function

      twig
      twig
      {{ include('path/to/x') }}
      twig
      {{ include('path/to/x') }}

    The include tag passes the entire parent context to the included file by default:

    twig
    twig
    {% set a = 1 %}
    {% set b = 2 %}
    {% include 'path/to/x' %} {# in path/to/x a=1 and b=2 #}
    twig
    {% set a = 1 %}
    {% set b = 2 %}
    {% include 'path/to/x' %} {# in path/to/x a=1 and b=2 #}

    To pass only certain data, use include with only:

    twig
    twig
    {% set a = 1 %}
    {% set b = 2 %}
    {% include 'path/to/x' with {a:a} only %}
    {# in path/to/x a=1 and b does not exist #}
    twig
    {% set a = 1 %}
    {% set b = 2 %}
    {% include 'path/to/x' with {a:a} only %}
    {# in path/to/x a=1 and b does not exist #}

    Rename variables in the with (can be combined with only):

    twig
    twig
    {% set a = 1 %}
    {% include 'path/to/x' with {y:a} %} {# in path/to/x a=1 and y=1 #}
    {% include 'path/to/z' with {y:a} only %}
    {# in path/to/z y=1 and a does not exist #}
    twig
    {% set a = 1 %}
    {% include 'path/to/x' with {y:a} %} {# in path/to/x a=1 and y=1 #}
    {% include 'path/to/z' with {y:a} only %}
    {# in path/to/z y=1 and a does not exist #}

Articles You Might Enjoy

Or Go To All Articles