menu pomocí Nette\Database

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
next
Člen | 4
+
0
-

Zdravím,
s nette začínám zatím vše OK, ale narazil jsem na problém s generováním menu.

struktura databáze

+----+-------+---------+-----------+
| id | title | link    | parent_id |
+----+-------+---------+-----------+
| 1  |  1.0. | default |    NULL   |
+----+-------+---------+-----------+
| 2  |  1.1. | default |     1     |
+----+-------+---------+-----------+
|..........další záznamy...........|

v presenteru

public function renderDefault($id = NULL)
{
    $query = $this->database->table('menu');

    if($id == NULL) {
			$query->where('parent_id', NULL);
			$this->template->menus = $query->fetchAll();
		} else {
			$query->where('parent_id', $id);
			return $query->fetchAll();
		}
}

v latte

{block #menu}
   <ul>
{foreach $menus as $menu}
        <li>
		{$menu->title}
		{var $childrens = $presenter->renderDefault($menu->id)}
		{foreach $childrens as $children}
			<ul>
				<li>
					{$children->title}
				</li>
			</ul>
		{/foreach}
        </li>
    </ul>
	{/foreach}
{/block}

menu se mi vypíše viz.

<ul>
     <li>Menu1
			<ul>
				<li>Submenu1</li>
			 </ul>
			<ul>
				<li>Submenu2</li>
			 </ul>
     </li>
     <li>Menu2</li>
     <li>Menu3</li>
     <li>Menu5
			<ul>
				<li>
					Sumnenu3
				</li>
			</ul>
     </li>
 </ul>

a s tím mi vyvstáají 2 problémy negeneruje se validní html při více položek submenu a nevím jak udělat teoreticky nekonečné menu (levely)

  • menu
  • menu > submenu
  • menu > submenu > subsubmenu
  • menu2
  • menu2 > submenu

nevím jestli je to špatným dotazováním na úrovně, nebo výpisem v latte.
Tohle menu je pouze 2 úrovňové, protože deklarovat pro každou úroveň proměnou se mi zdá po programátorské stránce jako zvěrstvo.

Předem děkuji za rady.

iguana007
Člen | 970
+
+1
-

Co se týče validity, tak by ti ty vnořené seznamy měly pomoci vyřešit latte makra first + last: https://latte.nette.org/cs/tags

Více úrovní dosáhneš tak, že si do té latte části zavedeš rekurzi, kterou tam nyní nemáš, proto si limitován jen na 2 levely stromu.

Osobně bych ti ale doporučil spíše jiný postup, který je výborně popsaný zde: http://php.vrana.cz/…rakticky.php a zde: http://php.vrana.cz/…uny-uzlu.php – sice je náročnější na údržbu (CRUD operace nad stromem), ale samotný výpis je velmi rychlý a jednoduchý + se s tím velice jednoduše vykreslují i další věci, jako je třeba drobečková navigace apod.

Editoval iguana007 (20. 11. 2014 11:28)

next
Člen | 4
+
0
-

iguana007 napsal(a):

Co se týče validity, tak by ti ty vnořené seznamy měly pomoci vyřešit latte makra first + last: https://latte.nette.org/cs/tags

makra first a last mi pomohli s validací – vyřešno

			{first}<ul>{/first}
				<li>
					{$children->title}
				</li>
			{last}</ul>{/last}

iguana007 napsal(a):

Více úrovní dosáhneš tak, že si do té latte části zavedeš rekurzi, kterou tam nyní nemáš, proto si limitován jen na 2 levely stromu.

Právě koukám na rekurzi a nějak nevím jak s tím pokročit jestli teda mám zrušit ten druhý dotaz na potomky nebo co s tím

iguana007 napsal(a):

Osobně bych ti ale doporučil spíše jiný postup, který je výborně popsaný zde: http://php.vrana.cz/…rakticky.php a zde: http://php.vrana.cz/…uny-uzlu.php – sice je náročnější na údržbu (CRUD operace nad stromem), ale samotný výpis je velmi rychlý a jednoduchý + se s tím velice jednoduše vykreslují i další věci, jako je třeba drobečková navigace apod.

na traverzování jsem koukal také, ale říkám si že je lepší začít pomalu :)

iguana007
Člen | 970
+
0
-

@next když si tady na fóru necháš vyhledat „menu rekurze“, tak ti to vrátí spoustu vláken, kde se totéž již řešilo – např. tady: https://forum.nette.org/…podkategorie

Editoval iguana007 (20. 11. 2014 12:20)

next
Člen | 4
+
0
-

Teď čtu různý články a příspěvky v diskuzích ale pořád tomu nemůžu přijít na kloub.

Když použiju způsob z článku tak mi to vyhazuje chybu Call to undefined method Nette\Database\Table\Selection::related()

next
Člen | 4
+
0
-

Omlouvám se moje chyba jsem měl překlep a všiml jsem si až teď :(

Takže vyřešeno dle vlákna

V presenteru

public function renderDefault($id = NULL)
{
		$this->template->menu = $this->database->table('menu')->where('parent_id',NULL);
}

a latte

{block #menu}
<ul>
    {foreach $menu as $item}
    <li>
		{$item->title}
		{? $selection = $item->related('menu','parent_id')}
		{if $selection->count()>0}
			{include #menu, menu => $selection}
		{/if}
    </li>
    {/foreach}
</ul>
{/block}

Díky za rady

Editoval next (20. 11. 2014 22:09)