Version: dev-master
Bug Description
When only modules are used in an app, links cannot be created when only one RouteList is used. Exception saying "Invalid link: No route for Bar:Foo:waldo()" is thrown.
Steps To Reproduce
- Download nette/sandbox
composer install
- Move Homepage presenter into a Home module:
-namespace App\Presenters;
+namespace App\HomeModule\Presenters;
- Create another module with another presenter (and put it into
FooPresenter.php for example):
namespace App\BarModule\Presenters;
final class FooPresenter extends \App\Presenters\BasePresenter
{
public function renderWaldo(): void
...
- Update RouterFactory to read
$router->addRoute('foobar/<action>', [
'presenter' => 'Foo',
'action' => 'default',
'module' => 'Bar',
]);
$router->addRoute('<presenter>/<action>', [
'presenter' => 'Homepage',
'action' => 'default',
'module' => 'Home',
]);
Note the 'module' key.
- Update
Homepage/default.latte to include
<a n:href=":Bar:Foo:waldo">bar module</a>
- Enable debug mode, edit
Bootstrap.php, e.g.:
- //$configurator->setDebugMode('23.75.345.200'); // enable for your remote IP
+ $configurator->setDebugMode(true); // enable for your remote IP
-
Start PHP (see the help in nette/sandbox), and load the page
-
You should see
User Warning
Invalid link: No route for Bar:Foo:waldo()
- Change the router (
RouterFactory.php) code:
- $router->addRoute('foobar/<action>', [
- 'presenter' => 'Foo',
- 'action' => 'default',
- 'module' => 'Bar',
- ]);
- $router->addRoute('<presenter>/<action>', [
- 'presenter' => 'Homepage',
- 'action' => 'default',
- 'module' => 'Home',
- ]);
+ $routerBar = new RouteList('Bar');
+ $routerBar->addRoute('foobar/<action>', [
+ 'presenter' => 'Foo',
+ 'action' => 'default',
+ ]);
+ $router->add($routerBar);
+
+ $routerHome = new RouteList('Home');
+ $routerHome->addRoute('<presenter>/<action>', [
+ 'presenter' => 'Homepage',
+ 'action' => 'default',
+ ]);
+ $router->add($routerHome);
Note that module name was moved from the module key to the RouteList constructor and that now, instead of adding a Route, we add a RouteList.
- Load the page in your browser again, no error
Expected Behavior
It works :-) Or the exception is more clear or docs are clear.
Possible Solution
There are several options, not sure which one is the correct one, feedback wanted:
- update docs and say when only modules are used then each module needs to use its own
RouteList with the module name specified in the constructor
- somehow try to make it work as it used to before nette/routing was created
Spent quite some time debugging the problem and this is what helped to fix (and understand) the problem for me:
#208 describes that nette/routing classes have no idea about //modules// and that Application\Routers\RouteList solves that. But this is in constructUrl:
public function constructUrl(array $params, Nette\Http\UrlScript $refUrl): ?string
{
if ($this->module) {
if (strncmp($params[self::PRESENTER_KEY], $this->module, strlen($this->module)) === 0) {
$params[self::PRESENTER_KEY] = substr($params[self::PRESENTER_KEY], strlen($this->module));
} else {
return null;
}
}
return parent::constructUrl($params, $refUrl);
}
so if there's no $this->module then it just calls parent::constructUrl which doesn't know anything about modules.
The docs says:
In Nette we can split presenters into modules. Therefore we need to work with those modules in routes. We can use module parameter in Route class:
+
If we have more routes that we want to group together in a module, we can use RouteList with name of module in constructor:
So I tried using the constructor param and it worked.
Honestly I'd be totally fine with just updating the docs (and maybe add a BC warning to nette/application release notes?), let me know I can fix it (just not sure how).
Thanks and sorry for this long bug report, tried to write down all I've learned in the past 2 days or so.
Version: dev-master
Bug Description
When only modules are used in an app, links cannot be created when only one
RouteListis used. Exception saying "Invalid link: No route for Bar:Foo:waldo()" is thrown.Steps To Reproduce
composer installFooPresenter.phpfor example):Note the
'module'key.Homepage/default.latteto includeBootstrap.php, e.g.:Start PHP (see the help in nette/sandbox), and load the page
You should see
RouterFactory.php) code:Note that module name was moved from the
modulekey to theRouteListconstructor and that now, instead of adding aRoute, we add aRouteList.Expected Behavior
It works :-) Or the exception is more clear or docs are clear.
Possible Solution
There are several options, not sure which one is the correct one, feedback wanted:
RouteListwith the module name specified in the constructorSpent quite some time debugging the problem and this is what helped to fix (and understand) the problem for me:
#208 describes that nette/routing classes have no idea about //modules// and that
Application\Routers\RouteListsolves that. But this is inconstructUrl:so if there's no
$this->modulethen it just callsparent::constructUrlwhich doesn't know anything about modules.The docs says:
So I tried using the constructor param and it worked.
Honestly I'd be totally fine with just updating the docs (and maybe add a BC warning to nette/application release notes?), let me know I can fix it (just not sure how).
Thanks and sorry for this long bug report, tried to write down all I've learned in the past 2 days or so.