Routování pro zanořené moduly

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

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/ ?

Eda
Backer | 220
+
0
-

Zkus doplnit výchozí hodnotu i pro module:

$router = new RouteList('Navigation');
$router[] =  new Route('/navigation/<module>/<presenter>[/<action>][/<id>]', array(
    'presenter' => 'Homepage',
    'action' => 'default',
	'module' => 'Admin',
));
return $router;
Ivorius
Nette Blogger | 119
+
0
-

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

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

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

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

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