Aplikace vybírá delší routu než by měla

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

Ahoj,
mám nejnovější Nette 2 a PHP 5.3. V bootstrapu mám tyto problémové routy:

$router = $application->getRouter();

$router[] = new Route('admin/<presenter>/<action>/<id>', array(
	'presenter' => 'Admin',
	'action' => 'default',
	'id' => NULL,
));

$router[] = new Route('<id>', array(
	'presenter' => 'Browser',
	'action' => 'show',
	'id' => NULL,
));

Mělo by se to chovat jako klasický blog, tj. example.com/admin/articles/new povede na Presenter = Articles, action = new. To funguje jak má. Články se pak mají zobrazovat na example.com/clanek — a tohle mi vůbec nefunguje. Pokud si tu adresu zobrazím, přesměruje mě to: example.com/clanek → example.com/admin/browser/show/clanek, ale presenter, action a id to nastaví správně. Co prosím dělám špatně? Já dost dobře nechápu, jak se může aplikovat první routa, když nemám v adrese žádné „admin“.

_Martin_
Generous Backer | 679
+
0
-

Děje se tak proto, že Nette vždy přesměrovává na kanonickou verzi adresy – to z důvodu, aby web nebyl postihován za zdvojený obsah. V tvém případě to vypadá následovně:

  1. Požadavek na example.com/clanek se správně přeloží na P: Browser, A: Show, ID: clanek
  2. Nette se pokusí vygenerovat adresu pro zadání P: Browser, A: Show, ID: clanek
  3. Tomu odpovídá 1. routa, vznikne tedy example.com/admin/browser/show/clanek

Řešení mě napadají dvě:

  1. explicitně v routě vyjmenovat, které presentery patří do administrace
  2. použít dva moduly: jeden pro administraci a druhý pro frontend

Osobně bych se klonil k druhému řešení.

Phoenix
Člen | 13
+
0
-

Díky, trochu jsem se posunul, ale narazil jsem na další problémy… Upravil jsem routy takto:

$router = $application->getRouter();

$router[] = new Route('admin/<presenter>/<action>/<id>', array(
        'Module' => 'Back',
	'presenter' => 'Back:Admin',
	'action' => 'default',
	'id' => NULL,
));

$router[] = new Route('<id>', array(
        'Module' => 'Front',
	'presenter' => 'Front:Browser',
	'action' => 'show',
	'id' => NULL,
));

Už mi funguje adresa example.com/article. Ale nevím jak na ni odkázat a v adminu mi to taky generuje podivné odkazy. Když jsem v adminu, přidává mi to do URL „back.“: example.com/admin/back.site/all-sites/. A když se na této stránce odkážu pomocí

{link :Front:Browser:show, 'id' => 'article'}

odkáže mě to na example.com/admin/front.browser/show/article místo na example.com/article.

_Martin_
Generous Backer | 679
+
0
-

Odmaž z definice rout 'Module' => 'Back'. Tím, že máš jméno modulu současně u presenteru, tak vlastně říkáš, že je modul Front, v něm další Front a v něm presentery (to samé v adminu).

Phoenix
Člen | 13
+
0
-

Zkoušel jsem všechny možné kombinace (odstranit ‚Module‘ a nechat Back:Admin a naopak) a pokaždé něco nefungovalo… Nevím co dělám špatně, každopádně už nemám nervy na to to řešit, v routě jsem explicitně vyjmenoval ty čtyři presentery, které tam používám a funguje to jak má. Díky.

_Martin_
Generous Backer | 679
+
0
-

Moje chyba, špatně jsem ti poradil. 'module' => 'Back' mělo zůstat a zmizet měl modul z definice presenteru. Správně má být:

$router[] = new NRoute('admin/<presenter>/<action>/<id>', array(
        'module' => 'Back',
        'presenter' => 'Admin',
        'action' => 'default',
        'id' => NULL,
));

$router[] = new NRoute('<id>', array(
        'module' => 'Front',
        'presenter' => 'Browser',
        'action' => 'show',
        'id' => NULL,
));

Otestováno=)

P.S. Některé prohlížeče si pamatují přesměrování, takže je třeba je vypnout a zapnout (nebo promazat keš), aby si „všimnuly“ nových rout.

P.S.2 Nette je často case-sensitive ('Module' => 'Front' se nerovná 'module' => 'Front').

Phoenix
Člen | 13
+
0
-

OK, díky, až budu mít někdy čas, zkusím si s tím pohrát, zatím mi to funguje, tak už se v tom hrabat nebudu… :-)