How to define general route for modular application?
- JuniorJR
- Member | 181
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
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
@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
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)
- Badaboom
- Member | 33
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