Nody (Dynamické routy)

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

Už nějáký čas přemýšlím nad tím jak „správně“ vyřešit nody (dynamické routy). Mám v hlavě pár nápadu jak by to šlo ale nepříjdou mě správné. Nicméně je tady popíšu.

  1. Je dynamické načtení (z DB/cache) a předat je routeru. Ale nepříjde mě správné mít pak v aplikaci třeba 500 rout. (Asi by jí to zpomalilo)
  2. Napsat router který by si sám šahal do DB (cache) a podle toho načetl moduly/presenter. Taky se mě to moc nepozdává.

Pokud nevíte o co mě de a proč to potřebuju řešit tak se to teď pokusím popsat. Jde o to že zákazník/uživatel aplikace by chtěl na web vložit článek a pak další galerii. Článek by chtěl mít s URL example.com/nejaky-muj-clanek a example.com/nejaka-moje-galerie . Jenomže já jako tvůjce aplikace dopředu nevím jak on to bude chtít. A taky mám od zákazníka/uživatele odezvu že nechce mít URL ve tvaru example.com/clanek/nejaky-muj-clanek resp. example.com/galerie/nejaka-moje-galerie . A tak řeším tuto otázku.

Jak to řešíte? Nebo jak by jste to řešily?

Mas3r
Člen | 116
+
0
-

Já jsem to vyřešil přes návrh 2. Stačí si napsat vlastní router.

Všechny routy uložíš do Cache. Trošku problémů je s vytvářením nodů ve stromových strukturách, ale třeba to nebudeš potřebovat.

Stačí upravit pak matchUrl a constructUrl.

V DB to ukládám:

notebooky/podle-hmotnosti/do-3kg ⇒ Eshop:Catalog:View:45

Patrik Votoček
Člen | 2221
+
0
-

Mas3r napsal(a):

… Trošku problémů je s vytvářením nodů ve stromových strukturách, ale třeba to nebudeš potřebovat…

Jakej problém myslíš?

Když už řeším nody tak počítám i se stromovou strukturou.

Mas3r
Člen | 116
+
0
-

No si představ, že máš teda notebooky/podle-hmotnosti/do-3kg a změníš notebooky na „netbooky“, pak musíš všechny položky na této URL závisející také změnit.

Také ři každé změně čehokoliv musíš měnit tabulku s těmi aliasy(nody), což sice není problém, ale otrava.

Jod
Člen | 701
+
0
-

Tam stačí pregenerovať linky pre router nie?

Patrik Votoček
Člen | 2221
+
0
-

Taky si myslím stačí pouze spustit dávku na přejmenování všech Nodu které obsahují to co chceš změnit nebo pokud to máš řešené tak že máš uloženou strukturu takto:

notebooky - kategorie
podle-hmotnosti - filtr
do-3kg - parametr filtru

tak nikde není psáno že musíš mít jednotlivé další parametry uloženyjako

notebooky/podle-hmotnosti/do-1kg
notebooky/podle-hmotnosti/do-2kg
notebooky/podle-hmotnosti/do-3kg
notebooky/podle-hmotnosti/do-4kg
notebooky/podle-hmotnosti/do-5kg

ale můžeš je mít uloženy jako

notebooky - #1
podle-hmotnostri - #2 - parrent #1
do-1kg - #3 - parrent #2
...
do-5kg - #n - parrent #2

a pak když změníš notebooky za netbooky tak se to automaticky promítne až do do-3kg…
# je bráno jako identifikátor (id)

kravčo
Člen | 721
+
0
-

Ja by som s routovaním nevymýšľal, spravil by som jednu routu

Node:view?path=notebooky/do-20kg/armadne

Cieľový prezenter môže cestu sparsovať a prípadne forwardovať na iné prezentery/akcie…

Priložím ešte Davidov príklad vlastného routra (ak by ste chceli ísť tou cestou)

Honza Marek
Člen | 1664
+
0
-

Já jsem si vyrobil něco takového:

<?php
// pseudokód
class ArticleRouter {
	private $data;

	function __construct() {
		$arr = dibi::query("select id, url, parent from articles")->fetchAssoc("parent,#");
		$this->addArticlesWithParent(NULL, "", $arr);
	}

	function addArticlesWithParent($parentId, $startUrl, $articles) {
		// rekurzivně nacpat do pole $data
		foreach ($articles[$parentId] as $item) {
			$this->data[$item->id] = $startUrl . "/" . $item->url;
			$this->addArticlesWithParent($item->id, $startUrl . "/" . $item->url, $articles);
		}
	}

	function match(IHttpRequest $context) {
		// jestli je v poli $data, tak přidat do parametrů presenteru id
	}

	function constructUrl(PresenterRequest $request, IHttpRequest $context) {
		// if isset($data[$params["id"]) return $data[$params["id"]];
	}
}
?>

Nechce se mi to víc rozepisovat, snad je princip jasný. Myslím, že pro menší a střední weby je to dobré. Pro větší nevím, jestli je dobré přednačíst adresu tisíce článků.

David Grudl
Nette Core | 8218
+
0
-

vrtak-cz napsal(a):

  1. Je dynamické načtení (z DB/cache) a předat je routeru. Ale nepříjde mě správné mít pak v aplikaci třeba 500 rout. (Asi by jí to zpomalilo)

Spíš bych řekl zabilo ;)

Patrik Votoček
Člen | 2221
+
0
-

Tak mě to nedalo a vydal jsem se to testovat…

Testovací aplikace

  • 10000 Nodu/Rout (+1 univerzální na všechno, co neprojde)
  • 1 Presenter:action – pouze načetl z DB (vždy sahal do DB) testovací text a vyrendroval ho společně s ID Nody/Routy. Text se tahal vždy stejný, tzn. z tabulky data na s id 1.
  • Testování času běhu celé app od načtení Nette\loader po rendering (stopky se stoply až při samotném renderování) – All
  • Testování času běhu od zavolání $application->run() po spuštění akce v presenteru ({Presenter}Presenter::action{Action}) – Router

Co se testovalo

  1. možnost uvedená výše pod číslem 1
    1. pouze z DB
    2. cache
  2. možnost uvedená výše pod číslem 2
    1. pouze z DB
    2. cache
X 1a 1b 2a 2b
All 1.2992276748 1.25103594859 0.03462378184 0.0349680980047
Router 0.471882522106 0.468844731648 0.00418408711751 0.00432453552882

Časy jsou průměrné, po otestování 100 různých url (prvních 10 záznamů + posledních 10 záznamů + prostředních 10 záznamů + 70 náhodných) – vždy se jednalo o stejný seznam (tzn. 1a byla testována na stejné url, jako ostatní – 1b, 2a, 2b). Jsou uvedeny v sekundách.

Z uvedené tabulky vyplývá, že možnost 2a je 37.5x rychlejší, pokud se týká celé aplikace a 112x rychlejší, pokud se týká routeru, než možnost 1a. U možnosti 2b vs. 1b je to 35x aplikace a 108x router. Jak je taky patrné s cache a bez ní, jsou rozdíly zanedbatelné. Nicméně tento test nebyl prováděn na produkčním prostředí za ostrého provozu, takže mohou být některé výsledky zkreslené. Se zapnutou cache by měly být aplikace rychlejší, než bez ní.

David Grudl
Nette Core | 8218
+
0
-

Ještě by to chtělo, aby se při renderování zobrazilo tak 50 různých odkazů na jiné nody.

Patrik Votoček
Člen | 2221
+
0
-

Až se budu po fotbale nudit tak na to kouknu… ale myslím že se to moc lišit nebude… :-)