Podobné URL adresy, rôzne presentery

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

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

David Grudl
Nette Core | 8110
+
0
-
Jerry123456789
Člen | 37
+
0
-

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
+
0
-

Ř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
+
0
-

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
+
0
-

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
+
0
-

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)

grogy
Člen | 147
+
0
-

PS: Učitě by ale neškodilo, kdyby byla v dokumentaci stránka na téma „Tvorba vlastního routeru“.

To bych ocenil i já. Zkoušel jsem si napsat router na modul a bohužel bez úspěchu. Stačilo by menší nakopnutí, ale to je trošku off tohoto vlákna.

Ondřej Mirtes
Člen | 1536
+
0
-

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 | 8110
+
0
-

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
+
0
-

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.

David Grudl
Nette Core | 8110
+
0
-

Ok, tak něco sepíšu.

jardo
Člen | 17
+
0
-

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 | 8110
+
0
-

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() ani return
  • 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}.