在Magento中调用块的方法:createBlock vs Layout xml文件

时间:2010-04-26 19:07:58

标签: zend-framework magento

上下文:我正在尝试在网站的前端包含Adminhtml块来替换某些用户帐户块。我要做的第一件事就是在正确的页面上显示块。我可以通过在控制器中设置响应的Body来替换整个页面,但是我很难在布局xml文件中包含块然后在模板中调用它。

此块的默认模板是adminhtml / default / default / widget / grid.phtml。所以我在前端主题中放置了widget / grid.phtml和widget / grid /文件夹(widget / grid.phtml所需)。

我正在使用社区版v1.3.2.2

为什么我能够使用createBlock从Mage_Sales_OrderController创建一个adminhtml / sales_order_grid:

$this->getResponse()->setBody($this->getLayout()->createBlock('adminhtml/sales_order_grid')->toHtml());

但不是从前端布局,使用声明

<sales_order_history>
    <reference name="content">
        <block type="adminhtml/sales_order_grid" name="orders_widget"/>
    </reference>
</sales_order_history>
app / design / frontend / default / default / layout / sales.xml

后者在没有堆栈跟踪的情况下产生错误:

Fatal error: Call to a member function toHtml() on a non-object in app/code/core/Mage/Core/Model/Layout.php on line 526

该行是Alan在下面引用的函数getOutput()。回调[0]中的数据为空白。据我所知,它是空的。输出到日志时,它是空白的。 get_class(callback [0])也不会返回任何可辨别的内容。

据我所知,没有渲染块。除了错误消息之外,浏览器中没有显示任何内容。在日志中,app / code / core / Mage / Core / Model / Layout.php中getOutput()方法的唯一输出是它中断的那个 - 在回调[0]中没有块名称。

但是,我知道正在调用sales_order_grid块上的_prepareCollection。

更新:事实证明我可以通过将块添加到布局文件来获取渲染块。抛出错误的调用位于公共函数historyAction()中的app / code / core / Mage / Sales / controllers / OrderController.php中。对$ this-&gt; renderLayout()的调用是导致问题的原因。显然,我不能同时在同一个动作中呈现网格块和历史模板。我不确定为什么。

感谢任何指导!

1 个答案:

答案 0 :(得分:2)

有关您为实现这一目标所做的其他自定义项的更多详细信息可能有助于人们解决您的问题。当我尝试“以编程方式创建块”代码时,我收到以下错误。

Warning: include(/path/to/magento1point4.dev/app/design/frontend/base/default/template/widget/grid.phtml) [function.include]: failed to open stream: No such file or directory  in /path/to/magento1point4.dev/app/code/core/Mage/Core/Block/Template.php on line 189

我在上面的位置添加了一个简单的phtml模板,并且能够在之后通过布局文件插入块

    <reference name="content">
        <block type="adminhtml/sales_order_grid" name="orders_widget"/>
    </reference>

所以我怀疑你已经做过的事情已经绊倒了。

此外,Magento版本可以提供帮助。当前版本的社区版的第526行是评论。

所有这些都说明了我最好的猜测是在Layout类的getOutput方法中失败了。我会在你的开发服务器上添加一些日志记录,看看Magento试图做什么/实例化什么时候它就可以了。

public function getOutput()
{
    $out = '';
    if (!empty($this->_output)) {
        foreach ($this->_output as $callback) {
            Mage:Log('Trying to get the block ' . $callback[0] . ' and call its ' . $callback[1] . 'method');
            $out .= $this->getBlock($callback[0])->$callback[1]();
        }
    }

    return $out;
}