NavigationBuilder – udělátko pro dynamické skládání navigace

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

Rád bych vám představil NavigationBuilder, jednoduchý nástroj pro tvorbu webové navigace:

Features

  • dynamické přidávání/mazání položek navigace
  • neomezené množství zanořených úrovní
  • podpora pro lokalizaci
  • Verze 2.0 možnost řazení položek podle nastavené priority nebo názvu
  • Verze 2.0 vylepšená podpora komponentového modelu Nette
  • fluent interface
  • extrémně jednoduchá konfigurace i obsluha

Použití

Inicializace komponenty v presenteru:

<?php

class MyPresenter extends Presenter
{
	public function createComponentNavigation($name)
	{
		$navigation = new Navigation;
		// nastavení překladače (nepovinné)
        $navigation->setTranslator(new MyTranslator);

        // nastavení šablony (nepovinné)
        $navigation->setTemplate('/cesta/k/sablone.phtml');

        $navigation->getRoot()->label = 'Homepage';

        $navigation->add('Articles', $this->link('Articles:default'));
	}
}
?>

Zobrazení komponenty v šabloně

<div id="my_navigation">
{control navigation}
</div>

Co na to říkáte? Mám to hodit i do Nette\Extras?

Editoval Karel Klíma (29. 10. 2009 20:24)

Honza Kuchař
Člen | 1662
+
0
-

Mám to hodit i do Nette\Extras?

Wiki je furt zamčená. :(


Vypadá to fajn. Plánoval jsem něco takového udělat, ale i s podporou AJAXu. Z tohoto by potom dědil TabControl. (nemá od klasického menu strukturou moc daleko)

Michalek
Člen | 211
+
0
-

U mě ok, doteď jsem to řešil přes vlastní „systém“, ale tohle je samozřejmě lepčejší :-) Takže díky. Připomínky a nápady nemám, páč to dělá přesně to co potřebuju, nic víc, nic míň.

EDIT: Už jsem na to přišel, chybí mi priority, případně řazení dle něčeho :-) Různě postupně v modulech přidávám položky a občas bych nějakou potřeboval šoupnout pomocí priority výš než tu předchozí.

Editoval Michalek (18. 10. 2009 23:32)

Jakub Šulák
Člen | 222
+
0
-

Mě v této komponentě chybí možnost nastavit oprávnění…

Karel Klíma
Člen | 31
+
0
-

Michalek napsal(a):

EDIT: Už jsem na to přišel, chybí mi priority, případně řazení dle něčeho :-) Různě postupně v modulech přidávám položky a občas bych nějakou potřeboval šoupnout pomocí priority výš než tu předchozí.

To mi tam chybí taky :-) Plánuji to dodělat do druhé, rozšířené verze. Zatím se mi nepodařilo najít nějaký pěkný způsob, jak prioritu nastavovat, resp. řadit dle ní a jak se chovat k položkám, které prioritu nemají.

Jedna z možností je nechat na uživateli, co za hodnotu prioritě přiřadí (ať už string nebo integer), řadit se to dá tak jako tak. Položky bez priority by se pak daly appendovat na konec, což se mi ale zas tolik nelíbí. Další variantou by mohly být předem definované priority (highest, high, medium, low, lowest), s tím, že položky bez priority by měly implicitně nastavenou prioritu medium a pak by se ještě mohly (nebo nemusely) řadit podle abecedy… A teď babo raď, co z toho implementovat.

Michalek
Člen | 211
+
0
-

U sebe jsem to řešil normálně INTem. Tzn. Položka „Hlavní strana“ měla 100, „Bazar“ 80 a „Fórum“ 60. Potřeboval jsem jich hodně… Všechno jsem to cpal do pole a pak řadil uživatelskou funkcí pro pole.

Osobně jsem položky bez priority neměl, ale to je otázka osobních preferencí a chápu, že tohle by mělo být univerzálnější :-)

Honza Marek
Člen | 1664
+
0
-

Můžu se zeptat k čemu to je?

P.S.: Nedalo mi to a zjednodušil jsem příklad. Spousta řádků je tam takových nesmyslných.

class MyPresenter extends Presenter
{
	public function createComponentNavigation($name)
	{
		$navigation = new NavigationBuilder($this, $name);

		// nastavení překladače (nepovinné)
		$navigation->setTranslator(new MyTranslator);

		// nastavení šablony (nepovinné)
		$navigation->setTemplate('/cesta/k/sablone.phtml');

		// vložení několika položek
		$navigation->add('Domů', 'http://www.example.com')
			->add('Produkty', $this->link('Products:default'))
			->add('Kontakt', $this->link('Contact:default'));
		$navigation->get('Produkty')
			->add('Pasti na myši', $this->link('Products:traps'))
			->add('Ničivé zbraně', $this->link('Products:guns'));
	}
}
Michalek
Člen | 211
+
0
-

K čemu to je?

Mám různé moduly – Bazar, Chat, Eshop, Diskuzi. V BasePresenteru si udělám NavigationBuilder $navigationMain a v presenterech modulů do nich přidávám další položky. Pokud vypnu Bazar, automaticky mi zmizí odkaz z menu. Nenapadlo mě jiné řešení, než to dělat podobným stylem jako tady.

Řeším takhle i „dynamické“ přidávání obsluhy modulů do NavigationAdmin. Jde o jakýsi rozšířitelný CMS systém.

A prozatím jsem na to „narouboval“ i systém breadcrumbs navigace.

Editoval Michalek (19. 10. 2009 20:44)

Honza Marek
Člen | 1664
+
0
-

To nandávání sekcí galerie do menu plnýho článků zní smysluplně.

Karel Klíma
Člen | 31
+
0
-

Honza M. napsal(a):

P.S.: Nedalo mi to a zjednodušil jsem příklad. Spousta řádků je tam takových nesmyslných.

Tos to teda zjednodušil :-)

Moje verze byla trochu odlišná, a to zcela záměrně. Musí se totiž počítat s tím, že ne vždy bude skript, který načítá data do menu, součástí presenteru (může být volán například přes events). I proto tam bylo to Environment::getApplication()->getPresenter();. Co se týče samotné „továrničky“ na komponentu, je čistě otázka preferencí, jestli ji implementovat nebo ne. Pokud mám na stránce jedinou navigaci, pak je kvůli tomu zbytečné psát samostatnou inicializační funkci. A já se klidně vsadím, že tato komponenta se bude z 90 % případů vyskytovat pouze jednou.

jasir
Člen | 746
+
0
-

Karel Klíma napsal(a):
… Co se týče samotné „továrničky“ na komponentu, je čistě otázka preferencí, jestli ji implementovat nebo ne. Pokud mám na stránce jedinou navigaci, pak je kvůli tomu zbytečné psát samostatnou inicializační funkci. A já se klidně vsadím, že tato komponenta se bude z 90 % případů vyskytovat pouze jednou.

Tady máš sice pravdu, ale mám takové tušení, že framework jde směrem, kdy bude potřebovat umět určit, které komponenty presenter/control umí vyrobit a kde. Továrničky doporučuji používat.

Editoval jasir (20. 10. 2009 9:40)

Ondřej Mirtes
Člen | 1536
+
0
-

Všechny potomky třídy Control by měl Presenter vytvářet v továrničce. Asi sepíšu nějaké „Advanced coding standards“ :)

Honza Marek
Člen | 1664
+
0
-

Tak já představím svojí verzi. Lépe využívá komponentového modelu Nette. Dále také umí označit aktuální položku a dá se využít k tvorbě drobečkové navigace.

Příklad

class HomepagePresenter extends BasePresenter {

	public function createComponentNavigation($name) {
		$menu = new Navigation($this, $name);
		$menu->setupHomepage("Úvodní stránka", $this->link("Homepage:"));
		$menu->add("Stránka", "/adresa");
		$sekce = $menu->add("Sekce", "/sekce");
		$clanek = $sekce->add("Článek", "/clanek");
		$sekce->add("Article", "/article");

		$menu->setCurrent($clanek);
	}

}

Komponenta nemá fluent interface (většinou se budou položky stejně přidávat v cyklu), ale metody add vrací právě přidaný objekt, takže je možné si jej uložit do proměnné a pak s ním operovat.

Ukázka šablony:

{control navigation:menu}
{control navigation:breadcrumbs}

(Lépe odsazený) výstup

<ul class="control menu">
	<li>
		<a href="/">Úvodní stránka</a>
	</li>
	<li>
		<a href="/adresa">Stránka</a>
	</li>
	<li>
		<a href="/sekce">Sekce</a>
		<ul>
			<li>
				<strong>Článek</strong>
			</li>
			<li>
				<a href="/article">Article</a>

			</li>
		</ul>
	</li>
</ul>

<div class="control breadcrumbs">
	<a href="/">Úvodní stránka</a> &rarr;
	<a href="/sekce">Sekce</a> &rarr;
	<span class="current">Článek</span>
</div>

Kód komponenty

Navigation.php

<?php

/**
 * Navigation
 *
 * @author Jan Marek
 * @license MIT
 */
class Navigation extends NavigationNode {

	/** @var NavigationNode */
	private $current;

	/**
	 * Set node as current
	 * @param NavigationNode $node
	 */
	public function setCurrent(NavigationNode $node) {
		if (isset($this->current)) {
			$this->current->isCurrent = false;
		}
		$node->isCurrent = true;
		$this->current = $node;
	}

	/**
	 * Setup homepage
	 * @param string $label
	 * @param string $url
	 * @return Navigation
	 */
	public function setupHomepage($label, $url) {
		$this->label = $label;
		$this->url = $url;
		return $this;
	}

	/**
	 * Render menu
	 */
	public function renderMenu() {
		$this->createTemplate()
			->setFile(dirname(__FILE__) . "/menu.phtml")
			->render();
	}

	/**
	 * Render breadcrumbs
	 */
	public function renderBreadcrumbs() {
		if (empty($this->current)) return;

		$items = array();
		$node = $this->current;

		while (isset($node)) {
			array_unshift($items, $node);
			$node = $node->parent;
		}

		$template = $this->createTemplate()
			->setFile(dirname(__FILE__) . "/breadcrumbs.phtml");
		$template->items = $items;
		$template->render();
	}

}

NavigationNode.php

<?php

/**
 * Navigation node
 *
 * @author Jan Marek
 * @license MIT
 */
class NavigationNode extends Control {

	/** @var string */
	public $label = "undefined";

	/** @var string */
	public $url = "#";

	/** @var NavigationNode */
	public $parent;

	/** @var bool */
	public $isCurrent = false;

	/**
	 * Add navigation node as a child
	 * @staticvar int $counter
	 * @param string $label
	 * @param string $url
	 * @return NavigationNode
	 */
	public function add($label, $url) {
		$navigationNode = new self;
		$navigationNode->label = $label;
		$navigationNode->url = $url;
		$navigationNode->parent = $this;

		static $counter;
		$this[++$counter] = $navigationNode;

		return $navigationNode;
	}

}

menu.phtml

<ul class="control menu">
	<li>
		{if $control->isCurrent}
		<strong>{$control->label}</strong>
		{else}
		<a href="{$control->url}">{$control->label}</a>
		{/if}
	</li>
	{assign $children $control->getComponents()}
	{block #menu}
	{foreach $children as $item}
	<li>
		{if $item->isCurrent}
		<strong>{$item->label}</strong>
		{else}
		<a href="{$item->url}">{$item->label}</a>
		{/if}

		{if count($item->getComponents())}
		<ul>
			{include #menu, children => $item->getComponents()}
		</ul>
		{/if}
	</li>
	{/foreach}
	{/block}
</ul>

breadcrumbs.phtml

<div class="control breadcrumbs">
	{foreach $items as $item}
	{if $iterator->isLast()}
	<span class="current">{$item->label}</span>
	{else}
	<a href="{$item->url}">{$item->label}</a> &rarr;
	{/if}
	{/foreach}
</div>

Budoucnost

  • Tohle je zatím taková pracovní verze, tak tu zatím nejdou měnit měnit šablony či označit třídou rodiče $currentu jako aktivní položky. Všechno bude.
  • Přemýšlím o generování sitemapy.
  • Uvítám další nápady.
  • Translator mi přijde zbytečný, protože většinou v menu budou články a tak a tam se tahají z databáze rovnou přeložené názvy.
redhead
Člen | 1313
+
0
-

Hezké, zdá se že si vždycky musíš udělat svojí verzi komponent ;)

Jinak to s tím translatorem, wtf? Kdo říkal, že v menu musí být pouze články?

Co třeba Domů → Statistiky → Návštěvnost?? To tahat z db asi nebudu, takže s absencí translatoru musím nesouhlasit.

Jinak když jsem dělal vlastní (velmi jednoduchou) komponentu na navigaci, tak jsem trochu koumal nad tím linkováním, a došel jsem k trochu rychlejší (rychleji psané) variantě kdy jsem volal něco jako:

<?php
$menu->add('Kategorie', 'Default:category', $catId);
?>

Vlastně si to komponenta sama převedla přes $presenter->link().

Ovšem nevím, zda je to bylo moudrý nebo spíš správný návrh. Problém jsem s tím ale neměl.

Honza Marek
Člen | 1664
+
0
-

Jasný, ale podle mě takových odkazů bude menšina a tudíž nebude problém zavolat nějaké Helpers::translate($text). Spíše naopak, pokud se to bude míchat s nepřekládanými texty. Hlavně já to zatím nepotřebuju :)

Michalek
Člen | 211
+
0
-

Zdá se mi, že beru jako „menu“ něco jiného než ty…

Menu s články, když jich mám přes 20.000, neplánuju. Mám to čistě na přepínání mezi moduly, orientace v admin menu (každý modul si zaregistruje třeba Bazar / Přidat – Upravit – Smazat) a breadcrumbs.

Taky to pořád neřeší prioritu, dejme tomu, že registruji postupně moduly Bazar, Obchod a Diskuze, ale v menu bych to rád měl seřazené jako Diskuze, Bazar, Obchod. :-)

Honza Marek
Člen | 1664
+
0
-

Michalek napsal(a):

Zdá se mi, že beru jako „menu“ něco jiného než ty…

Menu s články, když jich mám přes 20.000, neplánuju.

Nemusejí se načíst všechny, ale třeba jen ty v rozbalených sekcích. Nebo vůbec žádné, to je jedno.

Mám to čistě na přepínání mezi moduly, orientace v admin menu (každý modul si zaregistruje třeba Bazar / Přidat – Upravit – Smazat) a breadcrumbs.

Hm tady by ten translator asi dával smysl.

Taky to pořád neřeší prioritu, dejme tomu, že registruji postupně moduly Bazar, Obchod a Diskuze, ale v menu bych to rád měl seřazené jako Diskuze, Bazar, Obchod. :-)

Nad tím ještě popřemýšlím. Teď mě napadá vyřešit to v metodě add projetím všech komponent, porovnáním a vložením před první komponentu s nižší prioritou.

redhead
Člen | 1313
+
0
-

Věř mi, že translator by se určitě hodil. Pokud se nejedná o nějaký EShop nebo Blog, tak bych ho využil skoro úplně všude, zvláště u nějaký specializovaných webových aplikací.

Tomik
Nette Evangelist | 485
+
0
-

Říkal jsem o tom už Honzovi na Webexpu, mám menu komponentu i se správou (přetahováním jednotlivých položek), to video jsem dělal pro Honzu (aby se moh' inspirovat), ale kdo by se chtěl podívat… http://tomik.jmx.cz/nette/menu.avi :) Pokud by o to byl zájem, zveřejním to, ale nebude to hned, chvilku mi to bude trvat, rád bych to dal do nějakého „obecnějšího znovu použitelného“ tvaru. Případně bych to mohl poslat Honzovi a on by si s tímto pohrál. ;)

Michalek
Člen | 211
+
0
-

To je pro mě osobně zase moc, jdu směrem, že v adminu nebudou tyhle provozní věci vůbec editovatelné. Můžu si to dovolit, nedělám CMS pro veřejnost ala Wordpress/Joomla :)

Tomik
Nette Evangelist | 485
+
0
-

Michalek napsal(a):

(…) Můžu si to dovolit, nedělám CMS pro veřejnost ala Wordpress/Joomla :)

Šťastný člověk! :)

Karel Klíma
Člen | 31
+
0
-

Honza M. napsal(a):

Tak já představím svojí verzi. Lépe využívá komponentového modelu Nette. Dále také umí označit aktuální položku a dá se využít k tvorbě drobečkové navigace.

Tvoje verze mě donutila k tomu, abych šel zas studovat manuál ke komponentám :-) Využítí toho „oficiálního“ modelu vypadá pěkně. Já jsem v mezičase dost podstatně rozšířil tu svoji verzi, doplnil jsem například řazení (na čtyři způsoby) a další markantní vylepšení (včetně překladu).

Pokud se najde nějaký dobrovolník, který bude ochoten udělat syntézu obou verzí, vznikne docela dobrá a použitelná komponenta :-)

Honza Marek
Člen | 1664
+
0
-

Karel Klíma napsal(a):

Tvoje verze mě donutila k tomu, abych šel zas studovat manuál ke komponentám :-) Využítí toho „oficiálního“ modelu vypadá pěkně.

Fajn. Jinak já jsem to ještě přepsal tak, aby Navigation nedědila od NavigationNode. Tím pádem může být NavigationNode potomkem třídy Component místo Control. Ta je o dost složitější, což se při více položkách (např. 1000) znatelně projeví na rychlosti.

Karel Klíma
Člen | 31
+
0
-

Honza M. napsal(a):

Karel Klíma napsal(a):

Tvoje verze mě donutila k tomu, abych šel zas studovat manuál ke komponentám :-) Využítí toho „oficiálního“ modelu vypadá pěkně.

Fajn. Jinak já jsem to ještě přepsal tak, aby Navigation nedědila od NavigationNode. Tím pádem může být NavigationNode potomkem třídy Component místo Control. Ta je o dost složitější, což se při více položkách (např. 1000) znatelně projeví na rychlosti.

Původně jsem to měl taky tak oddělené, ale pak jsem to spojil do jednoho, hrozně nerad se totiž opakuju v psaní kódu. Každé řešení má svoje pro a proti…

Karel Klíma
Člen | 31
+
0
-

Pustil jsem na svobodu novou verzi, viz první příspěvek v tomto vláknu: https://forum.nette.org/…ani-navigace

Oggy
Člen | 306
+
0
-

Honza M. napsal(a):

Karel Klíma napsal(a):

Tvoje verze mě donutila k tomu, abych šel zas studovat manuál ke komponentám :-) Využítí toho „oficiálního“ modelu vypadá pěkně.

Fajn. Jinak já jsem to ještě přepsal tak, aby Navigation nedědila od NavigationNode. Tím pádem může být NavigationNode potomkem třídy Component místo Control. Ta je o dost složitější, což se při více položkách (např. 1000) znatelně projeví na rychlosti.

je možné to někde vidět? děkuju

sodae
Nette Evangelist | 250
+
0
-

v NavigationNode je menší bug a to na řádku 325 , nastavuje adresu na #

Edit: verze 2

Editoval sodae (27. 10. 2009 14:29)

forkman
Člen | 72
+
0
-

Mohl bych poprosit o nějaký polopatický návod pro začátečníky, jak tu komponentu použít?
Vytvoření komponenty jsem si dal do BasePresenteru a {control navigation} mi nadává, že taková komponenta neexistuje.
Určitě by se hodilo tohle „udělátko“ líp zdokumentovat ;-)

Edit
Dobře, tak to bylo jen tím, že v Example je špatně ta komponenta vytvořená, bug s # mě zase tak nezaskočil, ale je to moc dobrá práce.

Editoval forkman (30. 10. 2009 9:34)

Karel Klíma
Člen | 31
+
0
-

sodae napsal(a):

v NavigationNode je menší bug a to na řádku 325 , nastavuje adresu na #

Edit: verze 2

Díky za upozornění, v nové verzi 2.1 je to již opraveno.

jasir
Člen | 746
+
0
-

Tomik napsal(a):

Říkal jsem o tom už Honzovi na Webexpu, mám menu komponentu i se správou (přetahováním jednotlivých položek), to video jsem dělal pro Honzu (aby se moh' inspirovat), ale kdo by se chtěl podívat… http://tomik.jmx.cz/nette/menu.avi :) Pokud by o to byl zájem, zveřejním to, ale nebude to hned, chvilku mi to bude trvat, rád bych to dal do nějakého „obecnějšího znovu použitelného“ tvaru. Případně bych to mohl poslat Honzovi a on by si s tímto pohrál. ;)

Tak jsem se podíval na video a vypadá to perfektně. Bravo!

Nechceš to tedy zveřejnit? Bylo by to skvělé… Díky!.

Honza Kuchař
Člen | 1662
+
0
-

Bylo by to skvělé… Díky!.

Bylo by to výborné!! :)

Oggy
Člen | 306
+
0
-

honzakuchar napsal(a):

Bylo by to skvělé… Díky!.

Bylo by to výborné!! :)

jj:-)

Mám ještě dotaz.. jak takovéhle komponenty s web strukturou používáte?..
Hned si ji naplníte všemi sekcemi..články? ..
Nebo si do té struktury připádávet navštívené větve? .. jak by se potom dal udělat export sitemapy? ..
Cachujete si již jednou dejme tomu z db načtenou strukturu?

Michalek
Člen | 211
+
0
-

Tak jsem se k tomu konečně dostal :-)

Osobně mi v „návodu“ chybí ukázka jak řadit (jde to najít ze zdrojáku, jasně, ale ušetřilo by to pár vteřin), pak pro laika je asi nicneříkající řádek $navigation->getRoot()->label = 'Homepage';.

A nakonec, Hlavní strana – priorita 1000, Článek – priorita 500, Jak jsme šli na houby – priorita 100. A ono se to řadí obráceně než bych čekal :-)

Jinak ale dost dobrý.

Editoval Michalek (30. 10. 2009 12:50)

Oggy
Člen | 306
+
0
-

Bohužel se mi nedostalo odpovědi a rád bych si vyslechl názor zkušenějších programátorůn takže svůj dotaz, pokud dovolíte :-), zopakuji.

Jak komponentu typu NavigationBuilderu používáte?

Akorát jsem něco takového bastlil.. ale nejsem si přesně jist jak to uchopit.

Jestli při startu webu naplnit komponentu všemi sekcemi atd? .. Z toho jsem ustoupil, protože mi to přijde absolutně zbytečné (naopak se to krásně dá použít k výše zmíněnému generovaní mapy webu, sitemap pro google atd.)

Poté teda nastává otázka jak plnit komponentu až když je to potřeba..
Celkovou strukturu mám v db..
Takže při vytvoření komponenty bych naplnil říkám tomu tabs.. tedy základní rodiče =(hlavní menu) a potomky těchto tabů plnil až když jsou potřeba… ale jak je plnit..pokud přijdu na web v některé sekci z hlubší struktury?.. poté by bylo potřeba vytvořit všechny sekce ze stejným rodičem jako má akt. sekce ..vytvořit rodiče a předtím vytvořeným potomkům přidat rodiče atd..až k příslušnému tabu.
Nevím jestli je to zrovna ok..:-/

Nejde ani tak přímo o kód, ale myšlenku jak tuto situaci nějak čistě a rychle řešítě?..

Ono k Nette jsem přišel nedávno :-) a nejsem si jist, jestli celá komponenta má být potomkem ComponentContaineru a jednotlivé sekce Componenty..nebo je lepší Control..(pokud tedy pomineme nějaké ajax vykreslení) atd.

Karel Klíma
Člen | 31
+
0
-

Oggy napsal(a):

Jak komponentu typu NavigationBuilderu používáte?

Já osobně využívám dvojí metodu pro přidávání položek. V rámci aplikaci mám moduly, každý modul má svou vlastní třídu (např. UsersModule, nemá to s Nette moc společného). Architekturou je to podobné Drupalu – neobsahuje to v podstatě žádné jádro, ale je to jako skládanka. Jeden z těchto modulů hlavní, obsahuje navigaci a property onNavigationBuild, která se použije jako event handler při inicializaci nebo renderování navigace.

V praxi mám pak v nějakém base presenteru něco jako:

<?php
public function startup() {
    $navigation = $this->getComponent('navigation');
    Modules::get('Nejaky_modul')->onNavigationBuild($navigation);
}
?>

a v nějakém jiném modulu/presenteru například tohle:

<?php
public function startup() {
    Modules::get('Nejaky_modul')->onNavigationBuild[] = array($this, 'setupNavigation');
}
public function setupNavigation(Navigation $navigation) {
    $navigation->add('Polozka', 'url');
    ...
}
?>

Nejsem si jistý, zda-li je tohle optimální použití, ale funguje mi to spolehlivě.

kybermonty
Člen | 10
+
0
-

Díky za tuhle komponentu, ale uvítal bych i dynamické nastavení aktuální položky v menu.

Tady je kód, jak jsem to řešil já…

V presenteru:

$navigation = new Navigation;
// ...
$current = $navigation->findByLink($this->link($this->getAction()));
if ($current != NULL) {
	$navigation->setCurrent($current);
}

Ve třídě Navigation:

public function findByLink($link)
{
	// projde rekurzivně všechny položky v menu
	foreach ($this->root->getComponents(TRUE) as $item) {
		if ($item->url === $link) {
			return $item;
		}
	}
	return NULL;
}
Vyki
Člen | 388
+
0
-

jasir napsal(a):

Tomik napsal(a):

Říkal jsem o tom už Honzovi na Webexpu, mám menu komponentu i se správou (přetahováním jednotlivých položek), to video jsem dělal pro Honzu (aby se moh' inspirovat), ale kdo by se chtěl podívat… http://tomik.jmx.cz/nette/menu.avi :) Pokud by o to byl zájem, zveřejním to, ale nebude to hned, chvilku mi to bude trvat, rád bych to dal do nějakého „obecnějšího znovu použitelného“ tvaru. Případně bych to mohl poslat Honzovi a on by si s tímto pohrál. ;)

Je tato komponenta již někde ke stažení? Vypadá to opravdu moc povedeně. Díky za odpověď

Tomik
Nette Evangelist | 485
+
0
-

Vyki napsal(a):

Je tato komponenta již někde ke stažení? Vypadá to opravdu moc povedeně. Díky za odpověď

Zatím není. Bohužel nemám čas na to ji učesat a poskytnout široké veřejnosti vč. podpory, návodu a podobně. Ale pokud jsi minimálně středně pokročilý uživatel Nette, můžu Ti poskytnout potřebné materiály, a ty už by sis s nima nějak poradil. :)

Vyki
Člen | 388
+
0
-

Tomik napsal(a):

Vyki napsal(a):

Je tato komponenta již někde ke stažení? Vypadá to opravdu moc povedeně. Díky za odpověď

Zatím není. Bohužel nemám čas na to ji učesat a poskytnout široké veřejnosti vč. podpory, návodu a podobně. Ale pokud jsi minimálně středně pokročilý uživatel Nette, můžu Ti poskytnout potřebné materiály, a ty už by sis s nima nějak poradil. :)

Myslím, že bych to zvládnout měl. Časově to nyní mám kvůli škole také napjaté, ale ve volných chvílích věřím, že zvládnu tuto knihovnu zobecnit, popsat a poskytnout pro testování.

Tomik
Nette Evangelist | 485
+
0
-

Vyki napsal(a):

Myslím, že bych to zvládnout měl. Časově to nyní mám kvůli škole také napjaté, ale ve volných chvílích věřím, že zvládnu tuto knihovnu zobecnit, popsat a poskytnout pro testování.

Já jsem spíš myslel pro tvoje osobní účely, ale pokud by se Ti to podařilo udělat rozumně, tak aby to bylo pochopitelné a použitelné, a zachoval bys informace o mém (spolu)autorství, nebránil bych se. :)

Když tak mi napiš mail (viz podpis pod tímto příspěvkem), odpovím Ti, popíšu Ti co a jak, a napíšu odkaz na stažení materiálů…

Oggy
Člen | 306
+
0
-

Vyki napsal(a):

jasir napsal(a):

Tomik napsal(a):

Říkal jsem o tom už Honzovi na Webexpu, mám menu komponentu i se správou (přetahováním jednotlivých položek), to video jsem dělal pro Honzu (aby se moh' inspirovat), ale kdo by se chtěl podívat… http://tomik.jmx.cz/nette/menu.avi :) Pokud by o to byl zájem, zveřejním to, ale nebude to hned, chvilku mi to bude trvat, rád bych to dal do nějakého „obecnějšího znovu použitelného“ tvaru. Případně bych to mohl poslat Honzovi a on by si s tímto pohrál. ;)

Je tato komponenta již někde ke stažení? Vypadá to opravdu moc povedeně. Díky za odpověď

Můžu se jen zeptat – ten strom webových sekcí, který tam přeřazuješ děláš jakým jquery pluginem?
Dělám něco podobného.. používám plugin sortable a jquery tree view na rozbalování atd.. ale mám problém s tím sortable.. nějak neokážu ty sekce řadit skrze jednotlivé levely..můžu přeřazovat jen sekce na nejvzšší úrovni..

Tomik
Nette Evangelist | 485
+
0
-

Oggy napsal(a):

Můžu se jen zeptat – ten strom webových sekcí, který tam přeřazuješ děláš jakým jquery pluginem?
Dělám něco podobného.. používám plugin sortable a jquery tree view na rozbalování atd.. ale mám problém s tím sortable.. nějak neokážu ty sekce řadit skrze jednotlivé levely..můžu přeřazovat jen sekce na nejvzšší úrovni..

No, je to plugin nad právě tím sortable, který má chybu, že nelze pracovat s těmi vnořenými členy.

http://code.google.com/…edsortables/

Oggy
Člen | 306
+
0
-

Tomik napsal(a):

Oggy napsal(a):

Můžu se jen zeptat – ten strom webových sekcí, který tam přeřazuješ děláš jakým jquery pluginem?
Dělám něco podobného.. používám plugin sortable a jquery tree view na rozbalování atd.. ale mám problém s tím sortable.. nějak neokážu ty sekce řadit skrze jednotlivé levely..můžu přeřazovat jen sekce na nejvzšší úrovni..

No, je to plugin nad právě tím sortable, který má chybu, že nelze pracovat s těmi vnořenými členy.

http://code.google.com/…edsortables/

děkuju

Panda
Člen | 569
+
0
-

Já osobně používám jsTree. Možná z toho někdy udělám komponentu pro Nette…

Tomik
Nette Evangelist | 485
+
0
-

Panda napsal(a):

Já osobně používám jsTree. Možná z toho někdy udělám komponentu pro Nette…

To vypadá taky pěkně.

Oggy
Člen | 306
+
0
-

Panda napsal(a):

Já osobně používám jsTree. Možná z toho někdy udělám komponentu pro Nette…

ooo..to vzpadá super.. protože se mi nějak zase nedařilo to skloubit dohormady s treeview, protože to nepotřebuji mít v seznamu ale v divech.. tohle tak letmým pohledem vypadá, že umí všechno a něco navíc a má dokumentaci:-) ..díky

Oggy
Člen | 306
+
0
-

tak jstree umí přesně to co jsem hledal díky..

ještě dotaz .. snažím se ještě rozchodit cookies..aby si tree zapamatoval stav..
ale mám trošku trable identifikátorem, aby to chodilo ..
je potřeba každý list, aby měl své id…takto:

<?php
<ul>
		<li id="li_1" rel="node-type">
			<a href="#"><ins>&nbsp;</ins>Root node</a>
			<ul>
				<li id="li_2" rel="node-type">
					<a href="#"><ins>&nbsp;</ins>Child node</a>
				</li>
			</ul>
		</li>
		<li id="li_3" rel="node-type">
			<a href="#"><ins>&nbsp;</ins>Root node</a>
		</li>
	</ul>

?>

..můj template .. tam je problém s tím, že do includované šablony se counter přenese.. ale nadřazené šablona již změněnou hodnotu nezná..

nebo jsem přehlédl nějakou funkčnost jstree, kde by toto řešil za mě :-)

<?php
    <div class="tree">
        {assign $sekce $control->getComponents()}
        {assign $counter 0}
        {block #menu}
        <ul>
            {foreach $sekce as $item}
            {? $counter += 1}
            <li id="li_{$counter}"><a href="#"><ins>&nbsp;</ins>{$item->nazevMenu}</a>
                    {if count($item->getComponents())}
                            {include #menu, 'sekce' => $item->getComponents(), 'counter' => $counter}
                    {/if}
            </li>
            {/foreach}
        </ul>
        {/block}
    </div>
?>

Editoval Oggy (10. 1. 2010 8:47)

Honza Kuchař
Člen | 1662
+
0
-

Nechcete to přidat do extras?

cuga
Člen | 210
+
0
-

Honza Marek napsal(a):

Budoucnost

  • Tohle je zatím taková pracovní verze, tak tu zatím nejdou měnit měnit šablony či označit třídou rodiče $currentu jako aktivní položky. Všechno bude.
  • Přemýšlím o generování sitemapy.
  • Uvítám další nápady.
  • Translator mi přijde zbytečný, protože většinou v menu budou články a tak a tam se tahají z databáze rovnou přeložené názvy.

jak si na tom s tou budoucnosti? :) hodne bych ocenil to oznacovani jako aktivni rodice prvku

Honza Marek
Člen | 1664
+
0
-

O budoucnosti nic nevim, nejsem věštec. Ale současnost mám na githubu.