Vylepšení šablonovacího jazyka
- David Grudl
- Nette Core | 8218
V aktuální revizi se objevilo drobné rozšíření šablonovacího jazyka CurlyBrackets. Jde o vyvíjenou věc, ještě to nemusí 100% fungovat.
Původně:
{block #content}
<div id="main">
<h1....
<p>....
</div>
{/block}
nově alternativně:
<div id="main" n:block="#content">
<h1....
<p>....
</div>
Původně:
<ul>
{foreach $items as $item}
<li>{$item}</li>
{/foreach}
</ul>
nově alternativně:
<ul>
<li n:foreach="$items as $item">{$item}</li>
</ul>
Původně:
{if $cond}
<div class="login">
<p>User {$name}</p>
...
</div>
{/if}
nově alternativně:
<div class="login" n:if="$cond">
<p>User {$name}</p>
...
</div>
Pokud se to někomu nelíbí, ať … vy víte ;)
- David Grudl
- Nette Core | 8218
Nově lze pomocí makro atributů zapisovat i případy, kdy se například iterátor týká více elementů a nebylo by možné ho přiřadit jen k jednomu:
<ul>
{foreach $items as $item}
<li>A {$item}</li>
<li>B {$item}</li>
{/foreach}
</ul>
Atribut se jednoduše umístí na rodičovský prvek a dá se mu prefix
inner-
:
<ul n:inner-foreach="$items as $item">
<li>A {$item}</li>
<li>B {$item}</li>
</ul>
Výhodou implementace je, že je plně propojena s makry definovanými
v CurlyBracketMacros, takže pokud přidáme nové párové makro, můžeme je
používat i jako makro-atribut. Lze tak využít např. i nové makro
ifset
:
<a href="..." n:ifset="$name">{$name}</a>
- LM
- Člen | 206
Jakým způsobem lze includovat jen vnitřek rodičovského elementu?
// base.phtml
<title n:block="#title">Nette</title>
{extends "base.phtml"}
<title n:block="#title">{include #parent} - Homepage</title>
se mi includne i tag title
což je nechtěné lze to nějak
obejít? teda kromě použití {block…
- phx
- Člen | 651
Ted jsem trochu zmaten. Asi jsem nepochopil vyznam inner-.
Osobne bych cekal, ze tyto zapisy vybeneruji totozny vystup:
<ul n:foreach="$items as $item">
<li>{$item}</li>
</ul>
vs.
<ul n:inner-foreach="$items as $item">
<li>{$item}</li>
</ul>
Proste foreach je jakoby misto HTML ul.
- DocX
- Člen | 154
phx napsal(a):
Ted jsem trochu zmaten. Asi jsem nepochopil vyznam inner-.
Osobne bych cekal, ze tyto zapisy vybeneruji totozny vystup:
<ul n:foreach="$items as $item"> <li>{$item}</li> </ul> vs. <ul n:inner-foreach="$items as $item"> <li>{$item}</li> </ul>
Proste foreach je jakoby misto HTML ul.
Jak jsem pochopil Davidovo úvod, tak n:foreach obalí foreachem ten element na nemž to je (a ten se pak opakuje), zatímco n:inner-foreach obalí foreachem vnitřek toho elementu na nemž je (a opakuje se pak ten vnitřek uvnitř elementu s n:inner-foreach)
- Majkl578
- Moderator | 1364
phx:
samotné foreach se aplikuje přímo na tag, u kterého je zapsán, kdežto
inner-foreach na obsah; viz:
tento kód:
<ul>
<li n:foreach="array(1,2,3) as $num">{$num}</li>
</ul>
ale i tenhle:
<ul n:inner-foreach="array(1,2,3) as $num">
<li>{$num}</li>
</ul>
vygenerují to samé:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Editoval Majkl578 (26. 8. 2009 19:57)
- phx
- Člen | 651
Jo to zni logicky. Jen mi je asi kapku proti srsti to, ze foreach se palikuje okolo prvku ve kterem je.
Kdyz se ale juknu do HTML tak jo mate pravdu, ze atributy plati pro prvek u ktereho jsou + potomci.
Takze tyto zapisy jsou naprosto totozne:
<ul>
<li n:foreach="$items as $item">{$item}</li>
</ul>
vs.
<ul n:inner-foreach="$items as $item">
<li>{$item}</li>
</ul>
Osobne mi citelnejsi prijde ten 2. Mozna vec nazoru, mozna namet na prohozeni vyznamu: foreach vs. outer-foreach (sakra to zni divne:)
- Majkl578
- Moderator | 1364
phx: mě zase přijde hezčí ta první verze, ale asi to je o zvyku (a taky o tom, že aktuálně dělám ve stabilní verzí 0.9 :) )
Blizzy napsal(a):
>Jak je vyřešen zápis více n:atributů do tagu? Záleží v tomto případě na pořadí atributů?
výsledek to ovlivnit může
vygenerovaný kód bude v pořadí, ve kterém zapíšeš n: atributy. takže
pokud napíšeš toto:
{assign $data range(1,99999)}
{assign $show false}
<span n:foreach="$data as $img" n:if="$show">{$img}</span>
tak se sice nic nestane, ale php projde 99999× foreach a až poté se aplikuje podmínka
jinak bych měl dotaz (prosbu / bugfix request?) na Davida: nefunguje to s nepárovými tagy jako img, šlo by to fixnout? :)
Editoval Majkl578 (26. 8. 2009 23:02)
- David Grudl
- Nette Core | 8218
Blizzy napsal(a):
Jak je vyřešen zápis více n:atributů do tagu? Záleží v tomto případě na pořadí atributů?
Nezáleží. Dodržuje se HTML konvence, kde pořadí atributů nemá na dokument vliv.
Pokud bych na jednom elementu použil zároveň n:if, n:foreach a n:block, bude vygenerován kód, který se chová nejvíce očekávatelně. Tj. celý element bude obalen do jednoho bloku, v něm proběhne cyklus a v každém průchodu cyklem bude volán if, abych šlo vykreslované prvky pohodlně filtrovat.
- David Grudl
- Nette Core | 8218
phx napsal(a):
Mozna vec nazoru, mozna namet na prohozeni vyznamu: foreach vs. outer-foreach (sakra to zni divne:)
Tohle se nedá rozhodnout od stolu, zkus si nejprve nějakou šablonu takto napsat (či přepsat starší) a pak o tom diskutujme.
- David Grudl
- Nette Core | 8218
jinak bych měl dotaz (prosbu / bugfix request?) na Davida: nefunguje to s nepárovými tagy jako img, šlo by to fixnout? :)
Ve vývojové 0.9 by mělo.
- Ondřej Mirtes
- Člen | 1536
David Grudl napsal(a):
phx napsal(a):
Mozna vec nazoru, mozna namet na prohozeni vyznamu: foreach vs. outer-foreach (sakra to zni divne:)
Tohle se nedá rozhodnout od stolu, zkus si nejprve nějakou šablonu takto napsat (či přepsat starší) a pak o tom diskutujme.
Ten foreach přímo na <li>
není podle mě moc
intuitivní, přendal bych ho na rodičovský prvek, klasický
{foreach}
taky vždy obaluje nějaký svůj obsah, který se pak
vypisuje vícekrát. Jsem pro n:foreach na <ul>
(apod.).
- David Grudl
- Nette Core | 8218
Určitě tady musí být zachována jednotnost, na co se to aplikuje. Vezměte si takové n:if nebo n:block – na co byste očekávali, že se to bude aplikovat?
- Blizzy
- Člen | 149
Jde nějak hezky zapsat klasický výpis foreach
obalený
jedním if
…else
pro kontrolu prázdnosti
procházeného pole?
{if $pole}
<table>
{foreach $pole as $prvek}
<tr><td>{$prvek}</td></tr>
{/foreach}
</table>
{else}
<p>Neexistují žádné prvky</p>
{/if}
Obsah tabulky pomocí foreach je jasný, nejlíp přes
inner-foreach
na <table>
, ale dá se nějak
pěkně zapsat i ten if
s else
? Samotného mě
nenapadá žádné schůdné řešení, tak jsem zvědavý, jestli nějaké
existuje. :)
- David Grudl
- Nette Core | 8218
Makro n:else
by mělo moc velký WTF faktor:
<table n:if="$pole">
<tr n:foreach="$pole as $prvek"><td>{$prvek}</td></tr>
</table>
<p n:else>Neexistují žádné prvky</p>
Vhodnější mi připadá přímočařejší řešení:
<table n:if="$pole">
<tr n:foreach="$pole as $prvek"><td>{$prvek}</td></tr>
</table>
<p n:if="!$pole">Neexistují žádné prvky</p>
- David Grudl
- Nette Core | 8218
Ještě pár nápadů pro šablony:
- Atribut
n:tag-if
určený pouze pro tag, obsah by zůstal:
<a href="logout" n:tag-if="$isSigned">{$name}</a>
// když $isSigned = TRUE
<a href="logout">{$name}</a>
// když $isSigned = FALSE
{$name}
- automatické odstraňování komentářů z HTML, pokud mají určitou syntax, např.
<!-- tento komentář v kódu zůstane -->
<!-- !tento bude odstraněn -->
- Naith_cz
- Člen | 8
Jak se na to dívám, nebylo by lepší převzít systém šablon z PHPTAL, tak aby se daly použít v obou systémech? Stejně se to k tomu přibližuje. Mělo by to výhodu v tom, že lze sdílet šablony, jak mezi projekty v Nette, tak i ty, kde Nette nelze použít a využije se pouze PHPTAL. Navíc by to pomohlo rozšířit Nette za hranice.
- Jan Jakeš
- Člen | 177
Stejně se to k tomu přibližuje.
To, že LatteFilter umí podobnou syntaxi jako PHPTAL vůbec neznamená, že se k PHPTAL přibližuje ;) Nette Templates umí výborně dědění, context-sensitive escaping, práci s AJAXem (která se má ještě změnit)… Šablonovací systém z Nette je pro mě jedna z killer-features a nahradit ho nějakým PHPTALem… Děkuji, nechci.
Editoval Juan (10. 10. 2009 10:58)
- grogy
- Člen | 147
Asi tak..
O Nette Mail se nejdřív také mluvilo, že není potřeba, že existuje spousta jiných (externích) knihoven, které jsou kvalitní a tak není znovu potřeba objevovat kolo.. Ikdyž to tak je, tak se ukázalo jak krásné je mít vlatní (Davidovo) řešení psané přesné na míru Nette (propojení se šablonami).
Proto si myslím, že převzít jiný šablonovací systém nepřipadá v úvahu, hlavně kvůli jejich síle jak jsou implementované v celém systému.
- Patrik Votoček
- Člen | 2221
Naith_cz napsal(a):
Jak se na to dívám, nebylo by lepší převzít systém šablon z PHPTAL, tak aby se daly použít v obou systémech? Stejně se to k tomu přibližuje. Mělo by to výhodu v tom, že lze sdílet šablony, jak mezi projekty v Nette, tak i ty, kde Nette nelze použít a využije se pouze PHPTAL. Navíc by to pomohlo rozšířit Nette za hranice.
Asi tak…
Nic ti nebrání v tom napsat si driver (pseudo filtr – prostředníka mezi PHPTAL a Nette\Template) kterej bude používat místo Latte (Nette – CurlyBrackets) PHPTAL. Troufám si říct že dokonce je to otázka pár minut (max hodin).
PS: co vím tak IInfo taky nepoužívá (možná už také používají Latte) ale jejich vlastní šablonovací systém. Někdo tu kdysi dávno dělal driver pro Smarty. Takže to vážně není problém…
Editoval vrtak-cz (10. 10. 2009 11:59)
- Naith_cz
- Člen | 8
Asi tak… (no neodolal jsem ;-))
@Juan
asi jsem to napsal špatně, ale nemyslel jsem to tak, že by měl převzít
PHPTAL. Co by se mohlo převzít, tak je syntaxe, tak aby byly šablony
přenositelné. Šlo mi o interoperabilitu.
@grogy
nedráždi mě tím kolem :-) Jinak situace u šablon je jiná, než u mail.
Šablony se mnohdy zadávají jinam (grafici, kodeři html) a bylo by vhodné
mít jednotnější syntaxi.
@vrtak-cz
tak to zatím nepůjde, protože se snažím logiku a kod Nette pochopit.
Nicméně, teď se mám projekt, u kterého jsem zjistil, že mohu využít pouze šablonovací systém. Očesal jsem Nette tak, abych tam měl jen to, co potřebuji pro šablonování, ale pak jsem si řekl, proč to vlastně dělám a jestli by nestačil šablonovací systém. Odpověď byla, přece zase nebudu předělávat šablony na Nette a opačně. Přesto jsem se po nich podíval a narazil jsem právě na PHPTAL, který se mi zdá elegantní. No a tady jsem zjistil, že vývoj konverguje podobným směrem, tak proč tu syntaxi nesjednotit?
malé srovnání
Nette
<ul n:inner-foreach="$items as $item">
<li>A {$item}</li>
<li>B {$item}</li>
</ul>
PHPTAL
<tr tal:repeat="item myresult">
<td tal:content="item">item value</td>
</tr>
Editoval Naith_cz (10. 10. 2009 14:58)
- na1k
- Člen | 288
Naith_cz, sám sice přenositelné šablony nijak nevyužiju, ale pokud bys na tom přeci jen stavěl, dostalo by se Nette do situace, kdy by bylo (ať už více nebo méně) závislé na PHPTALu. Protože jakmile jednou řekneš, že šablony přenositelné budou, tak jsou pak někteří lidé schopní tě i ukamenovat v případě, že PHPTAL přidal něco, co Nette neumí anebo naopak…
Líbí se mi, jak se Nette prezentuje, a sice že se neopičí, a přestože některé věci řeší podobně jako jiné frameworky/šablonovací jazyky, pořád jde svoji cestou a drží se nejlepších řešení. Už kvůli téhle myšlence bych jakékoliv provázání s cizími produkty (prakticky konkurenčními) omezil .. ideálně na nulu. (Samozřejmě rozšíření funkcí je věc jiná. V tomle případě ale Nette šablonovací jazyk má a to velice dobrý.)
A vůbec – k čemu ta přenositelnost? Možná mám málo zkušeností a proto se takhle blbě ptám, ale sám tíhnu k tomu, dělat co se dá v Nette a zbytečně nemíchat různé systémy, jazyky atp. A pokud jde o to, zadat práci někomu externímu (neprogramátorovi), tak pokud dotyčný rozumí PHPTALu, určitě nebude mít problém s Nette.
A kdyby i to snad někomu nešlo pod fousy, tak by snad šlo napsat nějaký skriptík na převod mezi těmi dvěma formáty, když už se tak moc podobají. Navíc ti Nette dovoluje použít vlastní šablonovací systém. Jen si troufám říct, že většina Nette komunity už dávno nahradila své oblíbené šablonovací systémy LatteFiltrem :)
- David Grudl
- Nette Core | 8218
@Juan
asi jsem to napsal špatně, ale nemyslel jsem to tak, že by měl převzít PHPTAL. Co by se mohlo převzít, tak je syntaxe, tak aby byly šablony přenositelné. Šlo mi o interoperabilitu.
Ono by to mělo smysl, kdyby PHPTAL byl velmi významný a hodně používaný, což asi není (ovšem nechci soudit, nevím). A jelikož každý systém má unikátní vlastnosti, přenositelnost stejně zaručit nelze.
- falkon
- Člen | 17
Dotaz bokom: Neslo by v Nette sablonach implementovat nieco ako
foreachelse
, zname napr. zo Smarty ? Uzitocna to vec napr. pri generovani riadkov
tabulky, ak nejake data dostupne su, resp. jedneho riadku s hlaskou „No items
found…“ ak data nie su.
Nikde som to bohuzial nenasiel, tak dufam ze nenosim drevo do lesa…
Diky.
- jasir
- Člen | 746
falkon napsal(a):
Dotaz bokom: Neslo by v Nette sablonach implementovat nieco ako
foreachelse
, zname napr. zo Smarty ? Uzitocna to vec napr. pri generovani riadkov tabulky, ak nejake data dostupne su, resp. jedneho riadku s hlaskou „No items found…“ ak data nie su.
Nikde som to bohuzial nenasiel, tak dufam ze nenosim drevo do lesa…
Diky.
Diskuze probíhala tady
- falkon
- Člen | 17
Dakujem, tuto diskusiu som naozaj nenasiel. Bohuzial dane vlakno je uz uzavrete, tak skusim reagovat sem (dufam, ze to nie je velky off-topic, kedze sa to tyka vylepsenia sablonovacieho jazyka:) ).
Honza M. napsal(a):
Mohl bys mi předvést příklad, kdy by se {foreachelse} vyplatilo? Přemýšlel jsem o tom, a člověk stejně vždycky nějaký ten výpis potřebuje obalit buď <table></table> nebo <ul></ul>…
<?php
<table>
<tr>
<th>...</th>
<th>...</th>
<th>...</th>
</tr>
{foreach $array as $item}
<tr>
<td>{$item->attr1}</td>
<td>{$item->attr2}</td>
<td>{$item->attr3}</td>
</tr>
{foreachelse}
<tr>
<td colspan="3">
No items found.
</td>
</tr>
{/foreach}
</table>
?>
Predvedene riesenie pouziva 3 znacky {znacka}
(vratane
koncovych); riesenie pouzitim
{if}{foreach}...{/foreach}{else}...{/if}
by pouzilo 5 znaciek.
Takze podla Tvojej definicie ‚vyplatilo se‘ sa to podla mna vyplati.
phx napsal(a):
Na foreachelse bych se asi vykaslal. Zbytecne by jsme tvorili neco co jde vytvorit za pomoci if a navic si .myslim, ze s if to bude prehlednejsi.
Nic v zlom, ale tento vyrok vo mne evokuje podobny vyrok, a to ten, ze kazdy program sa da napisat len s pouzitim while cyklov. Tak naco budovat cely framework, ked vsetko dokazeme poskladat z WHILE cyklov? :) Zeby preto, aby sme nemuseli vsetko v sablonach riesit pomocou {if} konstrukcii? ;)
- Proki
- Člen | 66
Zdravím, poslední dobou jsem nějak moc nesledoval novinky v oblasti nových vylepšení šablon, ale víceméně se mi velice zamlouvají. Jen jsem narazil na pár drobností.
Zajímalo by mě, jak to vypadá s makrem attr, které nyní v šablonách vypadá nehezky, pokud je zbytek šablony tvořen pomocí n: atributů. Tak jestli už existuje nějaká náhrada.
Dále bych měl ještě jednu prosbu. V <n:assign prom=„value“ /> může být hodnota value pouze textový řetězec, což nefunguje v případě, že potřebuji mít tuto hodnotu dynamicky měněnou podle obsahu stránky. Např. tímto nastavuji unikátní titulek v detailu nějaké položky. Přitom při použití složených závorek vše funguje bez problémů.
Předem dík za odpovědi.
Editoval Proki (22. 10. 2009 23:59)
- redhead
- Člen | 1313
Proki napsal(a):
Zajímalo by mě, jak to vypadá s makrem attr, které nyní v šablonách vypadá nehezky, pokud je zbytek šablony tvořen pomocí n: atributů. Ty jestli už existuje nějaká náhrada.
Určitě je to dobrý nápad, ale asi nebude snadné rozhodnout jak by to mělo vypadat:
<div n:class="'new', $n->isNew"></div>
?
- v6ak
- Člen | 206
K n:else: IMHO by to problém být nemusel. Spíš bych ale byl pro něco stylu n:foreach-parent a n:foreach-else:
<ul n:foreach-parent>
<li n:foreach="$items as $item">{$item}
</ul>
<div n:foreach-else class="no-items">Zatím nic</div>
nebo:
"
<ul n:inner-foreach="$items as $item">
<li>{$item}
</ul>
<div n:foreach-else class="no-items">Zatím nic</div>":null
Myslím, že by nebyl problém umožnit oboje. Mám určitou koncepci. Důležité je tu však jedno pravidlo: bylo by nutné uvést n:foreach-else ihned za n:foreach-parent, n:inner-foreach nebo n:foreach. To aby v tom nebyl zmatek.
Ke kombinaci n:if, n:foreach a dalších: tak toto mi už trošku magie přijde, toho bych se bál.
Dál bych doporučil dávat řídící Nette atributy před ostatní. Tím myslím hlavně if, foreach apod. U případného n:href by to nebylo potřeba, to není řídící.
Ke komentářům: je IMHO lepší, když to IDE zvýrazní, takže nějaké speciální syntaxi bych se nebránil.
K n:class: viděl bych to spíš jinak: n-expr:class=„$iterator->isEven()?‚even‘:null“. Důležitá by tu byla podpora null.
- Petr Motejlek
- Člen | 293
Proč máte tendenci vypisovat tabulku, jejíž jediný smysl je uživateli oznámit, že je prázdná? ;) Z hlediska nějaké SEO je to úplně k ničemu, protože stránka, která obsahuje jeden obrázek a 4 tabulky, ve kterých je jeden řádek s textem „Žádný záznam“, je IMHO zbytečná ;). Jedinou informaci nese ten obrázek, ty 4 tabulky je daleko lepší neukazovat vůbec.
Ještě k diskuzi, kterou jsme vedli v již smazaném vlákně ;): Tenhle n: systém má super výhodu hlavně v tom, že např. NetBeans při autoformátování nechápe curly brackets značkování (např. {if} pro něj nic neznamená) a blbne odsazování. Pokud jsou použité n: atributy, nic neblbne a krásně se odsazuje, takže jedině výhoda. Ještě si ale musím nějak nastavit, aby mi n: atributy zvýrazňoval třeba červeně, abych je nepřehlížel ;).
V neposlední řadě si vážím toho, že došlo k přejmenování CurlyBracketsFilter na LatteFilter ;) Konečně nemám se zavedením n: atributů žádný ideový problém.
- Cifro
- Člen | 245
Hlasim „quasi“ bug:
Z Davidovho príspevku:
<a href="logout" n:tag-if="{$isSigned}">{$name}</a>
Hore uvedený kód nefunguje v najnovšej verzii Nette 2010–01–06
(814b137). Vyhodí to parse error:
syntax error, unexpected '{', expecting T_STRING or T_VARIABLE or '$'
pretože $isSigned
nemá byť v {}
.
Takto to funguje:
<meta name="robots" n:tag-ifset="$robots" content="{$robots}" />
- Honza Kuchař
- Člen | 1662
Petr Motejlek napsal(a):
Ještě si ale musím nějak nastavit, aby mi n: atributy zvýrazňoval třeba červeně, abych je nepřehlížel ;).
Ahoj,
jestli se ti to padaří nastavit, dej mi prosím vědět.
Díky moc
- Petr Motejlek
- Člen | 293
Nevím, jestli je dobré pořád pokračovat v tomhle vlákně, ale jelikož to souvisí s tématem, radši to napíšu sem, než založím nové.
Začal jsem plně využívat n: atributy, jsem s nimi docela spokojen, hlavně se mi líbí, že už mi IDE docela obstojně zarovnává (i když jsem stále nevyřešil to jejich obarvování ;)). Měl bych ale otázečku, pořád ještě občas potřebuji udělat třeba assign, nebo něco podobného v rámci šablony, a přijde mi drobet nepřehledné, když se mi v jedné šabloně míchá jak n:, tak CurlyBrackets. Napadlo mě, jestli by se nedal vytvořit celý tag (např. <nette></nette>, případně <nette />), ve kterém by se daly konstrukce jako assign zapisovat. Mohl bych pak třeba dělat <nette n:assign=„bleble ⇒ 1“ />. Pokud je to úplná blbost, klidně mě zastavte ;).
- Proki
- Člen | 66
Bohužel některá makra takto nefungují,
<n:include name="file.phtml" />
hlásí, že nebyl zadán
název šablony, <n:widget name="form" />
hlasí že nebyl
zadán název componenty atd…
Navíc n:assign má menší problém v tom, že uvnitř něj nelze dynamicky
sestavit řetězec (např.:
<n:assign title="$page->name . ' | Název webu'" />
)
- Petr Motejlek
- Člen | 293
Já myslel, že se musí dělat <n:assign=„promenna ⇒ hodnota“ />. Tvar <n:assign promenna="" /> mě nenapadl, ale taky to nepůsobí špatně, šlo by pak udělat assignů víc ;).