One of the new features to hit the Zend Framework since 0.7 is Zend_Controller_ModuleRouter and its sibling Zend_Controller_ModuleRewriteRouter. This allows for separating out sets of controlers, models and views into their own modules. The directory structure then looks like:
application/
controllers/
IndexController.php
ArticleController.php
blog/
controllers/
IndexController.php
models/
views/
news/
controllers/
IndexController.php
ListController.php
models/
views/
models/
views/
lib/
Zend/
webroot/
css/
img/
js/
index.php
To set this up, you use this code in index.php:
$frontController->setControllerDirectory(array( 'default' => array('../application/controllers'), 'blog' => '../application/blog/controllers', 'news' => '../application/news/controllers' )); $frontController->setRouter(new Zend_Controller_ModuleRouter()) ->setDispatcher(new Zend_Controller_ModuleDispatcher())
The module router then maps the first parameter of the URL to the module and so then looks for a controller within that module's controllers directory. Hence http://www.example.com/news/list/recent will map to the News_ListController::recentAction() in the ../application/news/controllers directory. If the first parameter is not a named module, then the default module is used and the first parameter is considered to be the controller instead. In this case http://www.example.com/article/list will map to ArticleController::listAction() in the ../application/controllers directory.
It's all very clever.
One issue with the directory layout above is that the controllers within the default route will need models and views too. These are within the application directory itself an so interspersed with the module directories; feels a bit untidy to me. It makes more sense to me to create a directory called default to hold the three directories:
application/
blog/
controllers/
IndexController.php
models/
views/
default/
controllers/
IndexController.php
ArticleController.php
models/
views/
news/
controllers/
IndexController.php
ListController.php
models/
views/
lib/
Zend/
webroot/
css/
img/
js/
index.php
with the set up code in index.php becoming:
To set this up, you use this code in index.php:
$frontController->setControllerDirectory(array( 'default' => array('../application/default/controllers'), 'blog' => '../application/blog/controllers', 'news' => '../application/news/controllers' )); $frontController->setRouter(new Zend_Controller_ModuleRouter()) ->setDispatcher(new Zend_Controller_ModuleDispatcher())
This now nicely keeps the MVC componts together and seems to work quite well. What I'm not sure of is how to handle an admin site. I suspect that the rewrite module router is the way to do this. I'm now into guesswork though, so will have to actually write some code in my IDE and see what happens.
I'm not sure what directory structure I want yet either.
If we take the news module:
news/
controllers/
IndexController.php
ListController.php
models/
views/
Do I want to put admin with it?
news/
controllers/
admin/
IndexController.php
IndexController.php
ListController.php
models/
views/
admin/
Or do I want a separate adminNews module? It's likely that the models used by news and adminNews will be the same (or adminNews will use a super-set of the news model), so I can see the logic of putting the admin code within the same set of directories.
Maybe I think too much about these sort of issues!


