Elementi HTML
Razred Nette\Utils\Html je pomočnik za generiranje kode HTML, ki preprečuje ranljivost XSS (Cross Site Scripting).
Deluje tako, da njegovi predmeti predstavljajo elemente HTML, nastavimo njihove parametre in jih pustimo, da se izrišejo:
$el = Html::el('img'); // ustvari element <img>
$el->src = 'image.jpg'; // nastavi atribut src
echo $el; // izpiše '<img src="image.jpg">'
Namestitev:
composer require nette/utils
Vsi primeri predpostavljajo, da je definiran naslednji vzdevek razreda:
use Nette\Utils\Html;
Ustvarjanje elementa HTML
Element je ustvarjen z metodo Html::el()
:
$el = Html::el('img'); // ustvari element <img>
Poleg imena lahko v sintaksi HTML vpišete tudi druge atribute:
$el = Html::el('input type=text class="red important"');
Lahko pa jih posredujete kot asociativno polje v drugem parametru:
$el = Html::el('input', [
'type' => 'text',
'class' => 'important',
]);
Če želite spremeniti in vrniti ime elementa:
$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, ker je <img> prazen element
Atributi HTML
Posamezne atribute HTML lahko nastavite in pridobite na tri načine, od vas pa je odvisno, kateri vam je bolj všeč. Prvi je prek lastnosti:
$el->src = 'image.jpg'; // nastavi atribut src
echo $el->src; // 'image.jpg'
unset($el->src); // odstrani atribut
// ali $el->src = null;
Drugi način je klicanje metod, ki jih lahko v nasprotju z nastavljanjem lastnosti verižno povežemo:
$el = Html::el('img')->src('image.jpg')->alt('photo');
// <img src="image.jpg" alt="photo">
$el->alt(null); // odstrani atribut
Tretji način je najbolj zgovoren:
$el = Html::el('img')
->setAttribute('src', 'image.jpg')
->setAttribute('alt', 'photo');
echo $el->getAttribute('src'); // 'image.jpg'
$el->removeAttribute('alt');
Atribute je mogoče množično nastaviti s addAttributes(array $attrs)
in izbrisati s
removeAttributes(array $attrNames)
.
Vrednost atributa ni nujno samo niz, za logične atribute lahko uporabite tudi logične vrednosti:
$checkbox = Html::el('input')->type('checkbox');
$checkbox->checked = true; // <input type="checkbox" checked>
$checkbox->checked = false; // <input type="checkbox">
Atribut je lahko tudi polje žetonov, ki so na seznamu ločeni s presledki, kar je primerno na primer za razrede CSS:
$el = Html::el('input');
$el->class[] = 'active';
$el->class[] = null; // ničla se ne upošteva
$el->class[] = 'top';
echo $el; // '<input class="active top">'
Druga možnost je asociativno polje, kjer vrednosti povedo, ali naj bo ključ naveden:
$el = Html::el('input');
$el->class['active'] = true;
$el->class['top'] = false;
echo $el; // '<input class="active">'
sloge CSS lahko zapišemo v obliki asociativnih polj:
$el = Html::el('input');
$el->style['color'] = 'green';
$el->style['display'] = 'block';
echo $el; // '<input style="color: green; display: block">'
Uporabili smo lastnosti, enako pa lahko storimo tudi z metodami:
$el = Html::el('input');
$el->style('color', 'green');
$el->style('display', 'block');
echo $el; // '<input style="color: green; display: block">'
Ali celo na najbolj pogovoren način:
$el = Html::el('input');
$el->appendAttribute('style', 'color', 'green');
$el->appendAttribute('style', 'display', 'block');
echo $el; // '<input style="color: green; display: block">'
Še nekaj: metoda href()
lahko olajša sestavljanje parametrov poizvedbe v naslovu URL:
echo Html::el('a')->href('index.php', [
'id' => 10,
'lang' => 'en',
]);
// '<a href="index.php?id=10&lang=en"></a>'
Podatkovni atributi
Podatkovni atributi imajo posebno podporo. Ker njihova imena vsebujejo pomišljaje, dostop prek lastnosti in metod ni tako
eleganten, zato je na voljo metoda data()
:
$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // ne tako elegantno
$el->data('max-size', '500x300'); // je eleganten
echo $el; // '<input data-max-size="500x300">'
Če je vrednost podatkovnega atributa polje, se samodejno serializira v JSON:
$el = Html::el('input');
$el->data('items', [1,2,3]);
echo $el; // '<input data-items="[1,2,3]">'
Vsebina elementa
Notranja vsebina elementa se nastavi z metodama setHtml()
ali setText()
. Prvo metodo uporabite le,
če veste, da v parametru zanesljivo posredujete varen niz HTML.
echo Html::el('span')->setHtml('hello<br>');
// '<span>hello<br></span>'
echo Html::el('span')->setText('10 < 20');
// '<span>10 < 20</span>'
Nasprotno pa notranjo vsebino pridobimo z metodama getHtml()
ali getText()
. Druga odstrani oznake iz
izpisa HTML in pretvori entitete HTML v znake.
echo $el->getHtml(); // '10 < 20'
echo $el->getText(); // '10 < 20'
Podrejena vozlišča
Notranja vsebina elementa je lahko tudi polje otrok. Vsak od njih je lahko niz ali drug element Html
. Vstavljamo
jih z uporabo addHtml()
ali addText()
:
$el = Html::el('span')
->addHtml('hello<br>')
->addText('10 < 20')
->addHtml( Html::el('br') );
// <span>hello<br>10 < 20<br></span>
Drug način za ustvarjanje in vstavljanje novega vozlišča Html
:
$ul = Html::el('ul');
$ul->create('li', ['class' => 'first'])
->setText('hello');
// <ul><li class="first">hello</li></ul>
Z vozlišči lahko delate, kot da so elementi polja. Tako do posameznih dostopate z uporabo oglatih oklepajev, jih
preštejete s count()
in iterirate nad njimi:
$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
Novo vozlišče lahko vstavite na določeno mesto z uporabo insert(?int $index, $child, bool $replace = false)
.
Če je $replace = false
, vstavi element na mesto $index
in premakne ostale. Če je
$index = null
, se element doda na konec.
// vstavi element v prvi položaj in premakne druge
$el->insert(0, Html::el('span'));
Vsa vozlišča se vrnejo z metodo getChildren()
in odstranijo z metodo removeChildren()
.
Ustvarjanje fragmenta dokumenta
Če želite delati z nizom vozlišč in vas zavijalni element ne zanima, lahko ustvarite tako imenovani dokumentni
fragment tako, da namesto imena elementa posredujete null
:
$el = Html::el(null)
->addHtml('hello<br>')
->addText('10 < 20')
->addHtml( Html::el('br') );
// hello<br>10 < 20<br>
Metodi fromHtml()
in fromText()
ponujata hitrejši način ustvarjanja fragmenta:
$el = Html::fromHtml('hello<br>');
echo $el; // 'hello<br>'
$el = Html::fromText('10 < 20');
echo $el; // '10 < 20'
Ustvarjanje izpisa HTML
Element HTML najlažje generirate tako, da uporabite echo
ali pa predmet oddate v (string)
. Ločeno
lahko natisnete tudi odpiralne ali zapiralne oznake in atribute:
$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"'
Pomembna lastnost je samodejna zaščita pred križanjem spletnih strani (XSS). Vse vrednosti
atributov ali vsebine, vstavljene z uporabo setText()
ali addText()
, so zanesljivo izločene:
echo Html::el('div')
->title('" onmouseover="bad()')
->setText('<script>bad()</script>');
// <div title='" onmouseover="bad()'><script>bad()</script></div>
Pretvorba HTML ↔ Besedilo
Za pretvorbo HTML v besedilo lahko uporabite statično metodo htmlToText()
:
echo Html::htmlToText('<span>One & Two</span>'); // 'One & Two'
HtmlStringable
Predmet Nette\Utils\Html
implementira vmesnik Nette\HtmlStringable
, ki ga na primer Latte ali obrazci
uporabljajo za razlikovanje predmetov, ki imajo metodo __toString()
, ki vrača kodo HTML. Tako do dvojnega izrivanja
ne pride, če na primer objekt v predlogi izpišemo z uporabo {$el}
.