[2008-12-12] Novinky v curlyBracketsFilter
- David Grudl
- Nette Core | 8227
V cyklech {foreach ...} ... {/foreach}
se automaticky
inicializuje proměnná $iterator, která obsahuje čístač a umí zjistit, zda
je aktuální prvek první nebo poslední. Příklad použití:
{foreach $rows as $row}
{if $iterator->isFirst()}
<table>
{/if}
<tr id="row-{$iterator->getCounter()}">
<td>{$row->name}</td>
<td>{$row->email}</td>
</tr>
{if $iterator->isLast()}
</table>
{/if}
{/foreach}
Podporované jsou i zanořené cykly. Nevýhodou je samozřejmě o něco
málo vyšší režie a blokování proměnné $iterator
pro
vlastní použití.
Syntax by pak šlo rozšířit o {foreachelse}
, tj. oblast pro
případ, kdy iterator neobsahuje žádné prvky:
{foreach $rows as $row}
...
{foreachelse}
<p>V tabulce nejsou žádné záznamy</p>
{/foreach}
Druhou novinkou je kontextové připínání escapování. V HTML by se escapovalo klasicky přes htmlSpecialChars(), v JavaScriptu by se volalo nejspíš json_encode(), pro CSS bych připravil speciální funkci (důvody viz třeba https://phpfashion.com/…-javascriptu). Příklad:
<p>Hodnota: {$value}</p> // ekvivalent <?= htmlSpecialChars($value) ?>
<script>
var value = {$value}; // ekvivalent <?= json_encode($value) ?>
</script>
A do třetice: díky refactoringu uvažuju nad přesunutím podpory pro
snippety ze třídy Control přímo do šablon. Takže se ptám, jestli někdo
přímo nepoužívá metody $control->beginSnippet()
a
$control->endSnippet()
?
- Honza Marek
- Člen | 1664
{foreachelse} vypadá na první pohled hezky… ale asi by se to muselo používat s tím {if $iterator->isFirst()}<table>{/if}, což mi nepřijde hezčí než vypsat <table> před {foreach}…
K iterátoru by bylo možná hezké mít metody isOdd a isEven, ale já bych je stejně nepoužil, protože řádky tabulky se dají obarvit přes jQuery :-D
- Tomik
- Nette Evangelist | 485
Honza M. napsal(a):
{foreachelse} vypadá na první pohled hezky… ale asi by se to muselo používat s tím {if $iterator->isFirst()}<table>{/if}, což mi nepřijde hezčí než vypsat <table> před {foreach}…
K iterátoru by bylo možná hezké mít metody isOdd a isEven, ale já bych je stejně nepoužil, protože řádky tabulky se dají obarvit přes jQuery :-D
No jo, ale v tom případě si musíš někde inicializovat boolean, zda
v poli $rows
je alespoň jeden záznam, pokud ne, pak vypsat
hlášku, že nic není, pokud ano, pak vypsat hlavičku tabulky, tzn. přijde
mi to Davidem navrhované řešení lepší (a pokud se to dobře popíše do
dokumentace, myslím, že by to ani nemělo mást nové uživatele).
- phx
- Člen | 651
Tak jako tak jde pouzit novy a stazy zpusob. Table ve foreach nebo pred a za. Toto me vubec netrapi:)
Urcite se ale primlouvam za isOdd a isEven. Jinak pekny.
Dale me jeste napda, ze by se mohlo hodit aby iterator mel nejake citace. Napr kdyz pod tabulkou budu chtit vypsat sumu. I kdyz asi by to bylo jako jit na komara s brokovnici.
- Tomik
- Nette Evangelist | 485
phx napsal(a):
Tak jako tak jde pouzit novy a stazy zpusob. Table ve foreach nebo pred a za. Toto me vubec netrapi:)
Urcite se ale primlouvam za isOdd a isEven. Jinak pekny.
Dale me jeste napda, ze by se mohlo hodit aby iterator mel nejake citace. Napr kdyz pod tabulkou budu chtit vypsat sumu. I kdyz asi by to bylo jako jit na komara s brokovnici.
Souhlasím s tím, že je to pěkná myšlenka, jinak se také přimlouvám za isOdd a isEven, rozhodně to může ušetřit práci. ;)
- David Grudl
- Nette Core | 8227
Tomik napsal(a):
Honza M. napsal(a):
{foreachelse} vypadá na první pohled hezky… ale asi by se to muselo používat s tím {if $iterator->isFirst()}<table>{/if}, což mi nepřijde hezčí než vypsat <table> před {foreach}…
No jo, ale v tom případě si musíš někde inicializovat boolean, zda v poli
$rows
je alespoň jeden záznam, pokud ne, pak vypsat hlášku, že nic není…
Souhlasím, že přínos konstrukce {foreachelse} je sporný.
Jinak isOdd() tam taky je. Jako největší přínost vidím hlavně isLast() – to se jen velmi těžko řeší v běžných podmínkách.
- Honza Marek
- Člen | 1664
Snažím se vymyslet nějakou krásnou syntax pro ulehčení napsání toho, že nemám co vypsat. Zatím jsem vymyslel toto. Zhodnocení toho, jestli je to blbost nechám na vás.
{iterate}
<table>
{foreach $rows as $row}
<td>{$row->name}</td>
<td>...</td>
{/foreach}
</table>
{/iterate}
{ifEmpty}
Nic nemáme
{/ifEmpty}
EDIT: asi je to blbost
{if count($rows) > 0}
<table>
{foreach $rows as $row}
...
{/foreach}
</table>
{else}
Nic tu není
{/if}
Oproti tomuto to rozhodně neni lepší…
Editoval Honza M. (11. 12. 2008 22:33)
- Honza Marek
- Člen | 1664
A pokud tam bude isOdd, dal bych tam i isEven. Nikdo si nebude pamatovat, kterej z nich tam je…
- Patrik Votoček
- Člen | 2221
Já dřív u svého frameworku (který sem používal než vyšlo nette) měl něco takového:
<?php
{ifforeach $data}
<ul>
{foreach $data as $value}
<li>{$value}</li>
{/foreach}
</ul>
{elseforeach}
<p>No repeating data</p>
{/ifforeach}
?>
Také uvnitř foreach existoval objekt iterator který vracel zda je to první/poslední/sudý/lichý/kolikátý cikl.
- Honza Marek
- Člen | 1664
Tomik napsal(a):
Já tedy osobně bych pro
{foreachelse}
byl, podle mě to zas tak hrozně syntaxi neznepřehledňuje a ten, kdo to nezná, může klidně bez závady (pouze si přidělá práci) používat nějaký vlastní způsob (toto platí i pro ty, kteří to nechtějí). :)
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>…
- David Grudl
- Nette Core | 8227
Všechno (kromě foreachelse) je implementované a mělo by to být funkční.
- David Grudl
- Nette Core | 8227
Protože filtr curlyBrackets narostl, tak jsem jej přesunul do samostatné třídy CurlyBracketsFilter.
// misto $template->registerFilter(/*Nette\Templates\*/'TemplateFilters::curlyBrackets');
$template->registerFilter(/*Nette\Templates\*/'CurlyBracketsFilter::invoke');
Starý způsob funguje, ale vygeneruje varování.
- Ola
- Člen | 385
Zdravím, po aktualizaci na poslední revizi mi nikde nefungují foreachy .. vždy mi to vyhodí toto:
Parse error: syntax error, unexpected T_AS in C:\www\nette\app\temp\cache-Nette.Template%00ad5a9a3fd70273d0c56f2056ea09836d.LastArticlesControl.phtml on line 10
Na danym řádku je v cache toto:
<?php foreach ($iterator = $_cb->iterators[] = new SmartCachingIterator($posts AS $key => $post"): ?>
EDIT: Tak to je tim, že v templatách píšu AS velkym písmem, ale nahrazuje se jen malý as .. Davide, opravíš to?
Editoval Ola (12. 12. 2008 6:56)