Nick Lo wrote:
One of the directory layouts, "Conventional Modular", was particularly interesting and seems to be a fairly logical way to organise modular ZF applications...

/application
/config (optional)
/(module1)
/config (optional as needed)
/controllers
/models
/views
/(module2)
/controllers
/models
/views
/(modulen)
/controllers
/models
/views

For what it's worth, I've been using some preDispatch code to allow a similar structure (or similar to this - it wasn't preDispatch at the beginning) ever since I started using ZF (which will probably be superceded sometime soon I know - but it's here in case it helps anyone):

/application
/config
/controllers
/ModulesController.php // See example below
/models
/modules
/module1
/controllers
/models
/views
/modulen
/controllers
/models
/views
/whois
/controllers
/WhoisController.php // See example route below
/views
/views

ModulesController.php - uses a define (MODULES_PATH) for the path to the modules folder:

class ModulesController extends Zend_Controller_Action {

public function init() {
parent::init();
}

public function preDispatch () {

// Get the Front controller from the registry
$ctrl = Zend::registry('ctrl_front');

$module = $this->_getParam('module', 'default');
$controller = $this->_getParam('module_controller', 'index');
$action = $this->_getParam('module_action', 'index');

$path = MODULES_PATH . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR;
$file = ucfirst($controller) . 'Controller.php';

// Check if the module and controller file exist
if (file_exists($path . $file) && is_readable($path . $file)) {

// Set the Modules controller path
$dispatcher = $ctrl->getDispatcher();
$dispatcher->setControllerDirectory($path);

// Add the module path to the include path for any local module files
if (!strstr(get_include_path(), $path)) {
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
}

// Forward to the appropriate module
$this->_forward($controller, $action, $this->_getAllParams());

} else {
$this->noRouteAction();
}
}

public function indexAction () {
}
}

The other piece that makes this work is the routing (from index.php):


$router = new Zend_Controller_RewriteRouter();

$default = new Zend_Controller_Router_Route('', array('module' => 'default', 'module_controller' => 'index', 'module_action' => 'index', 'controller' => 'modules', 'action' => 'index'));

//And an example for a whois module:

$route_whois = new Zend_Controller_Router_Route('whois/:domain/*', array('module' => 'whois', 'module_controller' => 'whois', 'module_action' => 'index', 'controller' => 'modules', 'action' => 'index'));

// or for more general /modules/modulename behaviour:

$route_modules3 = new Zend_Controller_Router_Route('modules/:module/:module_controller/:module_action/*', array('module' => 'default', 'module_controller' => 'index', 'module_action' => 'index', 'controller' => 'modules', 'action' => 'index'), array('module' => '(list|of|acceptable|modules|to|choose|from)+', 'module_controller' => '(list|of|acceptable|controllers)+', 'module_action' => '(list|of|acceptable|actions)+'));

$route_modules2 = new Zend_Controller_Router_Route('modules/:module/:module_controller/*', array('module' => 'default', 'module_controller' => 'index', 'module_action' => 'index', 'controller' => 'modules', 'action' => 'index'), array('module' => '(list|of|acceptable|modules|to|choose|from)+', 'module_controller' => '(list|of|acceptable|controllers)+'));

$route_modules1 = new Zend_Controller_Router_Route('modules/:module/*', array('module' => 'default', 'module_controller' => 'index', 'module_action' => 'index', 'controller' => 'modules', 'action' => 'index'));

/**
* Routes are matched in reverse order so make sure your most generic routes are defined first.
*/
$routes = array();
$routes['default'] = $route_default;
$routes['modules1'] = $route_modules1;
$routes['modules2'] = $route_modules2;
$routes['modules3'] = $route_modules3;
$routes['whois'] = $route_whois;

$router->addRoutes($routes);

$request = new Zend_Controller_Request_Http();

$ctrl = Zend_Controller_Front::getInstance();
Zend::register('ctrl_front', $ctrl);

$ctrl->setControllerDirectory(CONTROLLERS_PATH); // Defined before
$ctrl->setRequest($request);
$ctrl->setRouter($router);

$response = $ctrl->dispatch();


Hope that helps someone - it works nicely for me.

Jeremy

Reply via email to