Routování pro zanořené moduly
- Ivorius
- Nette Blogger | 119
Mám cca. takovou strukturu:
App
NavigationModule
AdminModule
Presenters
Templates
FrontModule
Presenters
DI
XYZModule
...
V extension jsem si zaregistroval mapping
$builder->getDefinition($builder->getByType(IPresenterFactory::class))->addSetup(
'setMapping',
[['Navigation' => 'Navigation\*Module\Presenters\*Presenter']]
);
a nastavil routy takto
$router = new RouteList('Navigation');
$router[] = new Route('/navigation/<module>/<presenter>[/<action>][/<id>]', array(
'presenter' => 'Homepage',
'action' => 'default',
));
return $router;
Presenter má namespace Navigation\AdminModule\Presenters;
Když si nechám teď v latte vygenerovat odkaz
:Navigation:Admin:Homepage:default
tak se dostanu na
/navigation/admin/
což je správně. Je však nějak možné za
pomocí rout tu url změnit na /admin/navigation/
?
- Ivorius
- Nette Blogger | 119
Ten modul se rozpozná správně, ale já chci dosáhnout url: admin/navigation/presenter/
Na základě tvého příspěvku, mě to přivedlo na tuto myšlenku
$router = new RouteList('Navigation');
$router[] = new Route('/admin/navigation/<presenter>[/<action>][/<id>]', array(
'lang' => \Unio\RouterFactory::getLangFilter(),
'presenter' => 'Homepage',
'action' => 'default',
'module' => 'Admin'
Není, to sice příliš modulární (co když bude další modul zanořen, např. Eshop:Product), ale účel to zatím splňuje. Možná má někdo lepší nápad?
Jaký význam má ten RouteList(), kromě toho že si ty routy takto označím? Do samotných route to nijak nezasahuje? Nebo snad lze nějak udělat toto?
$router = new RouteList('Navigation');
$router[] = new Route('/admin/<routelist>/<presenter>[/<action>][/<id>]', array(
'presenter' => 'Homepage',
'action' => 'default',
'module' => 'Admin',
));
- Machy8
- Člen | 59
K tomu modulárnímu řešení.
Zkus se podívat, jak to má řešené například ZenifyLegacy/ModularRouting. Ve výsledku jen implementuješ interface a je jedno, kde a jak zanořený tvůj routerFactory je. V ModularRoutingExtension si to podle implementovanýho interfacu tvoje továrničky najde, sesbírá a máš „hotovo“.
- Jan Mikeš
- Člen | 771
Ahoj, routelisty do sebe jdou libovolně zanořovat, můžeš tedy využít něco takového:
$router = new RouteList();
$adminRouter = new RouteList("Admin");
$adminRouter[] = new Route('navigation/admin//<presenter>[/<action>][/<id>]', [
'presenter' => 'Homepage',
'action' => 'default',
]);
$navRouter = new RouteList("Navigation");
$navRouter[] = $adminRouter;
$router[] = $navRouter;
return $router;
Editoval Jan Mikeš (30. 10. 2016 10:19)
- Ivorius
- Nette Blogger | 119
@Machy8 já mohu každé extension nechat zpracovat svůj
routerFactory a tím tedy vytvářet nové routy specifické pro daný modul.
Rád bych ale měl nějakou obecnou routu, co by v případě url
admin/m/eshop/<presenter>
věděla, že se zpracovává
presenter s namespace Eshop\AdminModule
nebo url
admin/m/eshop/products/<presenter>
že namespace presenteru
je Eshop\Products\AdminModule
To /m/ v url tam asi bude nutné, aby nekolidovalo s presentery přímo v AdminModule.
Takhle mi to dává smysl, namespace budou podle adresářové struktury ale přitom url budou začínat admin/ což je v administraci zvykem.
- Ivorius
- Nette Blogger | 119
Zkusil jsem
class RouterFactory
{
/**
* @return \Nette\Application\IRouter
*/
public function createRouter()
{
$router = new RouteList('Admin');
$router[] = new Route('admin/m/<module>/<presenter>[/<action>][/<id>]', array(
'module' => array(
Route::FILTER_IN => array($this, 'filterInModule'),
Route::FILTER_OUT => array($this, 'filterOutModule'),
),
'lang' => \Unio\RouterFactory::getLangFilter(),
'presenter' => 'Homepage',
'action' => 'default',
));
return $router;
}
public function filterInModule($module)
{
return ucfirst($module) . ':Admin';
}
public function filterOutModule($module)
{
list($module) = explode(':', $module);
return strtolower($module);
}
}
Problém ale je, že $module sice neobsahuje Admin, ale je tam přidán jako první asi nějak přes ten RouteList