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&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 < 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 < 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 < 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 < 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 < 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()'><script>bad()</script></div>
Conversie HTML ↔ Text
Puteți utiliza metoda statică htmlToText()
pentru a converti HTML în text:
echo Html::htmlToText('<span>One & 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}
.