强制Magento始终对模块使用单个控制器
最终结果是我可以访问 http://www.mysite.com /frontname/something/something
The end result would be that I could go to http://www.mysite.com/frontname/something/something
我将捕获姓氏后面的所有内容,并使用它来添加钩子和设置数据. 这将以与类别如何工作类似的方式起作用,但是我的名字将被前缀在url之前,以便我可以在与该类别相关的布局中调用不同的块.
I will capture everything after the frontname and use that to add hooks and set data. This would act in a similar manner to how categories work but my frontname would be prepended to the url so that i can call different blocks in the layout related to that category.
如果在解决所有问题后对其他人有帮助,则可以使用_call方法来处理所有请求:
If it would help someone else after this is all figured out you would use the _call method to handle all requests: Dynamic router name for magento controller
如果有更好的方法可以做到这一点
If there is a better way to do this im all ears.
您应该创建一个自定义的路由器,它将与默认路由器一起使用.要将新路由器添加到配置中,请使用以下XML:
You should create a custom router that will be used additionally to the default router. To add a new router to the config, use this XML:
<default>
<web>
<routers>
<arbitrary_name>
<area>frontend</area>
<class>Your_Module_Controller_Router_Something</class>
</arbitrary_name>
</routers>
</web>
<shorturls>
</shorturls>
</default>
路由器可能如下所示:
class Your_Module_Controller_Router_Something extends Mage_Core_Controller_Varien_Router_Abstract
{
private static $_module = 'your_module';
private static $_realModule = 'Your_Module';
private static $_controller = 'your_controller';
private static $_controllerClass = 'Your_Module_ControllerClassName';
private static $_action = 'your_action';
/**
* @var Zend_Controller_Request_Http
*/
protected $_request;
/**
* Front controller looks for collectRoutes() although it is not defined
* in abstract router class!
*
* (non-PHPdoc)
* @see Mage_Core_Controller_Varien_Router_Standard::collectRoutes()
*/
public function collectRoutes()
{
// nothing to do here
}
/* (non-PHPdoc)
* @see Mage_Core_Controller_Varien_Router_Abstract::match()
*/
public function match(Zend_Controller_Request_Http $request)
{
$this->_request = $request;
// here you will have to implement your matching:
// - detect if the request should be matched by this router
// (i.e. check for "frontname" after base url)
// - return false if not
// - otherwise:
$this->_setRequestRoute();
$this->_dispatch();
return true;
}
/**
* @return void
*/
protected function _setRequestRoute()
{
$this->_request->setModuleName(self::$_module);
$this->_request->setControllerName(self::$_controller);
$this->_request->setActionName(self::$_action);
$this->_request->setControllerModule(self::$_realModule);
}
/**
* @return void
*/
protected function _dispatch()
{
$this->_request->setDispatched(true);
$controller = Mage::getControllerInstance(
self::$_controllerClass, $this->_request, $this->_response
);
$controller->dispatch(self::$_action);
}
}
重要的方法是match()
,它将为每个请求调用,并且必须确定路由器是否负责该请求,如果是,则将其分派.该路由器将始终调度相同的控制器操作your_controller/your_action
.
The important method is match()
which will be called for every request and has to determine if the router is responsible for the request and if yes, dispatch it. This router would always dispatch the same controller action your_controller/your_action
.
您可能还希望根据URL提供一些参数:$this->_request->setParam(key, value)
You might also want to make some parameters available based on the URL: $this->_request->setParam(key, value)