开发者

Ways to call Blocks within Magento: createBlock vs Layout xml file

Context: I'm trying to include Adminhtml blocks in the frontend of the site to replace some of the user account blocks. The first thing I'm trying to do is simply display the block on the correct page. I can replace the entire page by setting the Body of the response inside the controller, but I'm having a hard time including the block in the layout xml file and then calling it within the template.

This block's default template is adminhtml/default/default/widget/grid.phtml. So I have placed widget/grid.phtml and widget/grid/ folder (needed by widget/grid.phtml) inside of the frontend theme.

I'm using community edition v1.3.2.2

Why would I be able to create an adminhtml/sales_order_grid from Mage_Sales_OrderContr开发者_运维知识库oller using createBlock:

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

But not from a frontend layout, using a declaration

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

within app/design/frontend/default/default/layout/sales.xml

The latter produces an error without a stack trace:

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

That line is the function getOutput() that Alan refers to below. The data in callback[0] is blank. As far as I can tell, it's null. When output to a log, it's blank. get_class(callback[0]) returns nothing discernable as well.

As far as I can tell, no blocks are rendered. There is nothing shown in the browser except the error message. In the log, the only output from the getOutput() method within app/code/core/Mage/Core/Model/Layout.php is the one where it breaks - no block name in callback[0].

However, I do know that _prepareCollection on the sales_order_grid block is being called.

Update: It turns out that I can get the block to render by adding it to the layout file. The call that throws the error is in app/code/core/Mage/Sales/controllers/OrderController.php in public function historyAction(). The call to $this->renderLayout() is what causes the problem. Evidently, I can't have both the grid block and the history template rendered in the same action. I'm not sure why though.

Thanks for any guidance!


More details about the other customizations you've done to get yourself to this point might help people troubleshoot your problem. When I tried your "create the block programmatically" code I got the following error.

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

I added a simple phtml template to the above location and was able to insert the block via a layout file succfully after that

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

So I suspect something you've done along the way already is tripping things up.

Also, a Magento version would help things. Line 526 of the current version of community edition is a comment.

All that said my best guess is things are failing in the getOutput method of the Layout class. I'd add some logging to the function on your dev server to see what Magento is trying to do/instantiate when it bails on you.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜