HTML Elemanları
Nette\Utils\Html sınıfı, HTML kodu üretmeye yarayan ve Cross-Site Scripting (XSS) açıklarını önlemeye yardımcı olan bir araçtır.
Çalışma biçimi şudur: nesneleri HTML elemanlarını temsil eder; parametrelerini ayarlar, sonra render edersiniz:
$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
Bir elemanın gövdesini add() metoduyla metin ve başka elemanlarla doldurabilirsiniz. Metin
otomatik olarak kaçışlanır, elemanlar olduğu gibi eklenir:
echo Html::el('div')->add(
'Hello ',
Html::el('b')->setText('world'),
);
// '<div>Hello <b>world</b></div>'
Kurulum:
composer require nette/utils
Tüm örnekler, aşağıdaki sınıf takma adının tanımlandığını varsayar:
use Nette\Utils\Html;
HTML Elemanı Oluşturma
Eleman Html::el() metoduyla oluşturulur:
$el = Html::el('img'); // <img> elemanı oluşturur
Adın yanı sıra, HTML söz dizimini kullanarak başka nitelikler de belirtebilirsiniz:
$el = Html::el('input type=text class="red important"');
Ya da bunları ikinci parametrede ilişkisel dizi olarak verebilirsiniz:
$el = Html::el('input', [
'type' => 'text',
'class' => 'important',
]);
Elemanın adını değiştirmek ve almak için:
$el->setName('img');
$el->getName(); // 'img'
$el->isEmpty(); // true, çünkü <img> içeriksiz bir elemandır
HTML Nitelikleri
Tek tek HTML nitelikleri üç yolla ayarlanıp alınabilir; hangisini yeğleyeceğiniz size kalmış. Birincisi özellikler üzerinden:
$el->src = 'image.jpg'; // src niteliğini ayarlar
echo $el->src; // 'image.jpg'
unset($el->src); // niteliği kaldırır
// ya da $el->src = null;
İkinci yol, özellik ayarlamanın aksine zincirlenebilen metot çağrılarıdır:
$el = Html::el('img')->src('image.jpg')->alt('photo');
// <img src="image.jpg" alt="photo">
$el->alt(null); // niteliği kaldırır
Üçüncü yol ise en ayrıntılı olanıdır:
$el = Html::el('img')
->setAttribute('src', 'image.jpg')
->setAttribute('alt', 'photo');
echo $el->getAttribute('src'); // 'image.jpg'
$el->removeAttribute('alt');
Nitelikler addAttributes(array $attrs) ile toplu olarak ayarlanabilir,
removeAttributes(array $attrNames) ile kaldırılabilir.
Bir niteliğin değeri yalnızca dize olmak zorunda değildir; boolean nitelikler için boolean değerler kullanılabilir:
$checkbox = Html::el('input')->type('checkbox');
$checkbox->checked = true; // <input type="checkbox" checked>
$checkbox->checked = false; // <input type="checkbox">
Bir nitelik, boşlukla ayrılmış olarak çıktılanan değerlerden oluşan bir dizi 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 yok sayılır
$el->class[] = 'top';
echo $el; // '<input class="active top">'
Bir alternatif de, değerlerin anahtarın dahil edilip edilmeyeceğini belirttiği ilişkisel dizidir:
$el = Html::el('input');
$el->class['active'] = true;
$el->class['top'] = false;
echo $el; // '<input class="active">'
CSS stilleri ilişkisel dizi olarak yazılabilir:
$el = Html::el('input');
$el->style['color'] = 'green';
$el->style['display'] = 'block';
echo $el; // '<input style="color:green;display:block">'
Şimdiye kadar özellikleri kullandık, ama aynı sonuca metotlarla da ulaşılabilir:
$el = Html::el('input');
$el->style('color', 'green');
$el->style('display', 'block');
echo $el; // '<input style="color:green;display:block">'
Ya da en ayrıntılı biçimde:
$el = Html::el('input');
$el->appendAttribute('style', 'color', 'green');
$el->appendAttribute('style', 'display', 'block');
echo $el; // '<input style="color:green;display:block">'
Son bir ayrıntı: href() metodu, URL sorgu parametrelerini oluşturmayı kolaylaştırabilir:
echo Html::el('a')->href('index.php', [
'id' => 10,
'lang' => 'en',
]);
// '<a href="index.php?id=10&lang=en"></a>'
Data Nitelikleri
Data niteliklerinin özel bir desteği vardır. Adları tire içerdiğinden özellikler ve metotlar üzerinden erişmek pek
şık olmaz; bu yüzden ayrı bir data() metodu vardır:
$el = Html::el('input');
$el->{'data-max-size'} = '500x300'; // pek şık değil
$el->data('max-size', '500x300'); // şık olan bu
echo $el; // '<input data-max-size="500x300">'
Bir data niteliğinin değeri diziyse, 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ği setHtml() ya da setText() metotlarıyla ayarlanır. Birincisini yalnızca
parametrenin güvenilir biçimde güvenli bir HTML dizesi içerdiğinden eminseniz kullanın.
echo Html::el('span')->setHtml('hello<br>');
// '<span>hello<br></span>'
echo Html::el('span')->setText('10 < 20');
// '<span>10 < 20</span>'
Tersine, iç içerik getHtml() ya da getText() metotlarıyla alınabilir. İkincisi içerikteki HTML
etiketlerini kaldırır ve HTML varlıklarını karakterlere geri çevirir.
echo $el->getHtml(); // '10 < 20'
echo $el->getText(); // '10 < 20'
Alt Node'lar
Bir elemanın iç içeriği alt node'lardan oluşan bir dizi de olabilir. Her alt öğe ya bir dize ya da başka bir
Html nesnesidir. addHtml() ya da addText() ile eklenirler:
$el = Html::el('span')
->addHtml('hello<br>')
->addText('10 < 20')
->addHtml( Html::el('br') );
// <span>hello<br>10 < 20<br></span>
add() metodu birden çok alt öğeyi tek seferde ekler. Dizeler addText()'teki
gibi kaçışlanır, Html nesneleri olduğu gibi eklenir, null değerler atlanır; bu da koşullu
içerik için kullanışlıdır. Güvenilir biçimde güvenli HTML olan bir dizeyi Html::html() ile sarın:
$el = Html::el('span')->add(
'10 < 20',
Html::el('br'),
Html::html('hello<br>'),
$showNote ? Html::el('small')->setText('note') : null,
);
// <span>10 < 20<br>hello<br><small>note</small></span>
Yeni bir Html node'u oluşturup eklemenin başka bir yolu:
$ul = Html::el('ul');
$ul->create('li', ['class' => 'first'])
->setText('first');
// <ul><li class="first">first</li></ul>
Node'larla dizi öğeleriymiş gibi çalışabilirsiniz. Yani tek tek node'lara köşeli parantezlerle erişebilir,
count() ile sayabilir ve üzerlerinde yineleme yapabilirsiniz:
$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
Yeni bir node, insert(?int $index, $child, bool $replace = false) ile belirli bir konuma eklenebilir.
$replace = false ise elemanı $index konumuna ekler ve diğerlerini kaydırır.
$index = null ise elemanı sona ekler.
// elemanı ilk konuma ekler ve diğerlerini kaydırır
$el->insert(0, Html::el('span'));
Tüm node'lar getChildren() metoduyla alınabilir, removeChildren() metoduyla kaldırılabilir.
Belge Parçası Oluşturma
Bir node kümesiyle çalışmak istiyor ama sarmalayan bir eleman istemiyorsanız, bir belge
parçası oluşturabilirsiniz. Yalnızca alt öğelerini render eder, kendine ait bir etiket üretmez.
fragment() metodu bunu oluşturur ve tek çağrıda alt öğelerle doldurur; add() ile aynı
kuralları izler:
echo Html::fragment(
Html::el('strong')->setText('hello'),
'10 < 20',
Html::el('br'),
);
// <strong>hello</strong>10 < 20<br>
Yalnızca metin ya da yalnızca HTML içeren bir parça, text() ve html()
metotlarıyla oluşturulur:
echo Html::text('10 < 20'); // '10 < 20'
echo Html::html('hello<br>'); // 'hello<br>'
4.1.5 öncesi sürümleri desteklemeniz gerekiyorsa, eleman adı yerine null vererek bir parça oluşturun ve
addHtml() ile addText() kullanarak doldurun. text() ve html() yerine bu
sürümler, hâlâ çalışan ama kullanımdan kaldırılmış olan fromText() ve fromHtml()
metotlarını sunar:
$el = Html::el(null)
->addHtml('hello<br>')
->addText('10 < 20');
// hello<br>10 < 20
echo Html::fromText('10 < 20'); // '10 < 20'
echo Html::fromHtml('hello<br>'); // 'hello<br>'
HTML Çıktısı Üretme
Bir HTML elemanını çıktılamanın en basit yolu echo kullanmak ya da nesneyi (string) ile
dönüştürmektir. Açılış etiketini, kapanış etiketini ve nitelikleri ayrı ayrı da çıktılayabilirsiniz:
$el = Html::el('div class=header')->setText('hello');
echo $el; // '<div class="header">hello</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"'
render(?int $indent = null) metodu düzgün biçimlendirilmiş çıktı sunar. Bir girinti düzeyi verirseniz
çıktı birden çok satıra düzgün girintiyle dağıtılır:
echo $el->render(0); // girintili HTML döndürür
Önemli bir özellik de Cross-Site Scripting (XSS)
saldırılarına karşı otomatik korumadır. Tüm nitelik değerleri ile setText(), addText(),
add() ya da fragment() ile eklenen içerik güvenilir biçimde kaçışlanır:
echo Html::el('div')
->title('" onmouseover="bad()')
->setText('<script>bad()</script>');
// <div title='" onmouseover="bad()'><script>bad()</script></div>
HTML ↔ Metin Dönüşümü
HTML'i metne dönüştürmek için statik htmlToText() metodunu kullanabilirsiniz:
echo Html::htmlToText('<span>One & Two</span>'); // 'One & Two'
HtmlStringable
Nette\Utils\Html nesnesi Nette\HtmlStringable arayüzünü uygular. Latte ve Forms bu arayüzü,
örneğin HTML kodu döndüren bir __toString() metoduna sahip nesneleri ayırt etmek için kullanır. Böylece
nesneyi şablonda {$el} ile yazdırdığınızda çifte kaçışlama olmaz.