HTML Elemanları

Nette\Utils\Html sınıfı, Siteler Arası Betik Çalıştırma (XSS) güvenlik açığının oluşmasını engelleyen HTML kodu oluşturmak için bir yardımcıdır.

Şöyle çalışır: nesneleri HTML elemanlarını temsil eder, bunlara parametreler ayarlarız ve oluşturulmalarını sağlarız:

$el = Html::el('img');  // <img> elemanı oluşturur
$el->src = 'image.jpg'; // src niteliğini ayarlar
echo $el;               // '<img src="image.jpg">' yazdırır

Kurulum:

composer require nette/utils

Tüm örnekler, oluşturulmuş bir takma ad varsayar:

use Nette\Utils\Html;

HTML Elemanı Oluşturma

Elemanı Html::el() metoduyla oluştururuz:

$el = Html::el('img'); // <img> elemanı oluşturur

Adın yanı sıra, HTML sözdiziminde başka nitelikler de belirtebilirsiniz:

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

Veya bunları ikinci parametre olarak ilişkisel bir dizi olarak iletebilirsiniz:

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

Eleman adını değiştirme ve döndürme:

$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, çünkü <img> boş bir elemandır

HTML Nitelikleri

Bireysel HTML niteliklerini üç şekilde değiştirebilir ve okuyabiliriz, hangisini daha çok beğeneceğiniz size bağlıdır. Bunlardan ilki özellikler aracılığıyladır:

$el->src = 'image.jpg'; // src niteliğini ayarlar

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

unset($el->src);  // niteliği kaldırır
// veya $el->src = null;

İkinci yol, özellik ayarlamaya göre zincirleyebileceğimiz metotları çağırmaktır:

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

$el->alt(null); // niteliği kaldırma

Ve üçüncü yol en konuşkan olanıdır:

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

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

$el->removeAttribute('alt');

Nitelikler toplu olarak addAttributes(array $attrs) ile ayarlanabilir ve removeAttributes(array $attrNames) ile kaldırılabilir.

Niteliğin değeri yalnızca bir karakter dizisi olmak zorunda değildir, mantıksal nitelikler için mantıksal değerler de kullanılabilir:

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

Niteliğin değeri, boşluklarla ayrılmış olarak yazdırılacak bir değerler dizisi de olabilir, bu örneğin CSS sınıfları için kullanışlıdır:

$el = Html::el('input');
$el->class[] = 'active';
$el->class[] = null; // null göz ardı edilir
$el->class[] = 'top';
echo $el; // '<input class="active top">'

Alternatif, değerlerin anahtarın yazdırılıp yazdırılmayacağını söylediği ilişkisel bir dizidir:

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

CSS stilleri ilişkisel diziler şeklinde yazılabilir:

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

Şimdi özellikleri kullandık, ancak aynı şey metotlarla da yazılabilir:

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

Veya en konuşkan şekilde bile:

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

Son olarak küçük bir ayrıntı: href() metodu, URL'deki sorgu parametrelerini birleştirmeyi kolaylaştırabilir:

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

Veri Nitelikleri

Veri nitelikleri için özel destek vardır. Adları tire içerdiğinden, özellikler ve metotlar aracılığıyla erişim o kadar zarif değildir, bu nedenle bir data() metodu vardır:

$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // o kadar zarif değil
$el->data('max-size', '500x300'); // zarif
echo $el; // '<input data-max-size="500x300">'

Veri niteliğinin değeri bir dizi ise, otomatik olarak JSON'a serileştirilir:

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

Eleman İçeriği

Elemanın iç içeriğini setHtml() veya setText() metotlarıyla ayarlarız. Bunlardan ilkini yalnızca parametrede güvenilir bir şekilde güvenli bir HTML karakter dizisi ilettiğinizi biliyorsanız kullanın.

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

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

Ve tersine, iç içeriği getHtml() veya getText() metotlarıyla alırız. İkincisi, çıktıdan HTML etiketlerini kaldırır ve HTML varlıklarını karakterlere dönüştürür.

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

Alt Düğümler

Elemanın içi ayrıca alt (children) düğümler dizisi de olabilir. Her biri ya bir karakter dizisi ya da başka bir Html elemanı olabilir. Bunları addHtml() veya addText() kullanarak ekleriz:

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

Yeni bir Html düğümü oluşturmak ve eklemek için başka bir yol:

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

Düğümlerle, sanki bir diziymiş gibi aynı şekilde çalışılabilir. Yani, köşeli parantez kullanarak bireysel olanlara erişebilir, count() kullanarak sayabilir ve üzerlerinde yinelenebilir:

$el = Html::el('div');
$el[] = '<b>merhaba</b>';
$el[] = Html::el('span');
echo $el[1]; // '<span></span>'

foreach ($el as $child) { /* ... */ }

echo count($el); // 2

Yeni bir düğüm, insert(?int $index, $child, bool $replace = false) kullanılarak belirli bir yere eklenebilir. Eğer $replace = false ise, öğeyi $index konumuna ekler ve diğerlerini kaydırır. Eğer $index = null ise, öğeyi sona ekler.

// öğeyi ilk konuma ekler ve diğerlerini kaydırır
$el->insert(0, Html::el('span'));

Tüm düğümleri getChildren() metoduyla alırız ve removeChildren() metoduyla kaldırırız.

Belge Parçası Oluşturma

Bir düğüm dizisiyle çalışmak istiyorsak ve çevreleyen elemanla ilgilenmiyorsak, eleman adı yerine null ileterek sözde bir belge parçası oluşturabiliriz:

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

Parça oluşturmanın daha hızlı bir yolu fromHtml() ve fromText() metotlarını sunar:

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

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

HTML Çıktısı Oluşturma

Bir HTML elemanını yazdırmanın en basit yolu echo kullanmak veya nesneyi (string)'e dönüştürmektir. Açılış veya kapanış etiketlerini ve nitelikleri ayrı ayrı yazdırmak da mümkündür:

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

echo $el;               // '<div class="header">merhaba</div>'
$s = (string) $el;      // '<div class="header">merhaba</div>'
$s = $el->toHtml();     // '<div class="header">merhaba</div>'
$s = $el->toText();     // 'merhaba'
echo $el->startTag();   // '<div class="header">'
echo $el->endTag();     // '</div>'
echo $el->attributes(); // 'class="header"'

Önemli bir özellik, Siteler Arası Betik Çalıştırma (XSS)'ye karşı otomatik korumadır. setText() veya addText() aracılığıyla eklenen tüm nitelik değerleri veya içerik güvenilir bir şekilde kaçış işlemine tabi tutulur:

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

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

HTML ↔ Metin Dönüşümü

HTML'yi metne dönüştürmek için statik htmlToText() metodunu kullanabilirsiniz:

echo Html::htmlToText('<span>Bir &amp; İki</span>'); // 'Bir & İki'

HtmlStringable

Nette\Utils\Html nesnesi, örneğin Latte veya formların HTML kodu döndüren __toString() metoduna sahip nesneleri ayırt ettiği Nette\HtmlStringable arayüzünü uygular. Bu nedenle, örneğin nesneyi şablonda {$el} kullanarak yazdırırsak çift kaçış işlemi gerçekleşmez.

versiyon: 4.0