Magento自定义路由器丢失的布局对象 [英] Magento Custom Router Lost Layout Object
问题描述
似乎一切都已正确配置,我可以得到想要的输出,但我宁愿不要直接从控制器回显布局对象:
It seems like everything is being properly configured and I can get the output that I want but I would prefer not echoing the layout object directly from my controller:
我正在与之合作 config.xml
Here is what Im working with config.xml
<config>
<modules>
<ALS_Bestselling>
<version>0.1.0</version>
</ALS_Bestselling>
</modules>
<global>
<models>
<bestselling>
<class>ALS_Bestselling_Model</class>
</bestselling>
</models>
<blocks>
<bestselling>
<class>ALS_Bestselling_Block</class>
</bestselling>
</blocks>
<helpers>
<bestselling>
<class>ALS_Bestselling_Helper</class>
</bestselling>
</helpers>
</global>
<frontend>
<layout>
<updates>
<als_bestselling>
<file>bestselling.xml</file>
</als_bestselling>
</updates>
</layout>
</frontend>
<default>
<web>
<routers>
<bestselling_router>
<area>frontend</area>
<class>ALS_Bestselling_Controller_Router</class>
</bestselling_router>
</routers>
</web>
<shorturls>
</shorturls>
</default>
</config>
和
#File: Controller/Router.php
<?php
class ALS_Bestselling_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract
{
private static $_module = 'bestsellers';
private static $_realModule = 'ALS_Bestselling';
private static $_controller = 'index';
private static $_controllerClass = 'ALS_Bestselling_Controller_Index';
private static $_action = 'view';
public function initControllerRouters($observer)
{
$front = $observer->getEvent()->getFront();
$front->addRouter('bestselling', $this);
}
public function collectRoutes()
{
// nothing to do here
}
public function match(Zend_Controller_Request_Http $request)
{
$this->_request = $request;
$front = $this->getFront();
$identifier = trim($request->getPathInfo(), '/');
if(!substr($identifier,0,strlen('bestsellers')) == 'bestsellers'){
return false;
}else{
//$rewrite = Mage::getModel('core/url_rewrite');
$route_params = str_replace ( "bestsellers/" , "" , $identifier );
$rewrite = Mage::getModel('core/url_rewrite');
$rewrite->setStoreId(1);
$rewrite->loadByRequestPath($route_params);
$category_route = $rewrite->getIdPath();
//If no route exists for category send to a different router
if(!$category_route != ""){
return false;
}//Otherwise send the parameters to the request
else{
$id = str_replace ( "category/" , "" , $category_route );
$this->_request->setParam('id',$id);
}
$this->_setRequestRoute();
$this->_dispatch();
return true;
}
}
protected function _setRequestRoute()
{
$this->_request->setModuleName(self::$_module);
$this->_request->setControllerName(self::$_controller);
$this->_request->setActionName(self::$_action);
$this->_request->setControllerModule(self::$_realModule);
}
protected function _dispatch()
{
$this->_request->setDispatched(true);
$controller = Mage::getControllerInstance(self::$_controllerClass, $this->_request, $this->_response);
$controller->dispatch(self::$_action);
}
}
和
File: Controller/Index.php
class ALS_Bestselling_Controller_Index extends Mage_Core_Controller_Front_Action{
public function viewAction(){
$layout = Mage::app()->getLayout();
$layout->generateXml()->generateBlocks();
$render = $layout->getBlock('root')->toHtml();
echo $render;
}
}
先前的作品,但以下作品:
The previous works but the following:
$update = $this->getLayout()->getUpdate();
$update->addHandle('default');
$this->renderLayout();
在非对象上引发错误调用成员函数appendBody().
throws an error Call to a member function appendBody() on a non-object.
这是我应该做的事情吗,还是食谱中缺少一些东西?
Is this how I am suppose to do this or is there something missing from the recipe?
推荐答案
自定义路由类位于大多数开发人员使用Magento的边缘-标准方法是
Custom routing classes are on the fringe of what most developers do with Magento — the standard approach would be to setup a standard module controller with a frontname of bestselling
, or create your feature in a non-seo friendly way and then create a rewrite entity/object to SEO-ify it.
但是,我对自定义路由对象情有独钟,即使它们背后的最佳社区实践方法很少.没有行号,这听起来像您的例外情况
I, however, have a soft spot for custom routing objects, even if there's little in the way of best community practices behind them. Without a line number, it sounds like your exception
在非对象上调用成员函数appendBody()
Call to a member function appendBody() on a non-object
来自以下代码
#File: app/code/core/Mage/Core/Controller/Varien/Action.php
$this->getResponse()->appendBody($output);
给出getResponse
public function getResponse()
{
return $this->_response;
}
听起来您的控制器对象没有设置正确的响应对象.
It sounds like your controller object doesn't have a proper response object set.
查看您的控制器实例化代码
Looking at your controller instantiation code
$controller = Mage::getControllerInstance(self::$_controllerClass, $this->_request, $this->_response);
您引用的是$this->_response
属性-但是您的路由器类和抽象路由器类没有此属性.根据您发布的内容无法说出来,但这可能是您的问题.看看标准路由器的match方法是如何做到的.
You're referencing a $this->_response
property — but your router class and the abstract router class don't have this property. It's impossible to say based on what you've posted, but this is probably your problem. Take a look at how the standard router's match method does it.
#File: app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
//...
$controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse());
因此,使用前端控制器对象获取响应对象,并将其传递到getCongrollerInstance
工厂方法中,您应该会很好(或至少进入下一个问题)
So, use the front-controller object to grab the response object, pass that into the getCongrollerInstance
factory method, and you should be good to go (or at least onto the next problem)
这篇关于Magento自定义路由器丢失的布局对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!