class ERB

Die Klasse ERB (der Name steht für Embedded Ruby) ist ein einfach zu bedienender, aber auch sehr leistungsfähiger Template-Prozessor.

Verwendung

Bevor Sie ERB verwenden können, müssen Sie es zuerst anfordern (die Beispiele auf dieser Seite gehen davon aus, dass dies geschehen ist)

require 'erb'

Kurz gesagt

So funktioniert ERB

ERB unterstützt drei Arten von Tags

Einige einfache Beispiele

Hier ist ein einfaches Beispiel für ERB in Aktion

template = 'The time is <%= Time.now %>.'
erb = ERB.new(template)
erb.result
# => "The time is 2025-09-09 10:49:26 -0500."

Details

  1. Eine Plain-Text-Zeichenkette wird der Variablen template zugewiesen. Ihr eingebetteter Ausdrucks-Tag '<%= Time.now %>' enthält einen Ruby-Ausdruck, Time.now.

  2. Die Zeichenkette wird in ein neues ERB-Objekt eingefügt und in der Variablen erb gespeichert.

  3. Der Methodenaufruf erb.result generiert eine Zeichenkette, die den Laufzeitwert von Time.now enthält, wie er zum Zeitpunkt des Aufrufs berechnet wurde.

Das ERB-Objekt kann wiederverwendet werden

erb.result
# => "The time is 2025-09-09 10:49:33 -0500."

Ein weiteres Beispiel

template = 'The magic word is <%= magic_word %>.'
erb = ERB.new(template)
magic_word = 'abracadabra'
erb.result(binding)
# => "The magic word is abracadabra."

Details

  1. Wie zuvor wird eine Plain-Text-Zeichenkette der Variablen template zugewiesen. Ihr eingebetteter Ausdrucks-Tag '<%= magic_word %>' hat einen Variablennamen, magic_word.

  2. Die Zeichenkette wird in ein neues ERB-Objekt eingefügt und in der Variablen erb gespeichert; beachten Sie, dass magic_word nicht definiert sein muss, bevor das ERB-Objekt erstellt wird.

  3. magic_word = 'abracadabra' weist der Variablen magic_word einen Wert zu.

  4. Der Methodenaufruf erb.result(binding) generiert eine Zeichenkette, die den Wert von magic_word enthält.

Wie zuvor kann das ERB-Objekt wiederverwendet werden

magic_word = 'xyzzy'
erb.result(binding)
# => "The magic word is xyzzy."

Bindings

Ein Aufruf der Methode result, die die formatierte Ergebniszeichenkette erzeugt, erfordert ein Binding-Objekt als Argument.

Das Binding-Objekt stellt die Bindungen für Ausdrücke in Ausdrucks-Tags bereit.

Es gibt drei Möglichkeiten, das erforderliche Binding bereitzustellen

Standard-Binding

Wenn Sie kein binding-Argument an die Methode new_toplevel übergeben, verwendet die Methode ihr Standard-Binding: das von der Methode new_toplevel zurückgegebene. Dieses Binding hat die von Ruby selbst definierten Bindungen, also die für Rubys Konstanten und Variablen.

Dieses Binding ist ausreichend für einen Ausdrucks-Tag, der sich nur auf Rubys Konstanten und Variablen bezieht; diese Ausdrucks-Tags beziehen sich nur auf Rubys globale Konstante RUBY_COPYRIGHT und die globale Variable $0

template = <<TEMPLATE
The Ruby copyright is <%= RUBY_COPYRIGHT.inspect %>.
The current process is <%= $0 %>.
TEMPLATE
puts ERB.new(template).result
The Ruby copyright is "ruby - Copyright (C) 1993-2025 Yukihiro Matsumoto".
The current process is irb.

(Der aktuelle Prozess ist irb, da wir dort diese Beispiele durchführen!)

Lokales Binding

Das Standard-Binding ist für einen Ausdruck, der sich auf eine Konstante oder Variable bezieht, die dort nicht definiert ist, nicht ausreichend.

Foo = 1 # Defines local constant Foo.
foo = 2 # Defines local variable foo.
template = <<TEMPLATE
The current value of constant Foo is <%= Foo %>.
The current value of variable foo is <%= foo %>.
The Ruby copyright is <%= RUBY_COPYRIGHT.inspect %>.
The current process is <%= $0 %>.
TEMPLATE
erb = ERB.new(template)

Dieser Aufruf unten löst eine NameError aus, weil obwohl Foo und foo lokal definiert sind, sie nicht im Standard-Binding definiert sind.

erb.result # Raises NameError.

Um die lokal definierten Konstanten und Variablen verfügbar zu machen, können Sie result mit dem lokalen Binding aufrufen.

puts erb.result(binding)
The current value of constant Foo is 1.
The current value of variable foo is 2.
The Ruby copyright is "ruby - Copyright (C) 1993-2025 Yukihiro Matsumoto".
The current process is irb.

Erweitertes Binding

Eine weitere Möglichkeit, Variablen-Bindungen (aber keine Konstanten-Bindungen) verfügbar zu machen, ist die Verwendung der Methode result_with_hash(hash); der übergebene Hash enthält Namens-/Wertpaare, die zur Definition und Zuweisung von Variablen in einer Kopie des Standard-Bindings verwendet werden.

template = <<TEMPLATE
The current value of variable bar is <%= bar %>.
The current value of variable baz is <%= baz %>.
The Ruby copyright is <%= RUBY_COPYRIGHT.inspect %>.
The current process is <%= $0 %>.
TEMPLATE
erb = ERB.new(template)

Beide diese Aufrufe lösen eine NameError aus, weil bar und baz weder im Standard-Binding noch im lokalen Binding definiert sind.

puts erb.result          # Raises NameError.
puts erb.result(binding) # Raises NameError.

Dieser Aufruf übergibt einen Hash, der bewirkt, dass bar und baz in einem neuen Binding definiert werden (abgeleitet von new_toplevel).

hash = {bar: 3, baz: 4}
puts erb.result_with_hash(hash)
The current value of variable bar is 3.
The current value of variable baz is 4.
The Ruby copyright is "ruby - Copyright (C) 1993-2025 Yukihiro Matsumoto".
The current process is irb.

Tags

Die obigen Beispiele verwenden Ausdrucks-Tags. Dies sind die verfügbaren Tags in ERB.

Ausdrucks-Tags

Sie können einen Ruby-Ausdruck in ein Template einbetten, indem Sie einen Ausdrucks-Tag verwenden.

Seine Syntax lautet <%= Ausdruck %>, wobei Ausdruck jeder gültige Ruby-Ausdruck ist.

Wenn Sie die Methode result aufrufen, wertet die Methode den Ausdruck aus und ersetzt den gesamten Ausdrucks-Tag durch den Wert des Ausdrucks.

ERB.new('Today is <%= Date::DAYNAMES[Date.today.wday] %>.').result
# => "Today is Monday."
ERB.new('Tomorrow will be <%= Date::DAYNAMES[Date.today.wday + 1] %>.').result
# => "Tomorrow will be Tuesday."
ERB.new('Yesterday was <%= Date::DAYNAMES[Date.today.wday - 1] %>.').result
# => "Yesterday was Sunday."

Beachten Sie, dass Leerzeichen vor und nach dem Ausdruck erlaubt, aber nicht erforderlich sind und dass solche Leerzeichen aus dem Ergebnis entfernt werden.

ERB.new('My appointment is on <%=Date::DAYNAMES[Date.today.wday + 2]%>.').result
# => "My appointment is on Wednesday."
ERB.new('My appointment is on <%=     Date::DAYNAMES[Date.today.wday + 2]    %>.').result
# => "My appointment is on Wednesday."

Ausführungs-Tags

Sie können ausführbaren Ruby-Code in ein Template einbetten, indem Sie einen Ausführungs-Tag verwenden.

Seine Syntax lautet <% Code %>, wobei Code jeder gültige Ruby-Code ist.

Wenn Sie die Methode result aufrufen, führt die Methode den Code aus und entfernt den gesamten Ausführungs-Tag (erzeugt keinen Text im Ergebnis).

ERB.new('foo <% Dir.chdir("C:/") %> bar').result # => "foo  bar"

Leerzeichen vor und nach dem eingebetteten Code sind optional.

ERB.new('foo <%Dir.chdir("C:/")%> bar').result   # => "foo  bar"

Sie können Text mit Ausführungs-Tags verschachteln, um eine Kontrollstruktur wie eine Bedingung, eine Schleife oder eine case-Anweisung zu bilden.

Bedingung

template = <<TEMPLATE
<% if verbosity %>
An error has occurred.
<% else %>
Oops!
<% end %>
TEMPLATE
erb = ERB.new(template)
verbosity = true
erb.result(binding)
# => "\nAn error has occurred.\n\n"
verbosity = false
erb.result(binding)
# => "\nOops!\n\n"

Beachten Sie, dass der verschachtelte Text selbst Ausdrucks-Tags enthalten kann.

Schleife

template = <<TEMPLATE
<% Date::ABBR_DAYNAMES.each do |dayname| %>
<%= dayname %>
<% end %>
TEMPLATE
ERB.new(template).result
# => "\nSun\n\nMon\n\nTue\n\nWed\n\nThu\n\nFri\n\nSat\n\n"

Andere, nicht-steuernde Zeilen von Ruby-Code können mit dem Text verschachtelt werden, und der Ruby-Code kann selbst reguläre Ruby-Kommentare enthalten.

template = <<TEMPLATE
<% 3.times do %>
<%= Time.now %>
<% sleep(1) # Let's make the times different. %>
<% end %>
TEMPLATE
ERB.new(template).result
# => "\n2025-09-09 11:36:02 -0500\n\n\n2025-09-09 11:36:03 -0500\n\n\n2025-09-09 11:36:04 -0500\n\n\n"

Der Ausführungs-Tag kann auch mehrere Codezeilen enthalten.

template = <<TEMPLATE
<%
  (0..2).each do |i|
    (0..2).each do |j|
%>
* <%=i%>,<%=j%>
<%
    end
  end
%>
TEMPLATE
ERB.new(template).result
# => "\n* 0,0\n\n* 0,1\n\n* 0,2\n\n* 1,0\n\n* 1,1\n\n* 1,2\n\n* 2,0\n\n* 2,1\n\n* 2,2\n\n"

Kurzform für Ausführungs-Tags

Sie können das Schlüsselwortargument trim_mode: '%' verwenden, um eine Kurzform für Ausführungs-Tags zu aktivieren; dieses Beispiel verwendet die Kurzform % Code anstelle von <% Code %>.

template = <<TEMPLATE
% priorities.each do |priority|
  * <%= priority %>
% end
TEMPLATE
erb = ERB.new(template, trim_mode: '%')
priorities = [ 'Run Ruby Quiz',
               'Document Modules',
               'Answer Questions on Ruby Talk' ]
puts erb.result(binding)
  * Run Ruby Quiz
  * Document Modules
  * Answer Questions on Ruby Talk

Beachten Sie, dass in der Kurzform das Zeichen '%' das erste Zeichen in der Codezeile sein muss (keine führenden Leerzeichen).

Unterdrücken unerwünschter Leerzeilen

Wenn das Schlüsselwortargument trim_mode nicht angegeben ist, gehen alle Leerzeilen in das Ergebnis ein.

template = <<TEMPLATE
<% if true %>
<%= RUBY_VERSION %>
<% end %>
TEMPLATE
ERB.new(template).result.lines.each {|line| puts line.inspect }
"\n"
"3.4.5\n"
"\n"

Sie können trim_mode: '-' angeben, um jede Leerzeile zu unterdrücken, deren Quellzeile mit -%> endet (anstelle von %>).

template = <<TEMPLATE
<% if true -%>
<%= RUBY_VERSION %>
<% end -%>
TEMPLATE
ERB.new(template, trim_mode: '-').result.lines.each {|line| puts line.inspect }
"3.4.5\n"

Es ist ein Fehler, die nachgestellte '-%>'-Notation ohne trim_mode: '-' zu verwenden.

ERB.new(template).result.lines.each {|line| puts line.inspect } # Raises SyntaxError.

Unterdrücken unerwünschter Zeilenumbrüche

Betrachten Sie dieses Template

template = <<TEMPLATE
<% RUBY_VERSION %>
<%= RUBY_VERSION %>
foo <% RUBY_VERSION %>
foo <%= RUBY_VERSION %>
TEMPLATE

Wenn das Schlüsselwortargument trim_mode nicht angegeben ist, gehen alle Zeilenumbrüche in das Ergebnis ein.

ERB.new(template).result.lines.each {|line| puts line.inspect }
"\n"
"3.4.5\n"
"foo \n"
"foo 3.4.5\n"

Sie können trim_mode: '>' angeben, um den nachgestellten Zeilenumbruch für jede Zeile zu unterdrücken, die mit '%>' endet (unabhängig von ihrem Anfang).

ERB.new(template, trim_mode: '>').result.lines.each {|line| puts line.inspect }
"3.4.5foo foo 3.4.5"

Sie können trim_mode: '<>' angeben, um den nachgestellten Zeilenumbruch für jede Zeile zu unterdrücken, die sowohl mit '<%' beginnt als auch mit '%>' endet.

ERB.new(template, trim_mode: '<>').result.lines.each {|line| puts line.inspect }
"3.4.5foo \n"
"foo 3.4.5\n"

Kombinieren von Trim-Modi

Sie können bestimmte Trim-Modi kombinieren.

Kommentar-Tags

Sie können einen Kommentar in ein Template einbetten, indem Sie einen Kommentar-Tag verwenden; seine Syntax lautet <%# Text %>, wobei Text der Text des Kommentars ist.

Wenn Sie die Methode result aufrufen, entfernt sie den gesamten Kommentar-Tag (erzeugt keinen Text im Ergebnis).

Beispiel

template = 'Some stuff;<%# Note to self: figure out what the stuff is. %> more stuff.'
ERB.new(template).result # => "Some stuff; more stuff."

Ein Kommentar-Tag kann überall im Template erscheinen.

Beachten Sie, dass der Anfang des Tags '<%#' sein muss, nicht '<% #'.

In diesem Beispiel beginnt der Tag mit '<% #' und ist daher ein Ausführungs-Tag, kein Kommentar-Tag; der zitierte Code besteht ausschließlich aus einem Ruby-ähnlichen Kommentar (der natürlich ignoriert wird).

ERB.new('Some stuff;<% # Note to self: figure out what the stuff is. %> more stuff.').result
# => "Some stuff;"

Kodierungen

Ein ERB-Objekt hat eine Kodierung, die standardmäßig die Kodierung der Template-Zeichenkette ist; die Ergebniszeichenkette wird ebenfalls diese Kodierung haben.

template = <<TEMPLATE
<%# Comment. %>
TEMPLATE
erb = ERB.new(template)
template.encoding   # => #<Encoding:UTF-8>
erb.encoding        # => #<Encoding:UTF-8>
erb.result.encoding # => #<Encoding:UTF-8>

Sie können eine andere Kodierung angeben, indem Sie einen Magic Comment am Anfang des gegebenen Templates hinzufügen.

template = <<TEMPLATE
<%#-*- coding: Big5 -*-%>
<%# Comment. %>
TEMPLATE
erb = ERB.new(template)
template.encoding   # => #<Encoding:UTF-8>
erb.encoding        # => #<Encoding:Big5>
erb.result.encoding # => #<Encoding:Big5>

Fehlerberichterstattung

Betrachten Sie dieses Template (enthält einen Fehler).

template = '<%= nosuch %>'
erb = ERB.new(template)

Wenn ERB einen Fehler meldet, enthält es einen Dateinamen (falls verfügbar) und eine Zeilennummer; der Dateiname stammt von der Methode filename, die Zeilennummer von der Methode lineno.

Anfangs sind diese Werte nil und 0; diese Anfangswerte werden als '(erb)' und 1 gemeldet.

erb.filename # => nil
erb.lineno   # => 0
erb.result
(erb):1:in '<main>': undefined local variable or method 'nosuch' for main (NameError)

Sie können die Methoden filename= und lineno= verwenden, um Werte zuzuweisen, die in Ihrem Kontext aussagekräftiger sind.

erb.filename = 't.txt'
erb.lineno = 555
erb.result
t.txt:556:in '<main>': undefined local variable or method 'nosuch' for main (NameError)

Sie können die Methode location= verwenden, um beide Werte festzulegen.

erb.location = ['u.txt', 999]
erb.result
u.txt:1000:in '<main>': undefined local variable or method 'nosuch' for main (NameError)

Plain Text mit eingebettetem Ruby

Hier ist ein Plain-Text-Template; es verwendet die literale Notation '%q{ ... }', um das Template zu definieren (siehe %q Literale); dies vermeidet Probleme mit Backslashes.

template = %q{
From:  James Edward Gray II <james@grayproductions.net>
To:  <%= to %>
Subject:  Addressing Needs

<%= to[/\w+/] %>:

Just wanted to send a quick note assuring that your needs are being
addressed.

I want you to know that my team will keep working on the issues,
especially:

<%# ignore numerous minor requests -- focus on priorities %>
% priorities.each do |priority|
  * <%= priority %>
% end

Thanks for your patience.

James Edward Gray II
}

Das Template benötigt diese.

to = 'Community Spokesman <spokesman@ruby_community.org>'
priorities = [ 'Run Ruby Quiz',
               'Document Modules',
               'Answer Questions on Ruby Talk' ]

Schließlich erstellen Sie das ERB-Objekt und erhalten das Ergebnis.

erb = ERB.new(template, trim_mode: '%<>')
puts erb.result(binding)

From:  James Edward Gray II <james@grayproductions.net>
To:  Community Spokesman <spokesman@ruby_community.org>
Subject:  Addressing Needs

Community:

Just wanted to send a quick note assuring that your needs are being
addressed.

I want you to know that my team will keep working on the issues,
especially:

* Run Ruby Quiz
* Document Modules
* Answer Questions on Ruby Talk

Thanks for your patience.

James Edward Gray II

HTML mit eingebettetem Ruby

Dieses Beispiel zeigt ein HTML-Template.

Zuerst hier eine benutzerdefinierte Klasse, Product.

class Product
  def initialize(code, name, desc, cost)
    @code = code
    @name = name
    @desc = desc
    @cost = cost
    @features = []
  end

  def add_feature(feature)
    @features << feature
  end

  # Support templating of member data.
  def get_binding
    binding
  end

end

Das folgende Template benötigt diese Werte.

toy = Product.new('TZ-1002',
                  'Rubysapien',
                  "Geek's Best Friend!  Responds to Ruby commands...",
                  999.95
                  )
toy.add_feature('Listens for verbal commands in the Ruby language!')
toy.add_feature('Ignores Perl, Java, and all C variants.')
toy.add_feature('Karate-Chop Action!!!')
toy.add_feature('Matz signature on left leg.')
toy.add_feature('Gem studded eyes... Rubies, of course!')

Hier ist das HTML.

template = <<TEMPLATE
<html>
  <head><title>Ruby Toys -- <%= @name %></title></head>
  <body>
    <h1><%= @name %> (<%= @code %>)</h1>
    <p><%= @desc %></p>
    <ul>
      <% @features.each do |f| %>
        <li><b><%= f %></b></li>
      <% end %>
    </ul>
    <p>
      <% if @cost < 10 %>
        <b>Only <%= @cost %>!!!</b>
      <% else %>
         Call for a price, today!
      <% end %>
    </p>
  </body>
</html>
TEMPLATE

Schließlich erstellen Sie das ERB-Objekt und erhalten das Ergebnis (einige Leerzeilen werden weggelassen).

erb = ERB.new(template)
puts erb.result(toy.get_binding)
<html>
  <head><title>Ruby Toys -- Rubysapien</title></head>
  <body>
    <h1>Rubysapien (TZ-1002)</h1>
    <p>Geek's Best Friend!  Responds to Ruby commands...</p>
    <ul>
        <li><b>Listens for verbal commands in the Ruby language!</b></li>
        <li><b>Ignores Perl, Java, and all C variants.</b></li>
        <li><b>Karate-Chop Action!!!</b></li>
        <li><b>Matz signature on left leg.</b></li>
        <li><b>Gem studded eyes... Rubies, of course!</b></li>
    </ul>
    <p>
         Call for a price, today!
    </p>
  </body>
</html>

Andere Template-Prozessoren

Verschiedene Ruby-Projekte haben ihre eigenen Template-Prozessoren. Das Ruby Processing System RDoc hat zum Beispiel eines, das auch anderswo verwendet werden kann.

Andere beliebte Template-Prozessoren finden Sie auf der Seite Template Engines der Ruby Toolbox.