Podobné URL adresy, rôzne presentery
- jardo
- Člen | 17
Zdravíčko
V Nette (+DiBi) mám za sebou jeden projekt, ktorý sa podarilo dotiahnúť do konca, čiže základné porozumenie už určite mám. Momentálne však riešim otázku s ďaľším projektom u ktorého budem vypomáhať. Snažím sa presadiť použitie Nette, ale nedokážem vyriešiť problém s URL adresami.
Malo by sa jednať o jednoduchší e-shop, kde sa ale požadujú URL adresy, ktoré na prvý pohľad je ťažké odlíšiť o ktorý presenter sa jedná. Majme príklad:
Pre statický obsah (dajme tomu, že presenter bude Content) a url:
/jak-nakupovat
/proc-nakupovat-u-nas
Pre vypis kategorii (dajme tomu, že presenter bude Category) a url:
/kategorie
/podkategorie (tato kategória bude mať ako parent kategóriu „kategorie“)
Detail výpisu produktu (dajme tomu, že presenter bude Product) a url:
/prvni-produkt
/jiny-prod-ukt
V tomto prípade asi nebude ľahké použiť pravidlá pre route. Je nejaké elegantné riešenie, ktoré by sa dalo použiť ? Prípadne ako v Nette určiť, ktorý presenter sa použitie napríklad na základe predchodzieho spracovania URL. Napadne niekoho niečo ?
Ďakujem
- Jerry123456789
- Člen | 37
Co třeba si napsat vlasní router, který by podle url šáhnul do
db/souboru/pole/…, podle toho by určil presenter a vytvořil request.
Anebo přesvědčit ostatní členy v použítý nějakých prefixů nebo
id:
/page/jak-nakupovat
/cat/kategorie/podkategorie/…
/product/auticko-cervene
eventuelně /13543-auticko-cervene
//EDIT: budu muset zrychlit tempo psaní :D a nebo začít používat RSS
Editoval Jerry123456789 (18. 7. 2009 15:56)
- Ondřej Mirtes
- Člen | 1536
Řešením je vlastní router, ale jelikož se stále bojím se do něčeho takového pustit, napsal jsem si takovéto řešení (prosím zdejší osazenstvo o nebetyčnou kritiku a pověšení za koule do průvanu :o)):
Zkrátka do těch jednotlivých rout ten obsah, na který se mají matchovat, dosazuji dynamicky :)
$routingModel = new RoutingModel(); //cachován
$router[] = new Route('<seo ' . implode('|', $routingModel->getMiscs()) . '>/', array(
'presenter' => 'Misc',
'action' => 'default',
));
$router[] = new Route('<categorySeo ' . implode('|', $articleCategories = $routingModel->getArticleCategories()) . '>/', array(
'presenter' => 'Article',
'action' => 'default',
));
$router[] = new Route('<categorySeo ' . implode('|', $articleCategories) . '>/<seo>/', array(
'presenter' => 'Article',
'action' => 'show',
));
Editoval LastHunter (18. 7. 2009 16:37)
- Honza Marek
- Člen | 1664
Já bych určitě doporučil napsat si vlastní router. Není to nic složitého, zvlášť když ho máte odkud opsat. Vyšel bych třeba ze SimpleSeoRouteru od Honzy Tvrdíka.
- jakubkulhan
- Člen | 55
Přihřeji si vlastní polívčičku: Další možností, pokud nechceš vlastní router je způsob, jakým to řeší Shopaholic – a to tím způsobem, že všechny takovéto adresy směřuje na jediný presenter a podle toho, co najde v databázi, vybere view, viz https://github.com/…ootstrap.php#L79 a https://github.com/…resenter.php#L6.
- Jan Tvrdík
- Nette guru | 2595
Ten úvodní problém lze řešit pomocí 3 SimpleSeoRouterů, ale z hlediska výkonu (SSR nemá cache) asi nakonec skončíte na routeru vlastním.
Nebojte se psát si vlastní routry, není na tom nic těžkého. Jakmile si napíšete jeden router, tak ty ostatní už budou hračkou (pokud teda nebudete chtít napsat něco tak brutálně obecného jako je třída Route).
PS: Učitě by ale neškodilo, kdyby byla v dokumentaci stránka na téma „Tvorba vlastního routeru“.
Editoval Jan Tvrdík (18. 7. 2009 18:11)
- Ondřej Mirtes
- Člen | 1536
jakubkulhan napsal(a):
Přihřeji si vlastní polívčičku: Další možností, pokud nechceš vlastní router je způsob, jakým to řeší Shopaholic – a to tím způsobem, že všechny takovéto adresy směřuje na jediný presenter a podle toho, co najde v databázi, vybere view, viz https://github.com/…ootstrap.php#L79 a https://github.com/…resenter.php#L6.
Mno, to jen posouvá ten mechanismus routování o level níže.
BTW: Wow, e-shop v Nette :) Nette potřebuje více takovýchto projektů, CMS apod. :)
- David Grudl
- Nette Core | 8228
jakubkulhan napsal(a):
Přihřeji si vlastní polívčičku: Další možností, pokud nechceš vlastní router je způsob, jakým to řeší Shopaholic – a to tím způsobem, že všechny takovéto adresy směřuje na jediný presenter a podle toho, co najde v databázi, vybere view, viz https://github.com/…ootstrap.php#L79 a https://github.com/…resenter.php#L6.
BTW zajímavý projekt! Je podnětné vidět velmi tvůrčí přístup ke
kódu (třeba ten bootstrap.php
). Měl bych pár tipů, co by bylo
lepší udělat trošku jinak, aby to bylo „více Nette“, jen nevím, jestli
to mám psát, aby to nevyznělo jako kritika.
- jakubkulhan
- Člen | 55
David Grudl napsal(a):
BTW zajímavý projekt! Je podnětné vidět velmi tvůrčí přístup ke kódu (třeba ten
bootstrap.php
). Měl bych pár tipů, co by bylo lepší udělat trošku jinak, aby to bylo „více Nette“, jen nevím, jestli to mám psát, aby to nevyznělo jako kritika.
Tohle byla moje první aplikace v Nette, takže mi je jasné, že všechno nebude zrovna tak, jak by se pro Nette slušelo. Cokoli beru jako radu, ne jako kritiku, takže klidně sem s tím.
- jardo
- Člen | 17
David Grudl napsal(a):
Zkus se podívat sem https://forum.nette.org/…ovnove-routy?…
Toto mi pomohlo. Načerpal som aj inšpiráciu ešte z jedného postu nižšie a nejak to prispôsobil potrebám.
Ďakujem všetkým.
- David Grudl
- Nette Core | 8228
Konečně se dostává k tomu něco napsat ke kódu.
Nejsou tam chyby, ale řada věcí, které by se daly zjednodušit a výrazně tím zkrátit a zpřehlednit kód presenterů:
- po
$presenter->redirect()
nemusí následovat$presenter->terminate()
anireturn
- události formuláře onSubmit a onClick se volají jen když je odeslání
validní, tudíž není potřeba psát v obslužných
funkcích
if (!$form->isValid()) return
- tuším že
if ($image->getWidth() > $image->getHeight()) {
$image->resize(NULL, 60);
} else {
$image->resize(60, NULL);
}
lze nahradit za $image->resize(60, 60);
- formulářům a šabloně lze nastavit translator, takže není potřeba
všude psát
__(...)
ale nechat texty překládat automaticky - do frontendu bych dal všechny formuláře jako AppForm komponenty a odstranil tak práci přímo s $_POST v OrderPresenter.php
Pak jsou tu nějaké nové features v Nette 0.9, které umožní:
- rozsekat dlouhé metody
createComponent($name)
na malé např.createComponentDataForm()
atd. - ke komponentám se pak dá přistupovat přes
$presenter['dataForm']
nebo rovnou v šabloně přes{control dataForm}
- není nutné registrovat filtr
$this->template->registerFilter('Nette\Templates\CurlyBracketsFilter::invoke');
- vcelku složitá logika v @layout.phtml se dá nahradit
použitím
{block#...}
ve výsledku tedy mohou zcela zmizet metody jako
public function renderAddPage()
{
$this->template->title = __('Add page');
$this->template->form = $this->getComponent('pageAddForm');
}
protože řetězec Add page
by mohl být rovnou v šabloně
(tam se dá použít translator) a šablona si může na komponentu šáhnout
sama přes {control pageAddForm}
.