Latte 2.10: radost debugovat
Už se stává tradicí, že jednou za čtvrt roku přijde nová verze Latte nadupaná novinkama. Tentokrát se ty nejzásadnější novinky týkají debugování šablon. Pojďte se podívat na rychlý přehled.
Tracy panel
Latte disponuje úplně novým panelem do Tracy, který se v kombinaci s nette/application 3.1 zapíná automaticky:
V panelu vidíte všechny šablony počínaje základní šablonou
presenteru, přes šablony layoutů, až po všechny importované, includované
a embedované šablony. Můžete se přímo prokliknout do šablony, ale také
do zkompilovaného PHP kódu. Užitečnou informaci nese i samotné pořadí
šablon, protože ukazuje prioritu dědičné hierarchie bloků, která jinak
nemusí být vůbec zřejmá. Pokud by každá ze šablon definovala blok se
stejným názvem, bude vykreslen ten z nejvýše uvedené, a pomocí
{include parent}
se bude vkládat stejnojmenný blok ze šablony
vždy následující pod ní.
{trace}
I další novinka úzce souvisí s Tracy. Jde o značku
{trace}
, kterou můžete umístit kamkoliv do šablony a způsobí
vyhození výjimky. Ne však ledajaké, její callstack je vygenerován
z perspektivy šablon. Takže místo volání metod vidíme bloky a značky
{include}
, {extends}
, {import}
nebo
{embed}
. A také předávané argumenty.
Tahle vychytávka se hodí třeba při ladění složitých kompozicí, když potřebujete zjistit, jak se vykreslování dostalo k určitému bodu.
Mimochodem Latte kompiluje šablony do přehledného PHP kódu, který
můžete běžným způsobem krokovat v IDE, lze nastavovat breakpointy atd.
Verze 2.10 doplňuje do kódu mnohem více komentářů
/* line 123 */
odkazujících na číslo řádku ve zdrojové
šabloně, také metody představující bloky mají nově vysvětlující
phpDoc komentář.
n:tag
Atribut n:tag
umí dynamicky měnit název HTML elementu. To se
může hodit v situacích, kdy na základě hodnoty proměnné měníme
důležitost titulku:
<h1 n:tag="$heading" class="main">{$title}</h1>
Pokud je $heading === null
, vypíše se beze změny tag
<h1>
. Jinak se změní název elementu na hodnotu proměnné,
takže pro $heading === 'h3'
se vypíše:
<h3 class="main">...</h3>
{iterateWhile}
Značka {iterateWhile}
se hodí na nejrůznější kejkle ve
foreach cyklech, které se jinak řeší nesmírně komplikovaně. Může také
nahradit {first}
a {last}
. Jejímu popisu je
věnovaná samostatná kapitola
v dokumentaci.
{embed block}
Předchozí verze Latte přišla s důležitou značnou {embed},
která zásadním způsobem posouvá možnosti psaní komponent v Latte. Nyní
lze kromě souborů {embed file.latte}
embedovat i přímo bloky
{embed blockname}
.
Moderní syntax
[key: value]
Minulá verze Latte přišla s podporou pojmenovaných
argumentů z PHP 8.0 ve značkách jako {include}
nebo
{link}
:
before
{include 'file.latte' arg1 => 1, arg2 => 2}
now
{include 'file.latte' arg1: 1, arg2: 2}
Nyní můžete tuto moderní syntax používat také pro zápis polí (což tedy přímo v PHP možné není):
before
{[active => aktivní, suspend => pozastavený][$user->status]}
now
{[active: aktivní, suspend: pozastavený][$user->status]}
Nové filtry a funkce
V Latte 2.10 najdete plejádu nových funkcí (even()
,
odd()
, divisibleBy()
, first()
,
last()
) a filtrů
(|first
, |last
, |random
,
|round
, |floor
, |ceil
,
|join
, |slice
, |explode
,
|split
, |spaceless
a |query
).
Dále rozšiřuje filtr |sort
o možnost předat jako parametr
vlastní porovnávací funkci:
{var $sorted = ($names|sort: fn($a, $b) => $b <=> $a)}
Filtr |replace
může udělat více záměn najednou:
{='hello world'|replace: [h => l, l => h]} {* vypíše 'lehho worhd' *}
Engine::addFilterLoader()
Metoda addFilterLoader($loader)
nahrazuje univerzální filtr
addFilter(null, ....)
, jehož API nebylo příliš srozumitelné.
Úkolem loaderu je vrátit callback filtru nebo null
:
class Filters
{
public function loader(string $filter): ?callable
{
if (method_exists($this, $filter)) {
return [$this, $filter];
}
return null;
}
public function shortify($s, $len = 10)
{
return mb_substr($s, 0, $len);
}
...
}
PHP attributy
TemplateFunction
& TemplateFilter
Filtry a funkce můžete do Latte registrovat ještě jedním způsobem:
tím, že vytvoříte metody ve třídě šablony a dáte jim anotace
/** @filter */
nebo /** @function */
. Nyní můžete
anotace nahradit atributy PHP 8.0:
class HomepageTemplate
{
#[Latte\Attributes\TemplateFilter]
public function shortify(string $s, int $len = 10): string
{
return mb_substr($s, 0, $len); // zkrátí text na 10 písmen
}
#[Latte\Attributes\TemplateFunction]
public function random(...$args)
{
return $args[array_rand($args)];
}
}
One more thing
Pište, spouštějte, testujte a ukládejte šablony v novém online hřišti. Technická zajímavost: běží to celé čistě v prohlížeči.
Pokud převádíte starý projekt napsaný v čistém PHP do Nette, nebo projekt používající Twig do Latte, oceníte zbrusu novou knihovnu konvertorů. Jejich online podobu si můžete vyzkoušet na https://php2latte.nette.org a https://twig2latte.nette.org.
Nejde o jednoduché záměny pomocí regulárních výrazů, naopak se využívá přímo PHP respektive Twig parser, takže si převodník poradí s jakkoliv složitou syntaxí.
Převod z Twigu předpokládá ruční úpravu výsledku, protože konverzi
nelze provést jednoznačně. Twig používá tečkovou syntax, kde
{{ a.b }}
může znamenat $a->b
,
$a['b']
nebo $a->getB()
, což lze rozlišit až za
běhu, nikoliv při kompilaci. Převaděč proto vše převádí na
$a->b
. Také některé funkce, filtry nebo tagy nemají obdobu
v Latte, nebo se mohou chovat mírně jinak.
Komentáře
Za mě moc pěkné novinky.
V panelu „Rendered Templates“ by se mi hodně líbily i komponenty (a jejich šablony), celkem by to vizualizovalo, jak je stránka celá poskládaná.
Pohrával jsem si i s myšlenkou, že pro rychlé nalezení šablony bych přímo na stránce, například při podržení CTRL zobrazoval u konkrétních komponent jejich zdroj s možností prokliku do IDE, to by ušetřilo spoustu času. Šlo by třeba něco takového přidat?
Jsem zvědav, kdy z Latte vznikne samostatný jazky, jako tomu kdysi bylo u PHP :D
Jinak panle pro Tracy je supr! V minulosti jsme měli vlastní pro jiné templatovací systémy.
#1 joe šablony komponent by se měly zobrazit při nastavení konfigurace
#3 David Grudl Tak tu konfiguraci jsem přehlídnul, ale možná mám nějak ještě po staru řešené komponenty, to nastavení na „all“ nemá vliv.
Aha, tak oprava, už se mi to objevilo, jen jsem to čekal v tom hlavním stromu, ne v nových záložkách :)
Chcete-li odeslat komentář, přihlaste se