Nette Documentation Preview

syntax
Elementi HTML
*************

.[perex]
La classe [api:Nette\Utils\Html] è un aiuto per la generazione di codice HTML che previene le vulnerabilità Cross Site Scripting (XSS).


Funziona in modo tale che i suoi oggetti rappresentano elementi HTML, si impostano i loro parametri e si lascia che vengano resi:

```php
$el = Html::el('img'); // crea l'elemento <img>.
$el->src = 'image.jpg'; // imposta l'attributo src
echo $el; // stampa '<img src="immagine.jpg">'
```

Installazione:

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

Tutti gli esempi presuppongono che sia definito il seguente alias di classe:

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


Creazione di un elemento HTML .[#toc-creating-an-html-element]
==============================================================

L'elemento viene creato con il metodo `Html::el()`:

```php
$el = Html::el('img'); // crea l'elemento <img
```

Oltre al nome, è possibile inserire altri attributi nella sintassi HTML:

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

Oppure passarli come array associativo al secondo parametro:

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

Per modificare e restituire il nome di un elemento:

```php
$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // vero, poiché <img> è un elemento nullo
```


Attributi HTML .[#toc-html-attributes]
======================================

È possibile impostare e ottenere i singoli attributi HTML in tre modi, a seconda di quello che si preferisce. Il primo è attraverso le proprietà:

```php
$el->src = 'image.jpg'; // imposta l'attributo src

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

unset($el->src); // rimuove l'attributo
// oppure $el->src = null;
```

Il secondo modo è quello di chiamare metodi che, a differenza dell'impostazione delle proprietà, possono essere concatenati tra loro:

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

$el->alt(null); // rimuove l'attributo
```

E il terzo modo è il più loquace:

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

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

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

In blocco, gli attributi possono essere impostati con `addAttributes(array $attrs)` e cancellati con `removeAttributes(array $attrNames)`.

Il valore di un attributo non deve essere necessariamente una stringa, ma si possono usare anche valori logici per gli attributi logici:

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

Un attributo può anche essere un array di token, separati da spazi, adatto per esempio alle classi CSS:

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

Un'alternativa è un array associativo, in cui i valori dicono se la chiave deve essere elencata:

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

Gli stili CSS possono essere scritti sotto forma di array associativi:

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

Abbiamo utilizzato le proprietà, ma la stessa cosa può essere fatta utilizzando i metodi:

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

O anche nel modo più loquace:

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

Un'ultima cosa: il metodo `href()` può facilitare la composizione dei parametri di query in un URL:

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


Attributi dei dati .[#toc-data-attributes]
------------------------------------------

Gli attributi dei dati hanno un supporto speciale. Poiché i loro nomi contengono dei trattini, l'accesso tramite proprietà e metodi non è molto elegante, quindi esiste un metodo `data()`:

```php
$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // non è così elegante
$el->data('max-size', '500x300'); // è elegante
echo $el; // '<input data-max-size="500x300">'
```

Se il valore dell'attributo dati è un array, viene automaticamente serializzato in JSON:

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


Contenuto dell'elemento .[#toc-element-content]
===============================================

Il contenuto interno dell'elemento viene impostato dai metodi `setHtml()` o `setText()`. Usare il primo solo se si sa che si sta passando in modo affidabile una stringa HTML sicura nel parametro.

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

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

Al contrario, il contenuto interno si ottiene con i metodi `getHtml()` o `getText()`. Il secondo rimuove i tag dall'output HTML e converte le entità HTML in caratteri.

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


Nodi figli .[#toc-child-nodes]
------------------------------

Il contenuto interno di un elemento può anche essere un array di figli. Ognuno di essi può essere una stringa o un altro elemento `Html`. Vengono inseriti usando `addHtml()` o `addText()`:

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

Un altro modo per creare e inserire un nuovo nodo `Html`:

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

È possibile lavorare con i nodi come se fossero elementi di un array. Si può quindi accedere ai singoli nodi usando le parentesi quadre, contarli con `count()` e iterare su di essi:

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

Un nuovo nodo può essere inserito in una posizione specifica usando `insert(?int $index, $child, bool $replace = false)`. Se `$replace = false`, inserisce l'elemento nella posizione `$index` e sposta gli altri. Se `$index = null`, aggiunge un elemento alla fine.

```php
// inserisce l'elemento nella prima posizione e fa avanzare gli altri
$el->insert(0, Html::el('span'));
```

Tutti i nodi vengono restituiti dal metodo `getChildren()` e rimossi dal metodo `removeChildren()`.


Creare un frammento di documento .[#toc-creating-a-document-fragment]
---------------------------------------------------------------------

Se si vuole lavorare con una matrice di nodi e non si è interessati all'elemento che li avvolge, si può creare un cosiddetto *frammento di documento* passando `null` al posto del nome dell'elemento:

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

I metodi `fromHtml()` e `fromText()` offrono un modo più rapido per creare un frammento:

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

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


Generare l'output HTML .[#toc-generating-html-output]
=====================================================

Il modo più semplice per generare un elemento HTML è usare `echo` o lanciare un oggetto in `(string)`. È anche possibile stampare separatamente i tag e gli attributi di apertura o chiusura:

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

echo $el;               // '<div class="header"></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"'
```

Una caratteristica importante è la protezione automatica contro il [Cross Site Scripting (XSS) |nette:glossary#cross-site-scripting-xss]. Tutti i valori degli attributi o i contenuti inseriti con `setText()` o `addText()` vengono evasi in modo affidabile:

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

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


Conversione HTML ↔ Testo .[#toc-conversion-html-text]
=====================================================

È possibile utilizzare il metodo statico `htmlToText()` per convertire l'HTML in testo:

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


HtmlStringable .[#toc-htmlstringable]
=====================================

L'oggetto `Nette\Utils\Html` implementa l'interfaccia `Nette\HtmlStringable`, che, ad esempio, Latte o i form utilizzano per distinguere gli oggetti che hanno un metodo `__toString()` che restituisce codice HTML. Quindi il doppio escape non si verifica se, ad esempio, si stampa l'oggetto nel modello usando `{$el}`.

Elementi HTML

La classe Nette\Utils\Html è un aiuto per la generazione di codice HTML che previene le vulnerabilità Cross Site Scripting (XSS).

Funziona in modo tale che i suoi oggetti rappresentano elementi HTML, si impostano i loro parametri e si lascia che vengano resi:

$el = Html::el('img'); // crea l'elemento <img>.
$el->src = 'image.jpg'; // imposta l'attributo src
echo $el; // stampa '<img src="immagine.jpg">'

Installazione:

composer require nette/utils

Tutti gli esempi presuppongono che sia definito il seguente alias di classe:

use Nette\Utils\Html;

Creazione di un elemento HTML

L'elemento viene creato con il metodo Html::el():

$el = Html::el('img'); // crea l'elemento <img

Oltre al nome, è possibile inserire altri attributi nella sintassi HTML:

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

Oppure passarli come array associativo al secondo parametro:

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

Per modificare e restituire il nome di un elemento:

$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // vero, poiché <img> è un elemento nullo

Attributi HTML

È possibile impostare e ottenere i singoli attributi HTML in tre modi, a seconda di quello che si preferisce. Il primo è attraverso le proprietà:

$el->src = 'image.jpg'; // imposta l'attributo src

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

unset($el->src); // rimuove l'attributo
// oppure $el->src = null;

Il secondo modo è quello di chiamare metodi che, a differenza dell'impostazione delle proprietà, possono essere concatenati tra loro:

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

$el->alt(null); // rimuove l'attributo

E il terzo modo è il più loquace:

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

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

$el->removeAttribute('alt');

In blocco, gli attributi possono essere impostati con addAttributes(array $attrs) e cancellati con removeAttributes(array $attrNames).

Il valore di un attributo non deve essere necessariamente una stringa, ma si possono usare anche valori logici per gli attributi logici:

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

Un attributo può anche essere un array di token, separati da spazi, adatto per esempio alle classi CSS:

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

Un'alternativa è un array associativo, in cui i valori dicono se la chiave deve essere elencata:

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

Gli stili CSS possono essere scritti sotto forma di array associativi:

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

Abbiamo utilizzato le proprietà, ma la stessa cosa può essere fatta utilizzando i metodi:

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

O anche nel modo più loquace:

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

Un'ultima cosa: il metodo href() può facilitare la composizione dei parametri di query in un URL:

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

Attributi dei dati

Gli attributi dei dati hanno un supporto speciale. Poiché i loro nomi contengono dei trattini, l'accesso tramite proprietà e metodi non è molto elegante, quindi esiste un metodo data():

$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // non è così elegante
$el->data('max-size', '500x300'); // è elegante
echo $el; // '<input data-max-size="500x300">'

Se il valore dell'attributo dati è un array, viene automaticamente serializzato in JSON:

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

Contenuto dell'elemento

Il contenuto interno dell'elemento viene impostato dai metodi setHtml() o setText(). Usare il primo solo se si sa che si sta passando in modo affidabile una stringa HTML sicura nel parametro.

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

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

Al contrario, il contenuto interno si ottiene con i metodi getHtml() o getText(). Il secondo rimuove i tag dall'output HTML e converte le entità HTML in caratteri.

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

Nodi figli

Il contenuto interno di un elemento può anche essere un array di figli. Ognuno di essi può essere una stringa o un altro elemento Html. Vengono inseriti usando addHtml() o addText():

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

Un altro modo per creare e inserire un nuovo nodo Html:

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

È possibile lavorare con i nodi come se fossero elementi di un array. Si può quindi accedere ai singoli nodi usando le parentesi quadre, contarli con count() e iterare su di essi:

$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

Un nuovo nodo può essere inserito in una posizione specifica usando insert(?int $index, $child, bool $replace = false). Se $replace = false, inserisce l'elemento nella posizione $index e sposta gli altri. Se $index = null, aggiunge un elemento alla fine.

// inserisce l'elemento nella prima posizione e fa avanzare gli altri
$el->insert(0, Html::el('span'));

Tutti i nodi vengono restituiti dal metodo getChildren() e rimossi dal metodo removeChildren().

Creare un frammento di documento

Se si vuole lavorare con una matrice di nodi e non si è interessati all'elemento che li avvolge, si può creare un cosiddetto frammento di documento passando null al posto del nome dell'elemento:

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

I metodi fromHtml() e fromText() offrono un modo più rapido per creare un frammento:

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

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

Generare l'output HTML

Il modo più semplice per generare un elemento HTML è usare echo o lanciare un oggetto in (string). È anche possibile stampare separatamente i tag e gli attributi di apertura o chiusura:

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

echo $el;               // '<div class="header"></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"'

Una caratteristica importante è la protezione automatica contro il Cross Site Scripting (XSS). Tutti i valori degli attributi o i contenuti inseriti con setText() o addText() vengono evasi in modo affidabile:

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

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

Conversione HTML ↔ Testo

È possibile utilizzare il metodo statico htmlToText() per convertire l'HTML in testo:

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

HtmlStringable

L'oggetto Nette\Utils\Html implementa l'interfaccia Nette\HtmlStringable, che, ad esempio, Latte o i form utilizzano per distinguere gli oggetti che hanno un metodo __toString() che restituisce codice HTML. Quindi il doppio escape non si verifica se, ad esempio, si stampa l'oggetto nel modello usando {$el}.