Nette Documentation Preview

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

.[perex]
Die Klasse [api:Nette\Utils\Html] ist ein Helfer zur Generierung von HTML-Code, der hilft, Cross-Site-Scripting (XSS)-Schwachstellen zu verhindern.


Sie funktioniert, indem ihre Objekte HTML-Elemente repräsentieren, deren Attribute gesetzt und die dann gerendert werden können:

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

Installation:

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

Alle Beispiele setzen voraus, dass der folgende Alias definiert wurde:

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


Erstellung von HTML-Elementen
=============================

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

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

Neben dem Elementnamen können Sie weitere Attribute direkt in HTML-Syntax angeben:

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

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

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

Ändern und Abrufen des Elementnamens:

```php
$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, da <img> ein leeres Element ist (z.B. <br>, <hr>)
```


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

Einzelne HTML-Attribute können auf drei Arten geändert und gelesen werden, es hängt von Ihnen ab, welche Ihnen am besten gefällt. Die erste ist ü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 Möglichkeit ist der Aufruf von Methoden, die – im Gegensatz zum Setzen von Eigenschaften – verkettet werden können:

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

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

Und die dritte Möglichkeit 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 können gesammelt mit `addAttributes(array $attrs)` gesetzt und mit `removeAttributes(array $attrNames)` entfernt werden.

Der Wert eines Attributs muss kein String sein; für boolesche Attribute können auch boolesche Werte verwendet werden:

```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. Dies ist beispielsweise 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, bei dem die booleschen Werte angeben, ob der jeweilige Schlüssel als Wert ausgegeben werden soll:

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

CSS-Stile können als assoziatives Array geschrieben werden:

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

Wir haben eben Eigenschaften verwendet, aber dasselbe kann auch mit Methoden erreicht werden:

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

Oder 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">'
```

Noch eine Anmerkung: Die Methode `href()` kann das Zusammenstellen von Query-Parametern in URLs vereinfachen:

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


Datenattribute
--------------

Datenattribute (`data-*`) werden besonders unterstützt. Da ihre Namen Bindestriche enthalten, ist der Zugriff über Eigenschaften und Methoden weniger elegant. Daher gibt es die Methode `data()`:

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

Wenn der Wert eines Datenattributs ein Array ist, 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
===================

Der innere Inhalt eines Elements wird mit den Methoden `setHtml()` oder `setText()` festgelegt. Verwenden Sie `setHtml()` nur, wenn Sie sicher sind, dass der übergebene String vertrauenswürdiges HTML 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 wird der innere Inhalt mit den Methoden `getHtml()` oder `getText()` abgerufen. Letztere entfernt HTML-Tags aus dem Inhalt und konvertiert HTML-Entitäten in die entsprechenden Zeichen.

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


Kindknoten
----------

Der Inhalt eines Elements kann auch ein Array von Kindknoten (Children) sein. Jeder Kindknoten kann entweder ein String oder ein weiteres `Html`-Element sein. Sie werden mit `addHtml()` oder `addText()` hinzugefügt:

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

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

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

Mit den Kindknoten kann wie mit einem Array gearbeitet werden. Das heißt, man kann auf einzelne Knoten über eckige Klammern zugreifen, ihre Anzahl mit `count()` ermitteln und über sie iterieren:

```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
```

Ein neuer Knoten kann an einer bestimmten Position mit `insert(?int $index, $child, bool $replace = false)` eingefügt werden. Wenn `$replace = false` ist, wird das Element an der Position `$index` eingefügt und die nachfolgenden Elemente werden verschoben. Wenn `$index = null` ist, wird das Element am Ende angefügt.

```php
// Fügt das Element an die erste Position ein und verschiebt die anderen
$el->insert(0, Html::el('span'));
```

Alle Kindknoten können mit der Methode `getChildren()` abgerufen und mit `removeChildren()` entfernt werden.


Erstellung eines Dokumentfragments
----------------------------------

Wenn man mit einem Array von Knoten arbeiten möchte, ohne ein umschließendes Element zu benötigen, kann man ein sogenanntes *Dokumentfragment* erstellen, indem man `null` anstelle eines Elementnamens übergibt:

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

Einen schnelleren Weg zur Erstellung eines Fragments bieten die Methoden `fromHtml()` und `fromText()`:

```php
$el = Html::fromHtml('hello<br>');
echo $el; // 'hello<br>'

$el = Html::fromText('10 < 20');
echo $el; // '10 &lt; 20'
```


Generierung der HTML-Ausgabe
============================

Der einfachste Weg, ein HTML-Element auszugeben, ist die Verwendung von `echo` oder die Typumwandlung des Objekts zu `(string)`. Es ist auch möglich, das öffnende Tag, das schließende Tag und die Attribute separat auszugeben:

```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"'
```

Ein wichtiges Merkmal ist der automatische Schutz vor [Cross-Site-Scripting (XSS) |nette:glossary#Cross-Site Scripting XSS]. Alle Attributwerte oder Inhalte, die mit `setText()` oder `addText()` eingefügt werden, werden zuverlässig maskiert (escaped):

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

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


Konvertierung HTML ↔ Text
=========================

Zur Konvertierung von HTML in reinen 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 `Nette\HtmlStringable`-Interface. Dieses Interface wird beispielsweise von Latte oder Formularen verwendet, um Objekte zu erkennen, deren `__toString()`-Methode HTML-Code zurückgibt. Dadurch wird verhindert, dass der Inhalt doppelt maskiert wird, wenn ein solches Objekt beispielsweise in einer Vorlage mit `{$el}` ausgegeben wird.

HTML-Elemente

Die Klasse Nette\Utils\Html ist ein Helfer zur Generierung von HTML-Code, der hilft, Cross-Site-Scripting (XSS)-Schwachstellen zu verhindern.

Sie funktioniert, indem ihre Objekte HTML-Elemente repräsentieren, deren Attribute gesetzt und die dann gerendert werden können:

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

Installation:

composer require nette/utils

Alle Beispiele setzen voraus, dass der folgende Alias definiert wurde:

use Nette\Utils\Html;

Erstellung von HTML-Elementen

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

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

Neben dem Elementnamen können Sie weitere Attribute direkt in HTML-Syntax angeben:

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

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

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

Ändern und Abrufen des Elementnamens:

$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, da <img> ein leeres Element ist (z.B. <br>, <hr>)

HTML-Attribute

Einzelne HTML-Attribute können auf drei Arten geändert und gelesen werden, es hängt von Ihnen ab, welche Ihnen am besten gefällt. Die erste ist ü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 Möglichkeit ist der Aufruf von Methoden, die – im Gegensatz zum Setzen von Eigenschaften – verkettet werden können:

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

$el->alt(null); // Attribut entfernen

Und die dritte Möglichkeit 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 können gesammelt mit addAttributes(array $attrs) gesetzt und mit removeAttributes(array $attrNames) entfernt werden.

Der Wert eines Attributs muss kein String sein; für boolesche Attribute können auch boolesche Werte verwendet werden:

$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. Dies ist beispielsweise 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, bei dem die booleschen Werte angeben, ob der jeweilige Schlüssel als Wert ausgegeben werden soll:

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

CSS-Stile können als assoziatives Array geschrieben werden:

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

Wir haben eben Eigenschaften verwendet, aber dasselbe kann auch mit Methoden erreicht werden:

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

Oder 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">'

Noch eine Anmerkung: Die Methode href() kann das Zusammenstellen von Query-Parametern in URLs vereinfachen:

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

Datenattribute

Datenattribute (data-*) werden besonders unterstützt. Da ihre Namen Bindestriche enthalten, ist der Zugriff über Eigenschaften und Methoden weniger elegant. Daher gibt es die Methode data():

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

Wenn der Wert eines Datenattributs ein Array ist, 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

Der innere Inhalt eines Elements wird mit den Methoden setHtml() oder setText() festgelegt. Verwenden Sie setHtml() nur, wenn Sie sicher sind, dass der übergebene String vertrauenswürdiges HTML 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 wird der innere Inhalt mit den Methoden getHtml() oder getText() abgerufen. Letztere entfernt HTML-Tags aus dem Inhalt und konvertiert HTML-Entitäten in die entsprechenden Zeichen.

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

Kindknoten

Der Inhalt eines Elements kann auch ein Array von Kindknoten (Children) sein. Jeder Kindknoten kann entweder ein String oder ein weiteres Html-Element sein. Sie werden mit addHtml() oder addText() hinzugefügt:

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

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

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

Mit den Kindknoten kann wie mit einem Array gearbeitet werden. Das heißt, man kann auf einzelne Knoten über eckige Klammern zugreifen, ihre Anzahl mit count() ermitteln und über sie iterieren:

$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

Ein neuer Knoten kann an einer bestimmten Position mit insert(?int $index, $child, bool $replace = false) eingefügt werden. Wenn $replace = false ist, wird das Element an der Position $index eingefügt und die nachfolgenden Elemente werden verschoben. Wenn $index = null ist, wird das Element am Ende angefügt.

// Fügt das Element an die erste Position ein und verschiebt die anderen
$el->insert(0, Html::el('span'));

Alle Kindknoten können mit der Methode getChildren() abgerufen und mit removeChildren() entfernt werden.

Erstellung eines Dokumentfragments

Wenn man mit einem Array von Knoten arbeiten möchte, ohne ein umschließendes Element zu benötigen, kann man ein sogenanntes Dokumentfragment erstellen, indem man null anstelle eines Elementnamens übergibt:

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

Einen schnelleren Weg zur Erstellung eines Fragments bieten die Methoden fromHtml() und fromText():

$el = Html::fromHtml('hello<br>');
echo $el; // 'hello<br>'

$el = Html::fromText('10 < 20');
echo $el; // '10 &lt; 20'

Generierung der HTML-Ausgabe

Der einfachste Weg, ein HTML-Element auszugeben, ist die Verwendung von echo oder die Typumwandlung des Objekts zu (string). Es ist auch möglich, das öffnende Tag, das schließende Tag und die Attribute separat auszugeben:

$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"'

Ein wichtiges Merkmal ist der automatische Schutz vor Cross-Site-Scripting (XSS). Alle Attributwerte oder Inhalte, die mit setText() oder addText() eingefügt werden, werden zuverlässig maskiert (escaped):

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

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

Konvertierung HTML ↔ Text

Zur Konvertierung von HTML in reinen 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 Nette\HtmlStringable-Interface. Dieses Interface wird beispielsweise von Latte oder Formularen verwendet, um Objekte zu erkennen, deren __toString()-Methode HTML-Code zurückgibt. Dadurch wird verhindert, dass der Inhalt doppelt maskiert wird, wenn ein solches Objekt beispielsweise in einer Vorlage mit {$el} ausgegeben wird.