HTML elemek
A Nette\Utils\Html osztály egy segédprogram a HTML kód generálásához, amely megakadályozza a Cross Site Scripting (XSS) sebezhetőséget.
Úgy működik, hogy az objektumai HTML elemeket reprezentálnak, paramétereiket beállítjuk, és hagyjuk őket renderelni:
$el = Html::el('img'); // <img> elemet hoz létre
$el->src = 'image.jpg'; // beállítja az src attribútumot
echo $el; // kiírja '<img src="image.jpg">'
Telepítés:
composer require nette/utils
Minden példa feltételezi, hogy a következő osztály alias van definiálva:
use Nette\Utils\Html;
HTML-elem létrehozása
Az elem létrehozása a Html::el()
módszerrel történik:
$el = Html::el('img'); // <img> elemet hoz létre
A HTML-szintaxisban a név mellett más attribútumokat is megadhat:
$el = Html::el('input type=text class="red important"');
Vagy asszociatív tömbként adja át őket a második paraméterhez:
$el = Html::el('input', [
'type' => 'text',
'class' => 'important',
]);
Egy elem nevének megváltoztatása és visszaadása:
$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, mivel <img> üres elem
HTML-attribútumok
Az egyes HTML-attribútumokat háromféleképpen állíthatod be és kaphatod meg, rajtad áll, hogy melyik tetszik jobban. Az első a tulajdonságokon keresztül:
$el->src = 'image.jpg'; // beállítja az src attribútumot
echo $el->src; // 'image.jpg'
unset($el->src); // az attribútum eltávolítása
// vagy $el->src = null;
A második mód a metódusok hívása, amelyeket a tulajdonságok beállításával ellentétben láncszerűen egymáshoz kapcsolhatunk:
$el = Html::el('img')->src('image.jpg')->alt('photo');
// <img src="image.jpg" alt="photo">
$el->alt(null); // eltávolítja az attribútumot.
A harmadik mód pedig a legbeszédesebb:
$el = Html::el('img')
->setAttribute('src', 'image.jpg')
->setAttribute('alt', 'photo');
echo $el->getAttribute('src'); // 'image.jpg'
$el->removeAttribute('alt');
Tömegesen, az attribútumokat a addAttributes(array $attrs)
segítségével lehet beállítani, és a
removeAttributes(array $attrNames)
segítségével törölni.
Egy attribútum értékének nem kell csak egy karakterláncnak lennie, logikai attribútumokhoz logikai értékek is használhatók:
$checkbox = Html::el('input')->type('checkbox');
$checkbox->checked = true; // <input type="checkbox" checked>
$checkbox->checked = false; // <input type="checkbox">
Egy attribútum lehet szóközökkel elválasztva felsorolt tokenek tömbje is, ami például CSS-osztályok esetében megfelelő:
$el = Html::el('input');
$el->class[] = 'active';
$el->class[] = null; // a null értéket figyelmen kívül hagyjuk.
$el->class[] = 'top';
echo $el; // '<input class="active top">'
Alternatív megoldás az asszociatív tömb, ahol az értékek megmondják, hogy a kulcsot fel kell-e sorolni:
$el = Html::el('input');
$el->class['active'] = true;
$el->class['top'] = false;
echo $el; // '<input class="active">'
A CSS-stílusok asszociatív tömbök formájában írhatók:
$el = Html::el('input');
$el->style['color'] = 'green';
$el->style['display'] = 'block';
echo $el; // '<input style="color: green; display: block">'
Most a tulajdonságokat használtuk, de ugyanezt megtehetjük a metódusok használatával is:
$el = Html::el('input');
$el->style('color', 'green');
$el->style('display', 'block');
echo $el; // '<input style="color: green; display: block">'
Vagy akár a legbeszédesebb módon:
$el = Html::el('input');
$el->appendAttribute('style', 'color', 'green');
$el->appendAttribute('style', 'display', 'block');
echo $el; // '<input style="color: green; display: block">'
Még egy utolsó dolog: a href()
módszer megkönnyítheti a lekérdezési paraméterek összeállítását egy
URL-ben:
echo Html::el('a')->href('index.php', [
'id' => 10,
'lang' => 'en',
]);
// '<a href="index.php?id=10&lang=en"></a>'
Adatattribútumok
Az adatattribútumok speciális támogatással rendelkeznek. Mivel a nevük kötőjeleket tartalmaz, a tulajdonságokon és
metódusokon keresztüli hozzáférés nem olyan elegáns, ezért van egy módszer: data()
:
$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // nem olyan elegáns
$el->data('max-size', '500x300'); // nagyon elegáns
echo $el; // '<input data-max-size="500x300">'
Ha az adatattribútum értéke egy tömb, akkor az automatikusan JSON-ba szerializálódik:
$el = Html::el('input');
$el->data('items', [1,2,3]);
echo $el; // '<input data-items="[1,2,3]">'
Elem tartalma
Az elem belső tartalmát a setHtml()
vagy a setText()
metódusok határozzák meg. Az elsőt csak
akkor használja, ha tudja, hogy megbízhatóan biztonságos HTML karakterláncot ad át a paraméterben.
echo Html::el('span')->setHtml('hello<br>');
// '<span>hello<br></span>'
echo Html::el('span')->setText('10 < 20');
// '<span>10 < 20</span>'
Ezzel szemben a belső tartalmat a getHtml()
vagy a getText()
metódusokkal kapjuk meg. A második
eltávolítja a címkéket a HTML-kimenetből, és a HTML-elemeket karakterekké alakítja.
echo $el->getHtml(); // '10 < 20'
echo $el->getText(); // '10 < 20'
Gyermek csomópontok
Egy elem belső tartalma lehet a gyermekelemek tömbje is. Ezek mindegyike lehet egy-egy karakterlánc vagy egy másik
Html
elem. Ezek beillesztése a addHtml()
vagy a addText()
segítségével történik:
$el = Html::el('span')
->addHtml('hello<br>')
->addText('10 < 20')
->addHtml( Html::el('br') );
// <span>hello<br>10 < 20<br></span>
Egy másik módja egy új Html
csomópont létrehozásának és beszúrásának:
$ul = Html::el('ul');
$ul->create('li', ['class' => 'first'])
->setText('hello');
// <ul><li class="first">hello</li></ul>
A csomópontokkal úgy dolgozhat, mintha tömbelemek lennének. Tehát az egyeseket szögletes zárójelek segítségével
érhetjük el, a count()
segítségével megszámolhatjuk őket, és iterálhatunk rajtuk:
$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
Egy új csomópontot a insert(?int $index, $child, bool $replace = false)
segítségével lehet egy adott
pozícióba beilleszteni. Ha $replace = false
, akkor a $index
pozícióba illeszti be az elemet, a
többit pedig áthelyezi. Ha $index = null
, akkor egy elemet illeszt a végére.
// beilleszti az elemet az első pozícióba és előrébb lépteti a többit.
$el->insert(0, Html::el('span'));
Az összes csomópontot a getChildren()
metódus adja vissza, és a removeChildren()
metódus
távolítja el.
Dokumentumtöredék létrehozása
Ha csomópontok tömbjével akarsz dolgozni, és nem érdekel a csomagoló elem, létrehozhatsz egy úgynevezett
dokumentumtöredéket, ha az elem neve helyett a null
címet adod meg:
$el = Html::el(null)
->addHtml('hello<br>')
->addText('10 < 20')
->addHtml( Html::el('br') );
// hello<br>10 < 20<br>
A fromHtml()
és a fromText()
metódusok gyorsabb módját kínálják a töredék
létrehozásának:
$el = Html::fromHtml('hello<br>');
echo $el; // 'hello<br>'
$el = Html::fromText('10 < 20');
echo $el; // '10 < 20'
HTML kimenet generálása
A HTML-elemek generálásának legegyszerűbb módja a echo
használata, vagy egy objektumnak a
(string)
címre történő átvitele. A nyitó vagy záró címkéket és attribútumokat külön is ki lehet
nyomtatni:
$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"'
Fontos funkció a Cross Site Scripting (XSS)
elleni automatikus védelem. Minden attribútumérték vagy a setText()
vagy a addText()
használatával
beillesztett tartalom megbízhatóan elkerüli az escapet:
echo Html::el('div')
->title('" onmouseover="bad()')
->setText('<script>bad()</script>');
// <div title='" onmouseover="bad()'><script>bad()</script></div>
Átalakítás HTML ↔ Szöveg
A htmlToText()
statikus módszerrel a HTML-t szöveggé alakíthatja:
echo Html::htmlToText('<span>One & Two</span>'); // 'One & Two'
HtmlStringable
A Nette\Utils\Html
objektum megvalósítja a Nette\HtmlStringable
interfészt, amelyet például a
Latte vagy az űrlapok használnak azon objektumok megkülönböztetésére, amelyek rendelkeznek egy olyan
__toString()
metódussal, amely HTML-kódot ad vissza. Így nem történik kettős eszkábálás, ha például a
sablonban az objektumot a {$el}
segítségével nyomtatjuk ki.