Rekurze v šabloně se zacyklí
- Pan Dobrman
- Člen | 45
Dobrý den, snažil jsem se převést tento kód do šablony:
private function buildTree($parent2 = null)
{
foreach($this->menu as $name => $parent)
{
if($parent == $parent2)
{
echo $name;
$this->buildTree($name);
}
}
}
{block #menu}
{var $parent2 = null}
{foreach $menu as $name => $parent}
{if $parent == $parent2}
{$name}
{include #this, parent2 => $name}
{/if}
{/foreach}
{/block}
V php vše funguje v pořádku, jen v latte se zacyklí a vyhodí výjimku „Maximum function nesting level of ‚100‘ reached, aborting!“. Kde jsem udělal chybu?
Editoval Pan Dobrman (17. 7. 2012 22:08)
- Pan Dobrman
- Člen | 45
Bylo by možné v latte vytvořit, aby všechny poslední položky v každé větvi menu byly tučným písmem? Například takto:
- Menu 1
- Submenu 1
- Subsubmenu 1
- Submenu 2
- Submenu 1
- Menu 2
Pokusil jsme se použít makro last, ale to mi vždy označí tučným písmem jen poslední položku z úplně poslední větve (v příkladu položku „Submenu 2“).
{var $parent2 = null}
{block #menu}
{foreach $menu as $name => $parent}
{if $parent == $parent2}
{last}<strong>{/last}{$name}{last}</strong>{/last}
{include #this, parent2 => $name}
{/if}
{/foreach}
{/block}
Byl bych moc vděčný za radu. Děkuji
Editoval Pan Dobrman (18. 7. 2012 15:55)
- vvoody
- Člen | 910
Ty mas v $menu vsetky polozky a vzdy prechadzas uplne vsetky takze last moze byt len jedno. Mozno by si mohol vyuzit css selector :last-child alebo to menu poskladat este niekde popredu v modely a potom ho uz len takto vypisat s tym ze uz nebudes hladat vo vsetkych jeho polozkach, alebo do tretice :D ak to menu mas v DB tak to ide aj priamo s tym ze staci vlozit do sablony len selection na menu polozky s parentom NULL.
- Pan Dobrman
- Člen | 45
Děkuji za odpověď. Já měl za to, že pokud procházím pomocí rekurze, takže budu moci uplatnit makro last na více položek. Selector „:last-child“ by pro mě byl ideální, ale zjistil jsem, že bych potřeboval přidat ještě odkaz na vytvoření nové položky (což musím řešit v šabloně, protože přes css to nejspíše neudělám). V modelu jsem to nechtěl skládat, protože mi přijde čistější to udělat až v šabloně. Je něco takového možné v latte? Už se o to snažím skoro dvě hodiny, ale né a né na to přijít :).
- Pan Dobrman
- Člen | 45
Data mám předpřipravené tak, že při požadavku se mi vrátí pole ve tvaru ‚název‘ ⇒ ‚rodič‘. Pokud jsem vás správně pochopil, tak bych měl ke zpracování do šablony odeslat vždy jen jednu hlavní větev? např.:
1. cyklus
- Menu 1
- SubMenu 1
- SubSubMenu 1 #nebude označeno jako last
- SubMenu 2 #last
- SubMenu 1
2. cyklus
- Menu 2 #last
- Pan Dobrman
- Člen | 45
Mockrát děkuji za vás nápad. Výsledek vypadá takto (kód je ošklivý, psal jsem ho narychlo):
Komponenta:
public function render()
{
$return = array();
$this->generateTree($this->menu, null, $return);
$this->template->menu = $return;
$this->template->render();
}
private function generateTree($menu, $_parent = null, &$return)
{
foreach($menu as $name => $parent)
{
if($_parent == $parent)
{
$return[$name] = null;
unset($menu[$name]);
$this->recurse($menu, $name, $return[$name]);
}
}
}
Latte:
{var $_menu = $menu}
{block #menu}
<ul> /* Zatím nefunguje */
{foreach $_menu as $name => $parents}
<li>
{$name}
{if $parents != null}
{include #this, _menu => $parents}
{else}
Přidat novou položku
{/if}
</li>
{/foreach}
</ul>
{/block}
Editoval Pan Dobrman (18. 7. 2012 19:16)
- Pan Dobrman
- Člen | 45
Výstup není úplně podle mé představy, protože mám problémy s tagem <ul>. Chápete to správně, ale pokud vyměním makro else za last, tak se text „Přidat novou položku“ vypíše 2× (s else funguje vše jak má). Menu tahám z databáze jako pole ve tvaru: ‚název‘ ⇒ ‚rodič‘, poté ho přes funkci generateTree změním na:
array(2) {
"Menu 1" => array(2) {
"SubMenu 1" => array(1) {
"SubSubMenu 1" => NULL # 'název' => 'rodič'
}
"SubMenu 2" => NULL
}
"Menu 2" => NULL
}
- vvoody
- Člen | 910
Aky problem s tagom ul?
Ak pouzivate Nette/Database tak by bolo mozno lepsie riesenie z tohto vlakna.
- Pan Dobrman
- Člen | 45
Bohužel, používám Doctrine 2. Problém s tagem je, že jsem ho nejspíše špatně umístil :), takže se to pokusím přepsat a doufám, že poté už bude vše v pořádku.
- kbtm
- Člen | 22
Přeji dobrý den,
nechci zakládat nové vlákno, proto se ptám na možnost řešení stejné
chyby (Maximum function nesting level of ‚100‘ reached, aborting!) …
Aplikaci (seznamuji se s některými komponentami, problém je u komponenty
Menu od autora Murdej) zkouším pod několika prohlížeči – ale chyba se
objeví jen pod Firefoxem – v IE, Opeře a Chrome je vše OK.
Testuji na lokálu (WinXP + WampServer).
Pokud zkusím pustit testovací aplikaci „venku“ (http://menu.nette.murdej.cz/), je vše OK i pod
Firefoxem.
V prohlížeči jsou vyprázdněny všechny cache (tedy alespoň si myslím
…), pokud do aplikace úmyslně zavleču nějakou chybu (třeba změním
název třídy), je tato chyba správně ohlášena – tj. chybové hlášení
se změní.
Chyba se neprojevovala hned zpočátku – až po několika změnách aplikace.
Nyní ale zůstává stejná i při návratu k „originálu“ (modul
Menu.php, na řádce 179 :
178: public function Add($node) {
179: if (is_array($node)) {
180: $newNode = new MenuNode;
S pozdravem kbtm