【问题标题】:Ways to call Blocks within Magento: createBlock vs Layout xml fileMagento 中调用 Block 的方法:createBlock vs Layout xml 文件
【发布时间】:2011-02-12 13:16:34
【问题描述】:

上下文:我正在尝试在网站的前端包含 Adminhtml 块以替换一些用户帐户块。我要做的第一件事就是在正确的页面上显示块。我可以通过在控制器内设置响应的正文来替换整个页面,但是我很难在布局 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()。 callback[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->renderLayout() 的调用是导致问题的原因。显然,我不能在同一个动作中同时呈现网格块和历史模板。不过我不知道为什么。

感谢您的指导!

【问题讨论】:

  • 您可能应该使用 adminhtml/sales_order_grid 扩展的块之一。 adminhtml 块应该在管理而不是前端使用/呈现。

标签: zend-framework magento


【解决方案1】:

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

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;
}

【讨论】:

  • 谢谢艾伦。是的,我忘记了在正确位置包含模板文件的步骤。我也在这样做。我正在使用社区版 v1.3.2.2,你是对的,Magento 正在使用 getOutput() 方法。回调[0] 不是对象。我不确定这是为什么 - adminhtml/sales_order_grid 被映射到正确的类。也许它依赖于另一个尚未加载的类?
  • 您是否将 sales_order_grid 块放置在 sales_order_history 元素中?
  • 这个块的模板是adminhtml/default/default/widget/grid.phtml。目前,块内没有调用 setTemplate ,这很好。但是,当我在 __construct() 中为 not adminhtml/default/default/widget/grid.phtml 的块分配不同的模板时,我看到了不同的行为。 grid.phtml 的响应是否与大多数模板不同。而不是在模板上调用 getHtml(),也许回调 [1] 方法应该是 getGridHtml()?
  • 不,这没有多大意义......因为“编程方法”在调用 createBlock 之后直接调用 toHtml()。呃。
  • 1.最好在这里更新您用于 cmets 的原始问题。它流动得更好,并且不会向其他人隐藏信息 2. 回调[0] 中的内容是什么? 3. 失败前正在渲染哪些块?
猜你喜欢
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 1970-01-01
  • 2013-09-29
  • 2013-06-17
相关资源
最近更新 更多