Separating modules and routes into separate files

2 years ago

Breki
Member | 6
+
+1
-

Hi all!

Fairly new to Nette, but absolutely loving it so far. I'm building a site from scratch and have had some success so far, but when it came time to start working with modules, it became a little more difficult.

I've placed the presenters and templates for most of the site in /app/Modules/SiteModule with their own namespace, /App/SiteModule, and I'm able to get the routing to work fine with that in mind. No problem there.

The problem appears when I add /app/Modules/AdminModule (with namespace /App/AdminModule) and want to start setting up the routing to handle both of these modules. Ideally, I would like to be able to simply say that if the first part of the url is /admin/<whatever>, then use AdminModule, but everything else should use SiteModule.

Here's what I've tried so far:

I rebuilt my RouteFactory.php to be:

use Nette\Application\Routers\RouteList,
    Nette\Application\Routers\Route;

class RouteFactory
{
  /** @var array */
  private $routerFactories = array();

  public function addRouteFactory(IRouteFactory $routeFactory)
  {
    $this->routeFactories[] = $routeFactory;
  }

  public function createRouter()
  {
    $router = new RouteList();
    foreach ($this->routeFactories as $routeFactory) {
      $router[] = $routeFactory->createRouter();
    }

    return $router;
  }
}

I also added an iRouteFactory.php that looks like this:

interface IRouteFactory
{
  public function createRouter();
}

Inside my config.local.neon, I have this:

services:
    routeFactory.Site: App\SiteModule\RouteFactory
    routeFactory.Admin: App\AdminModule\RouteFactory
    route:
        class: RouteFactory
        setup:
            - addRouteFactory(@routeFactory.Site)
            - addRouteFactory(@routeFactory.Admin)

And finally, I have two files called AdminModuleRoutes.php and SiteModuleRoutes.php that contain:

namespace App\SiteModule;

class RouteFactory implements \IRouteFactory
{
  public function createRouter()
  {
    $router   = new RouteList('Site');
    $router[] = new Route('/about', 'Homepage:About');
    $router[] = new Route('<presenter>/<section>[/<id>]', 'Homepage:default');

   return $router;
  }
}

… and the equivalent for App\AdminModule, of course, both in the namespace and in the routelist name.

Now, my question is, why am I still not getting any routes loaded? It _seems_ to parse my PHP correctly and it _seems_ to do everything I ask it to, but it's like those final three lines in my config.local.neon just aren't being read or executed. Any ideas?

2 years ago

David Matějka
Moderator | 5702
+
0
-

Hi,
so you do not see that routes in tracy routing panel?

The code seems ok to me (maybe just switch order of setup methods so Admin router is first). Have you tried to put code from AdminModuleRoutes and SiteModuleRoutes directly into main RouteFactory?

2 years ago

Breki
Member | 6
+
0
-

Yeah, I can't find the problem either. The routing panel just shows up as empty and “No routes defined”.

And no, I haven't tried that, actually, but I don't think that would work either. The RouteFactory class is loaded outside of a namespace while the AdminModule and SiteModule route files use their own namespaces, App/AdminModule and App/SiteModule.

… Maybe that's the problem, that they're ending up under different namespaces, and the router doesn't want to parse them?

Edit: Come to think of it, the route definition files have to be in separate namespaces, because both have their own “class RouteFactory” in them, and have to be separated.

Last edited by Breki (2017-04-06 19:27)

2 years ago

CZechBoY
Member | 3212
+
0
-

Try to add this to config

services:
    router: @route::createRouter

2 years ago

Breki
Member | 6
+
0
-

Service ‘application.application’: Service of type Nette\Application\IRouter needed by Nette\Application\Application::__construct() not found. Did you register it in configuration file?

2 years ago

Felix
Nette Core | 882
+
+1
-

@Breki Any updates here? Have you already figured it out?

2 years ago

Breki
Member | 6
+
+1
-

Sorry for the late answer! Yes, I did! I'm not sure exactly which part it was that fixed it, but the two major changes that I made was to add:

use Nette\Application\Routers\RouteList,
    Nette\Application\Routers\Route;

to both of my xxxModuleRoutes.php files, and then change this:

route:
    class: RouteFactory
    setup:
        - addRouteFactory(@routeFactory.Site)
        - addRouteFactory(@routeFactory.Admin)

in config.neon to this:

route:
    class: \RouteFactory
        setup:
            - addRouteFactory(@routeFactory.Admin)
            - addRouteFactory(@routeFactory.Site)
        router: @route::createRouter()

Last edited by Breki (2017-04-25 14:41)