How to define general route for modular application?

Notice: This thread is very old.
JuniorJR
Member | 181
+
0
-

Hi, I'm facing a problem related to building of modular application where I've one BackOfficeModule which should be a simple ‘container’ for all admin related tasks, but this module should be considerer rather as wrapper for other modules (e.g. page administration). My current structure is something like:

BackOfficeModule
   - Presenters
PageModule
   - BackOfficeModule // contains backend related presenters
      - Presenters
         - PagesPresenter
   - FrontOfficeModule // contains frontend related presenters
      - Presenters
         - PagePresenter

But I struggle with routing/presenter mapping. I've defined common route for BackOfficeModule as this route should basically handle all other admin modules (I do not want to create separate routes for each of possible admin module as it would be only copy).

// this will match only BackOfficeModule presenters, not those in PageModule\BackOfficeModule
$router = new Nette\Application\Routers\RouteList('BackOffice');
$router[] = new Nette\Application\Routers\Route('admin/<locale>[/<presenter>[/<action>[/<id>]]]');

// currently I see only this solution
$router = new Nette\Application\Routers\RouteList('BackOffice');
$router[] = new Nette\Application\Routers\Route('admin/<locale>[/<presenter>[/<action>[/<id>]]]');

$router = new Nette\Application\Routers\RouteList('Page:BackOffice');
$router[] = new Nette\Application\Routers\Route('admin/<locale>[/<presenter>[/<action>[/<id>]]]');

How to correctly define general route which will match all backoffice modules (including nested backoffice modules in other modules)?

edit: sorry for bad topic category

Last edited by JuniorJR (2015-07-08 15:31)

Badaboom
Member | 33
+
0
-

I stumbled upon very similar issue, however my reason was I needed presenters (and modules) in more than one namespace. I gave up on that, because I would basically need to write my own PresenterFactory.

Solution for you is rather simple – switch the modules so BackOfficeModule and FrontOfficeModule are root modules. It even makes more sense. If you think about it, \PageModule\BackOfficeModule isn't subset of \BackOfficeModule – those are totally different modules sharing a name. However \BackOfficeModule\PageModule would be subset, or descendant if you will, of \BackOfficeModule. In other words, you want to access BackOffice to manage Pages, not access Pages to manage BackOffice.

Unfortunately, Nette makes use of namespaces to distinguish between modules and leaves you with less flexibility for naming. Now, you're prioritizing naming before logic structure. I have to admit, the way you have it gives a slightly better hint of what functionality the module brings to an app. If you wanted to have both, you would need to write advanced mapping and then you could have even better naming like:

Pages\Modules\Administration\Presenters\DefaultPresenter
Pages\Modules\Frontend\Presenters\PagePresenter

You would then map these (we're not talking about namespaces anymore) to

Admin Module > Pages Module > Default Presenter
Front Module > Pages Module > Page Presenter

I don't think it's worth the effort, though.


A little advice – name your modules AdminModule and FrontModule. BackOfficeModule and FrontOfficeModule might be more fancy, but it's much longer. And you will be using them throughout your app and soon it will become annoying.

JuniorJR
Member | 181
+
0
-

@Badaboom Thank you very much for your opinion. I'll restructure the modules and put BackOfficeModule as root of other modules, I think I'll deal with it.

JuniorJR
Member | 181
+
0
-

@Badaboom Well, I've realized If I use the proposed solution, where should I put other services, model entities etc.? I mean what would be good logical location for these?

Admin Module > Pages Module > Default Presenter
Front Module > Pages Module > Page Presenter

? > Facades
? > Entities
...

Last edited by JuniorJR (2015-07-09 22:36)

Badaboom
Member | 33
+
0
-

You can have it in a proper namespace. Simply put, you can follow PSR-4 (or PSR-0), except for presenters & modules.

Sample directory structure with namespaces after hashtag:

Pages
	- Facades				# Pages\Facades
	- Entities				# Pages\Entities
		- Page				# Pages\Entities\Page
	- Modules				# (just a directory - you can ofc leave it out)
		- BackOfficeModule
			- PageModule	# BackOfficeModule\PageModule
		- FrontOfficeModule
			- PageModule	# FrontOfficeModule\PageModule

Last edited by Badaboom (2015-07-10 00:23)

JuniorJR
Member | 181
+
0
-

@Badaboom Unfortunately, I'd like to follow PSR, but the inconsistency you used in PageModule > Modules is something what I'd like to avoid :( These are really awkward problems…

Badaboom
Member | 33
+
0
-

As I said, with default PresenterFactory, it's really tricky. And this is a mapping issue, you could probably solve it through routing if you listed route for every module, but that would be just a workaround.

If you really don't want to break PSR, then you can sacrifice clarity of the directory structure:

Pages
    - Facades           # Pages\Facades
    - Entities          # Pages\Entities
        - Page          # Pages\Entities\Page
BackOfficeModule
	- PageModule		# BackOfficeModule\PageModule
FrontOfficeModule
	- PageModule		# FrontOfficeModule\PageModule

I edited previous post, so it's a bit clearer