Nette Documentation Preview

syntax
HTML-Elemente
*************

.[perex]
Die Klasse [api:Nette\Utils\Html] ist ein Helfer zum Erzeugen von HTML-Code, der dabei hilft, Sicherheitslücken durch Cross-Site Scripting (XSS) zu verhindern.


Sie funktioniert so, dass ihre Objekte HTML-Elemente repräsentieren; Sie setzen deren Parameter und rendern sie anschließend:

```php
$el = Html::el('img');  // erzeugt das Element <img>
$el->src = 'image.jpg'; // setzt das Attribut src
echo $el;               // gibt '<img src="image.jpg">' aus
```

Den Körper eines Elements füllen Sie mit der Methode `add()` mit Text und weiteren Elementen. Text wird automatisch escapt, Elemente werden so eingefügt, wie sie sind: .{data-version:4.1.5}

```php
echo Html::el('div')->add(
	'Hallo ',
	Html::el('b')->setText('Welt'),
);
// '<div>Hallo <b>Welt</b></div>'
```

Installation:

```shell
composer require nette/utils
```

Alle Beispiele setzen voraus, dass dieser Klassen-Alias definiert ist:

```php
use Nette\Utils\Html;
```


Erzeugen eines HTML-Elements
============================

Ein Element wird mit der Methode `Html::el()` erzeugt:

```php
$el = Html::el('img'); // erzeugt das Element <img>
```

Neben dem Namen können Sie in HTML-Syntax auch weitere Attribute angeben:

```php
$el = Html::el('input type=text class="red important"');
```

Oder Sie übergeben sie als assoziatives Array im zweiten Parameter:

```php
$el = Html::el('input', [
	'type' => 'text',
	'class' => 'important',
]);
```

So ändern und lesen Sie den Namen des Elements:

```php
$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, denn <img> ist ein leeres Element
```


HTML-Attribute
==============

Die einzelnen HTML-Attribute lassen sich auf drei Arten setzen und auslesen; welche Ihnen lieber ist, bleibt Ihnen überlassen. Die erste geht über Properties:

```php
$el->src = 'image.jpg'; // setzt das Attribut src

echo $el->src; // 'image.jpg'

unset($el->src);  // entfernt das Attribut
// oder $el->src = null;
```

Die zweite Art sind Methodenaufrufe, die sich anders als das Setzen von Properties verketten lassen:

```php
$el = Html::el('img')->src('image.jpg')->alt('photo');
// <img src="image.jpg" alt="photo">

$el->alt(null); // entfernt das Attribut
```

Und die dritte Art ist die ausführlichste:

```php
$el = Html::el('img')
	->setAttribute('src', 'image.jpg')
	->setAttribute('alt', 'photo');

echo $el->getAttribute('src'); // 'image.jpg'

$el->removeAttribute('alt');
```

Attribute lassen sich mit `addAttributes(array $attrs)` gesammelt setzen und mit `removeAttributes(array $attrNames)` gesammelt entfernen.

Der Wert eines Attributs muss nicht nur ein String sein; für boolesche Attribute lassen sich boolesche Werte verwenden:

```php
$checkbox = Html::el('input')->type('checkbox');
$checkbox->checked = true;  // <input type="checkbox" checked>
$checkbox->checked = false; // <input type="checkbox">
```

Ein Attribut kann auch ein Array von Werten sein, die durch Leerzeichen getrennt ausgegeben werden. Das ist zum Beispiel für CSS-Klassen nützlich:

```php
$el = Html::el('input');
$el->class[] = 'active';
$el->class[] = null; // null wird ignoriert
$el->class[] = 'top';
echo $el; // '<input class="active top">'
```

Eine Alternative ist ein assoziatives Array, dessen Werte angeben, ob der Schlüssel enthalten sein soll:

```php
$el = Html::el('input');
$el->class['active'] = true;
$el->class['top'] = false;
echo $el; // '<input class="active">'
```

CSS-Stile lassen sich als assoziative Arrays schreiben:

```php
$el = Html::el('input');
$el->style['color'] = 'green';
$el->style['display'] = 'block';
echo $el; // '<input style="color:green;display:block">'
```

Bisher haben wir Properties verwendet, dasselbe lässt sich aber auch mit Methoden erreichen:

```php
$el = Html::el('input');
$el->style('color', 'green');
$el->style('display', 'block');
echo $el; // '<input style="color:green;display:block">'
```

Oder sogar auf die ausführlichste Weise:

```php
$el = Html::el('input');
$el->appendAttribute('style', 'color', 'green');
$el->appendAttribute('style', 'display', 'block');
echo $el; // '<input style="color:green;display:block">'
```

Eine letzte Kleinigkeit: Die Methode `href()` kann das Zusammensetzen von Query-Parametern einer URL vereinfachen:

```php
echo Html::el('a')->href('index.php', [
	'id' => 10,
	'lang' => 'en',
]);
// '<a href="index.php?id=10&amp;lang=en"></a>'
```


Data-Attribute
--------------

Data-Attribute werden besonders unterstützt. Weil ihre Namen Bindestriche enthalten, ist der Zugriff über Properties und Methoden nicht so elegant, deshalb gibt es die eigene Methode `data()`:

```php
$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // nicht so elegant
$el->data('max-size', '500x300'); // ist elegant
echo $el; // '<input data-max-size="500x300">'
```

Ist der Wert eines Data-Attributs ein Array, wird er automatisch nach JSON serialisiert:

```php
$el = Html::el('input');
$el->data('items', [1,2,3]);
echo $el; // '<input data-items="[1,2,3]">'
```


Inhalt des Elements
===================

Den inneren Inhalt des Elements setzen Sie mit den Methoden `setHtml()` oder `setText()`. Die erste verwenden Sie nur dann, wenn Sie sicher sind, dass der Parameter einen verlässlich sicheren HTML-String enthält.

```php
echo Html::el('span')->setHtml('hello<br>');
// '<span>hello<br></span>'

echo Html::el('span')->setText('10 < 20');
// '<span>10 &lt; 20</span>'
```

Umgekehrt lässt sich der innere Inhalt mit den Methoden `getHtml()` oder `getText()` auslesen. Die zweite entfernt HTML-Tags aus dem Inhalt und wandelt HTML-Entities zurück in Zeichen.

```php
echo $el->getHtml(); // '10 &lt; 20'
echo $el->getText(); // '10 < 20'
```


Kindknoten
----------

Der innere Inhalt eines Elements kann auch ein Array von Kindknoten sein. Jedes Kind kann entweder ein String oder ein weiteres `Html`-Objekt sein. Hinzugefügt werden sie mit `addHtml()` oder `addText()`:

```php
$el = Html::el('span')
	->addHtml('hello<br>')
	->addText('10 < 20')
	->addHtml( Html::el('br') );
// <span>hello<br>10 &lt; 20<br></span>
```

Die Methode `add()` fügt mehrere Kinder auf einmal ein. Strings werden genauso escapt wie bei `addText()`, `Html`-Objekte werden so eingefügt, wie sie sind, und `null`-Werte werden übersprungen, was sich für bedingte Inhalte anbietet. Einen String, der verlässlich sicheres HTML ist, verpacken Sie in `Html::html()`: .{data-version:4.1.5}

```php
$el = Html::el('span')->add(
	'10 < 20',
	Html::el('br'),
	Html::html('hello<br>'),
	$showNote ? Html::el('small')->setText('note') : null,
);
// <span>10 &lt; 20<br>hello<br><small>note</small></span>
```

Eine weitere Möglichkeit, einen neuen `Html`-Knoten zu erzeugen und einzufügen:

```php
$ul = Html::el('ul');
$ul->create('li', ['class' => 'first'])
	->setText('erster');
// <ul><li class="first">erster</li></ul>
```

Mit den Knoten lässt sich arbeiten, als wären sie Array-Elemente. Sie greifen also über eckige Klammern auf einzelne Knoten zu, zählen sie mit `count()` und iterieren über sie:

```php
$el = Html::el('div');
$el[] = '<b>hello</b>';
$el[] = Html::el('span');
echo $el[1]; // '<span></span>'

foreach ($el as $child) { /* ... */ }

echo count($el); // 2
```

Einen neuen Knoten fügen Sie mit `insert(?int $index, $child, bool $replace = false)` an einer bestimmten Position ein. Ist `$replace = false`, wird das Element an der Position `$index` eingefügt und die übrigen werden verschoben. Ist `$index = null`, wird das Element ans Ende angehängt.

```php
// fügt das Element an der ersten Position ein und verschiebt die übrigen
$el->insert(0, Html::el('span'));
```

Alle Knoten liefert die Methode `getChildren()`, entfernen lassen sie sich mit der Methode `removeChildren()`.


Erzeugen eines Dokumentfragments
--------------------------------

Wenn Sie mit einer Menge von Knoten arbeiten wollen und kein umschließendes Element brauchen, können Sie ein *Dokumentfragment* erzeugen. Es rendert nur seine Kinder, ohne einen eigenen Tag. Die Methode `fragment()` erzeugt es und füllt es in einem einzigen Aufruf mit Kindern, nach denselben Regeln wie `add()`: .{data-version:4.1.5}

```php
echo Html::fragment(
	Html::el('strong')->setText('hello'),
	'10 < 20',
	Html::el('br'),
);
// <strong>hello</strong>10 &lt; 20<br>
```

Ein Fragment mit ausschließlich Text- oder ausschließlich HTML-Inhalt erzeugen die Methoden `text()` und `html()`: .{data-version:4.1.5}

```php
echo Html::text('10 < 20');   // '10 &lt; 20'
echo Html::html('hello<br>'); // 'hello<br>'
```

Wenn Sie Versionen vor 4.1.5 unterstützen müssen, erzeugen Sie ein Fragment, indem Sie statt eines Elementnamens `null` übergeben, und füllen es mit `addHtml()` und `addText()`. Statt `text()` und `html()` bieten diese Versionen die Methoden `fromText()` und `fromHtml()`, die weiterhin funktionieren, aber veraltet sind:

```php
$el = Html::el(null)
	->addHtml('hello<br>')
	->addText('10 < 20');
// hello<br>10 &lt; 20

echo Html::fromText('10 < 20');   // '10 &lt; 20'
echo Html::fromHtml('hello<br>'); // 'hello<br>'
```


Erzeugen der HTML-Ausgabe
=========================

Am einfachsten geben Sie ein HTML-Element mit `echo` aus oder casten das Objekt nach `(string)`. Sie können auch den öffnenden Tag, den schließenden Tag und die Attribute getrennt ausgeben:

```php
$el = Html::el('div class=header')->setText('hello');

echo $el;               // '<div class="header">hello</div>'
$s = (string) $el;      // '<div class="header">hello</div>'
$s = $el->toHtml();     // '<div class="header">hello</div>'
$s = $el->toText();     // 'hello'
echo $el->startTag();   // '<div class="header">'
echo $el->endTag();     // '</div>'
echo $el->attributes(); // 'class="header"'
```

Die Methode `render(?int $indent = null)` bietet eine hübsche Formatierung. Wenn Sie eine Einrückungsebene übergeben, wird die Ausgabe über mehrere Zeilen sauber eingerückt:

```php
echo $el->render(0); // gibt eingerücktes HTML zurück
```

Eine wichtige Eigenschaft ist der automatische Schutz vor [Cross-Site Scripting (XSS) |nette:glossary#Cross-Site Scripting (XSS)]. Alle Attributwerte und alle über `setText()`, `addText()`, `add()` oder `fragment()` eingefügten Inhalte werden verlässlich escapt:

```php
echo Html::el('div')
	->title('" onmouseover="bad()')
	->setText('<script>bad()</script>');

// <div title='" onmouseover="bad()'>&lt;script&gt;bad()&lt;/script&gt;</div>
```


Umwandlung HTML ↔ Text
======================

Zur Umwandlung von HTML in Text können Sie die statische Methode `htmlToText()` verwenden:

```php
echo Html::htmlToText('<span>One &amp; Two</span>'); // 'One & Two'
```


HtmlStringable
==============

Das Objekt `Nette\Utils\Html` implementiert das Interface `Nette\HtmlStringable`. Latte und Forms nutzen dieses Interface zum Beispiel, um Objekte zu erkennen, deren Methode `__toString()` HTML-Code zurückgibt. Das verhindert doppeltes Escaping, wenn Sie das Objekt etwa im Template mit `{$el}` ausgeben.

HTML-Elemente

Die Klasse Nette\Utils\Html ist ein Helfer zum Erzeugen von HTML-Code, der dabei hilft, Sicherheitslücken durch Cross-Site Scripting (XSS) zu verhindern.

Sie funktioniert so, dass ihre Objekte HTML-Elemente repräsentieren; Sie setzen deren Parameter und rendern sie anschließend:

$el = Html::el('img');  // erzeugt das Element <img>
$el->src = 'image.jpg'; // setzt das Attribut src
echo $el;               // gibt '<img src="image.jpg">' aus

Den Körper eines Elements füllen Sie mit der Methode add() mit Text und weiteren Elementen. Text wird automatisch escapt, Elemente werden so eingefügt, wie sie sind:

echo Html::el('div')->add(
	'Hallo ',
	Html::el('b')->setText('Welt'),
);
// '<div>Hallo <b>Welt</b></div>'

Installation:

composer require nette/utils

Alle Beispiele setzen voraus, dass dieser Klassen-Alias definiert ist:

use Nette\Utils\Html;

Erzeugen eines HTML-Elements

Ein Element wird mit der Methode Html::el() erzeugt:

$el = Html::el('img'); // erzeugt das Element <img>

Neben dem Namen können Sie in HTML-Syntax auch weitere Attribute angeben:

$el = Html::el('input type=text class="red important"');

Oder Sie übergeben sie als assoziatives Array im zweiten Parameter:

$el = Html::el('input', [
	'type' => 'text',
	'class' => 'important',
]);

So ändern und lesen Sie den Namen des Elements:

$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, denn <img> ist ein leeres Element

HTML-Attribute

Die einzelnen HTML-Attribute lassen sich auf drei Arten setzen und auslesen; welche Ihnen lieber ist, bleibt Ihnen überlassen. Die erste geht über Properties:

$el->src = 'image.jpg'; // setzt das Attribut src

echo $el->src; // 'image.jpg'

unset($el->src);  // entfernt das Attribut
// oder $el->src = null;

Die zweite Art sind Methodenaufrufe, die sich anders als das Setzen von Properties verketten lassen:

$el = Html::el('img')->src('image.jpg')->alt('photo');
// <img src="image.jpg" alt="photo">

$el->alt(null); // entfernt das Attribut

Und die dritte Art ist die ausführlichste:

$el = Html::el('img')
	->setAttribute('src', 'image.jpg')
	->setAttribute('alt', 'photo');

echo $el->getAttribute('src'); // 'image.jpg'

$el->removeAttribute('alt');

Attribute lassen sich mit addAttributes(array $attrs) gesammelt setzen und mit removeAttributes(array $attrNames) gesammelt entfernen.

Der Wert eines Attributs muss nicht nur ein String sein; für boolesche Attribute lassen sich boolesche Werte verwenden:

$checkbox = Html::el('input')->type('checkbox');
$checkbox->checked = true;  // <input type="checkbox" checked>
$checkbox->checked = false; // <input type="checkbox">

Ein Attribut kann auch ein Array von Werten sein, die durch Leerzeichen getrennt ausgegeben werden. Das ist zum Beispiel für CSS-Klassen nützlich:

$el = Html::el('input');
$el->class[] = 'active';
$el->class[] = null; // null wird ignoriert
$el->class[] = 'top';
echo $el; // '<input class="active top">'

Eine Alternative ist ein assoziatives Array, dessen Werte angeben, ob der Schlüssel enthalten sein soll:

$el = Html::el('input');
$el->class['active'] = true;
$el->class['top'] = false;
echo $el; // '<input class="active">'

CSS-Stile lassen sich als assoziative Arrays schreiben:

$el = Html::el('input');
$el->style['color'] = 'green';
$el->style['display'] = 'block';
echo $el; // '<input style="color:green;display:block">'

Bisher haben wir Properties verwendet, dasselbe lässt sich aber auch mit Methoden erreichen:

$el = Html::el('input');
$el->style('color', 'green');
$el->style('display', 'block');
echo $el; // '<input style="color:green;display:block">'

Oder sogar auf die ausführlichste Weise:

$el = Html::el('input');
$el->appendAttribute('style', 'color', 'green');
$el->appendAttribute('style', 'display', 'block');
echo $el; // '<input style="color:green;display:block">'

Eine letzte Kleinigkeit: Die Methode href() kann das Zusammensetzen von Query-Parametern einer URL vereinfachen:

echo Html::el('a')->href('index.php', [
	'id' => 10,
	'lang' => 'en',
]);
// '<a href="index.php?id=10&amp;lang=en"></a>'

Data-Attribute

Data-Attribute werden besonders unterstützt. Weil ihre Namen Bindestriche enthalten, ist der Zugriff über Properties und Methoden nicht so elegant, deshalb gibt es die eigene Methode data():

$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // nicht so elegant
$el->data('max-size', '500x300'); // ist elegant
echo $el; // '<input data-max-size="500x300">'

Ist der Wert eines Data-Attributs ein Array, wird er automatisch nach JSON serialisiert:

$el = Html::el('input');
$el->data('items', [1,2,3]);
echo $el; // '<input data-items="[1,2,3]">'

Inhalt des Elements

Den inneren Inhalt des Elements setzen Sie mit den Methoden setHtml() oder setText(). Die erste verwenden Sie nur dann, wenn Sie sicher sind, dass der Parameter einen verlässlich sicheren HTML-String enthält.

echo Html::el('span')->setHtml('hello<br>');
// '<span>hello<br></span>'

echo Html::el('span')->setText('10 < 20');
// '<span>10 &lt; 20</span>'

Umgekehrt lässt sich der innere Inhalt mit den Methoden getHtml() oder getText() auslesen. Die zweite entfernt HTML-Tags aus dem Inhalt und wandelt HTML-Entities zurück in Zeichen.

echo $el->getHtml(); // '10 &lt; 20'
echo $el->getText(); // '10 < 20'

Kindknoten

Der innere Inhalt eines Elements kann auch ein Array von Kindknoten sein. Jedes Kind kann entweder ein String oder ein weiteres Html-Objekt sein. Hinzugefügt werden sie mit addHtml() oder addText():

$el = Html::el('span')
	->addHtml('hello<br>')
	->addText('10 < 20')
	->addHtml( Html::el('br') );
// <span>hello<br>10 &lt; 20<br></span>

Die Methode add() fügt mehrere Kinder auf einmal ein. Strings werden genauso escapt wie bei addText(), Html-Objekte werden so eingefügt, wie sie sind, und null-Werte werden übersprungen, was sich für bedingte Inhalte anbietet. Einen String, der verlässlich sicheres HTML ist, verpacken Sie in Html::html():

$el = Html::el('span')->add(
	'10 < 20',
	Html::el('br'),
	Html::html('hello<br>'),
	$showNote ? Html::el('small')->setText('note') : null,
);
// <span>10 &lt; 20<br>hello<br><small>note</small></span>

Eine weitere Möglichkeit, einen neuen Html-Knoten zu erzeugen und einzufügen:

$ul = Html::el('ul');
$ul->create('li', ['class' => 'first'])
	->setText('erster');
// <ul><li class="first">erster</li></ul>

Mit den Knoten lässt sich arbeiten, als wären sie Array-Elemente. Sie greifen also über eckige Klammern auf einzelne Knoten zu, zählen sie mit count() und iterieren über sie:

$el = Html::el('div');
$el[] = '<b>hello</b>';
$el[] = Html::el('span');
echo $el[1]; // '<span></span>'

foreach ($el as $child) { /* ... */ }

echo count($el); // 2

Einen neuen Knoten fügen Sie mit insert(?int $index, $child, bool $replace = false) an einer bestimmten Position ein. Ist $replace = false, wird das Element an der Position $index eingefügt und die übrigen werden verschoben. Ist $index = null, wird das Element ans Ende angehängt.

// fügt das Element an der ersten Position ein und verschiebt die übrigen
$el->insert(0, Html::el('span'));

Alle Knoten liefert die Methode getChildren(), entfernen lassen sie sich mit der Methode removeChildren().

Erzeugen eines Dokumentfragments

Wenn Sie mit einer Menge von Knoten arbeiten wollen und kein umschließendes Element brauchen, können Sie ein Dokumentfragment erzeugen. Es rendert nur seine Kinder, ohne einen eigenen Tag. Die Methode fragment() erzeugt es und füllt es in einem einzigen Aufruf mit Kindern, nach denselben Regeln wie add():

echo Html::fragment(
	Html::el('strong')->setText('hello'),
	'10 < 20',
	Html::el('br'),
);
// <strong>hello</strong>10 &lt; 20<br>

Ein Fragment mit ausschließlich Text- oder ausschließlich HTML-Inhalt erzeugen die Methoden text() und html():

echo Html::text('10 < 20');   // '10 &lt; 20'
echo Html::html('hello<br>'); // 'hello<br>'

Wenn Sie Versionen vor 4.1.5 unterstützen müssen, erzeugen Sie ein Fragment, indem Sie statt eines Elementnamens null übergeben, und füllen es mit addHtml() und addText(). Statt text() und html() bieten diese Versionen die Methoden fromText() und fromHtml(), die weiterhin funktionieren, aber veraltet sind:

$el = Html::el(null)
	->addHtml('hello<br>')
	->addText('10 < 20');
// hello<br>10 &lt; 20

echo Html::fromText('10 < 20');   // '10 &lt; 20'
echo Html::fromHtml('hello<br>'); // 'hello<br>'

Erzeugen der HTML-Ausgabe

Am einfachsten geben Sie ein HTML-Element mit echo aus oder casten das Objekt nach (string). Sie können auch den öffnenden Tag, den schließenden Tag und die Attribute getrennt ausgeben:

$el = Html::el('div class=header')->setText('hello');

echo $el;               // '<div class="header">hello</div>'
$s = (string) $el;      // '<div class="header">hello</div>'
$s = $el->toHtml();     // '<div class="header">hello</div>'
$s = $el->toText();     // 'hello'
echo $el->startTag();   // '<div class="header">'
echo $el->endTag();     // '</div>'
echo $el->attributes(); // 'class="header"'

Die Methode render(?int $indent = null) bietet eine hübsche Formatierung. Wenn Sie eine Einrückungsebene übergeben, wird die Ausgabe über mehrere Zeilen sauber eingerückt:

echo $el->render(0); // gibt eingerücktes HTML zurück

Eine wichtige Eigenschaft ist der automatische Schutz vor Cross-Site Scripting (XSS). Alle Attributwerte und alle über setText(), addText(), add() oder fragment() eingefügten Inhalte werden verlässlich escapt:

echo Html::el('div')
	->title('" onmouseover="bad()')
	->setText('<script>bad()</script>');

// <div title='" onmouseover="bad()'>&lt;script&gt;bad()&lt;/script&gt;</div>

Umwandlung HTML ↔ Text

Zur Umwandlung von HTML in Text können Sie die statische Methode htmlToText() verwenden:

echo Html::htmlToText('<span>One &amp; Two</span>'); // 'One & Two'

HtmlStringable

Das Objekt Nette\Utils\Html implementiert das Interface Nette\HtmlStringable. Latte und Forms nutzen dieses Interface zum Beispiel, um Objekte zu erkennen, deren Methode __toString() HTML-Code zurückgibt. Das verhindert doppeltes Escaping, wenn Sie das Objekt etwa im Template mit {$el} ausgeben.