Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
391 views
in Technique[技术] by (71.8m points)

php - Load block outside Magento, and apply current template

I have a Magento installation which is integrated with an external website, and I want the Magento's shopping cart block to be displayed on the header of this external site.

I have achieved this with the following code:

<?php

require_once(dirname(__FILE__).'/store/app/Mage.php');

$app = Mage::app();
$session = Mage::getSingleton('core/session', array('name'=>'frontend'));

$block = $app
    ->getLayout()
    ->getBlockSingleton('checkout/cart_sidebar')
    ->setTemplate('checkout/cart/sidebar.phtml');

echo $block->toHtml();

But, I want (and believe that it's possible) a nicer approach.

I dislike the fact that I must specify the template manually via setTemplate(), which involves hard-coding template locations and repeating something that it's defined somewhere else (in the design's layout xml files). I tried loading the block via $app->getLayout()->getBlock($name) with no results (were $name represents the block's reference name, as defined in the layout xml files).

So the question is:

Is there any way to render a block outside magento (with the following requisites)?

  • I want the base layout xml and the store's design layout updates of the design changes to be loaded automatically, so i don't need to specify the template path and the block type (again) manually.
  • I want to load the block by it's reference name, so I can make use of the properties applied to it on the layout xml files.

The purpose of this question is to wrap it in a function, and render every block outside Magento the same way it's done on the Magento templates. For example:

<div id="sidebar-cart-container">
    <?php echo $this->renderMagentoBlock('cart-block-reference-id'); ?>
</div>

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Took me a couple minutes of debugging, but it seems relatively easy.

<?php

/*
 * Initialize magento.
 */
require_once 'app/Mage.php';
Mage::init();

/*
 * Add specific layout handles to our layout and then load them.
 */
$layout = Mage::app()->getLayout();
$layout->getUpdate()
    ->addHandle('default')
    ->addHandle('some_other_handle')
    ->load();

/*
 * Generate blocks, but XML from previously loaded layout handles must be
 * loaded first.
 */
$layout->generateXml()
       ->generateBlocks();

/* 
 * Now we can simply get any block in the usual way.
 */
$cart = $layout->getBlock('cart_sidebar')->toHtml();
echo $cart;

Please note that you must manually specify which layout handles you want to load blocks from. The 'default' layout handle will contain the sidebar since it is placed there from inside checkout.xml.

But using the 'default' layout handle can come with a significant performance cost since many modules place their blocks in this handle. You may want to put all the blocks that you use on your external site in a separate layout handle and simply load that.

The choice is yours. Good luck.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...