Elemente HTML

Clasa Nette\Utils\Html este un ajutor pentru generarea de cod HTML care previne vulnerabilitatea Cross Site Scripting (XSS).

Funcționează în așa fel încât obiectele sale reprezintă elemente HTML, le setăm parametrii și le lăsăm să se redea:

$el = Html::el('img');  // creează elementul <img>
$el->src = 'image.jpg'; // stabilește atributul src
echo $el;               // tipărește '<img src="image.jpg">'

Instalare:

composer require nette/utils

Toate exemplele presupun că este definit următorul alias de clasă:

use Nette\Utils\Html;

Crearea unui element HTML

Elementul este creat folosind metoda Html::el():

$el = Html::el('img'); // creează elementul <img>

În plus față de nume, puteți introduce și alte atribute în sintaxa HTML:

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

Sau treceți-le ca o matrice asociativă la al doilea parametru:

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

Pentru a modifica și a returna un nume de element:

$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, deoarece <img> este un element void

Atribute HTML

Puteți seta și obține atribute HTML individuale în trei moduri, depinde de dumneavoastră care vă place mai mult. Primul este prin intermediul proprietăților:

$el->src = 'image.jpg'; // stabilește atributul src

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

unset($el->src);  // elimină atributul
// sau $el->src = null;

Al doilea mod este de a apela metode care, spre deosebire de setarea proprietăților, putem să le înlănțuim:

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

$el->alt(null); // elimină atributul

Iar al treilea mod este cel mai vorbăreț:

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

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

$el->removeAttribute('alt');

În bloc, atributele pot fi setate cu addAttributes(array $attrs) și șterse cu removeAttributes(array $attrNames).

Valoarea unui atribut nu trebuie să fie neapărat un șir de caractere, ci se pot utiliza și valori logice pentru atributele logice:

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

Un atribut poate fi, de asemenea, o matrice de simboluri, care sunt listate separate prin spații, ceea ce este potrivit pentru clasele CSS, de exemplu:

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

O alternativă este un tablou asociativ, în care valorile indică dacă cheia trebuie să fie listată sau nu:

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

Stilurile CSS pot fi scrise sub formă de tablouri asociative:

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

Am folosit acum proprietățile, dar același lucru se poate face și cu ajutorul metodelor:

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

Sau chiar în cel mai vorbăreț mod:

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

Un ultim lucru: metoda href() poate facilita compunerea parametrilor de interogare într-un URL:

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

Atribute de date

Atributele de date au un suport special. Deoarece numele lor conțin cratime, accesul prin intermediul proprietăților și metodelor nu este atât de elegant, așa că există o metodă data():

$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // nu atât de elegant
$el->data('max-size', '500x300'); // este elegant
echo $el; // '<input data-max-size="500x300">'

Dacă valoarea atributului de date este o matrice, aceasta este serializată automat în JSON:

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

Conținutul elementului

Conținutul interior al elementului este stabilit prin metodele setHtml() sau setText(). Folosiți prima metodă numai dacă știți că transmiteți în mod fiabil un șir HTML securizat în parametru.

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

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

Dimpotrivă, conținutul interior este obținut prin metodele getHtml() sau getText(). Cea de-a doua elimină etichetele din ieșirea HTML și convertește entitățile HTML în caractere.

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

Noduri copil

Conținutul interior al unui element poate fi, de asemenea, o matrice de copii. Fiecare dintre ei poate fi fie un șir de caractere, fie un alt element Html. Aceștia sunt introduși cu ajutorul addHtml() sau addText():

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

O altă modalitate de a crea și insera un nou nod Html:

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

Puteți lucra cu nodurile ca și cum ar fi elemente de matrice. Deci, accesați-le pe cele individuale folosind paranteze pătrate, numărați-le cu count() și iterați peste ele:

$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 nou nod poate fi inserat într-o anumită poziție folosind insert(?int $index, $child, bool $replace = false). Dacă $replace = false, se inserează elementul la poziția $index și se mută celelalte. În cazul în care $index = null, se adaugă un element la sfârșit.

// inserează elementul în prima poziție și avansează celelalte.
$el->insert(0, Html::el('span'));

Toate nodurile sunt returnate prin metoda getChildren() și eliminate prin metoda removeChildren().

Crearea unui fragment de document

Dacă doriți să lucrați cu o matrice de noduri și nu vă interesează elementul de înfășurare, puteți crea un așa-numit fragment de document, trecând null în locul numelui elementului:

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

Metodele fromHtml() și fromText() oferă o modalitate mai rapidă de a crea un fragment:

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

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

Generarea de ieșire HTML

Cel mai simplu mod de a genera un element HTML este de a utiliza echo sau de a transforma un obiect în (string). De asemenea, puteți imprima separat etichetele și atributele de deschidere sau de închidere:

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

O caracteristică importantă este protecția automată împotriva Cross Site Scripting (XSS). Toate valorile atributului sau conținutul inserat folosind setText() sau addText() sunt scăpate în mod fiabil:

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

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

Conversie HTML ↔ Text

Puteți utiliza metoda statică htmlToText() pentru a converti HTML în text:

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

HtmlStringable

Obiectul Nette\Utils\Html implementează interfața Nette\HtmlStringable, pe care, de exemplu, Latte sau formularele o folosesc pentru a distinge obiectele care au o metodă __toString() care returnează codul HTML. Astfel, scăparea dublă nu apare dacă, de exemplu, imprimăm obiectul din șablon folosind {$el}.

versiune: 4.0