Load Block Outside Magento, and Apply Current Template

Load block outside Magento, and apply current template

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.

Magento. Insert block into another without change template code

There is a way to do this, although it is not an entirely elegant solution. It will work in most instances though and has proved helpful on occasion.

Basically the idea is that you replace the block you want to render your block before/after in your layout XML, place that block as a child in your block and then render it's output before/after yours.

So let's say you wanted to output a block before the totals block on the cart details page, you could do the following in your extension's layout.xml

<checkout_cart_index>
<reference name="checkout.cart">
<block type="myextension/block" name="myextension.block" as="myextension_block" template="myextension/template.phtml">
<action method="setChild"><name>totals</name><block>totals</block></action>
</block>
<action method="setChild"><name>totals</name><block>myextension.block</block></action>
</reference>
</checkout_cart_index>

Then in your template.phtml file you would have:

<div id="myextension">
// Your template code
</div>

// Render the totals block that you placed inside your block
<?php echo $this->getChildHtml('totals'); ?>

As I said, this won't fit every situation and it's not incredibly elegant, but it does work.

Jon

Set Magento block template in layout xml

Your approach is almost correct.

Two things:

1. Set a new template instead of instantiating a new block
Instead of just assigning a different template to the product.info block, you are creating a new instance with the same name, replacing the original instance, and then the new template is set on that. Instead use this:

<mymodule_product_index>
<update handle="catalog_product_view" />
<reference name="product.info">
<action method="setTemplate">
<template>mymodule/product.phtml</template>
</action>
</reference>
</mymodule_product_index>

That should take care of the product view template in a clean way.

2. Handle processing order
If you look at where the view block product.info.bundle for the bundled products is declared, you will see it happens in the bundle.xml file, in a layout update handle called <PRODUCT_TYPE_bundle>.

Your code is referencing the block from the <[route]_[controller]_[action]> layout handle, i.e. <mymodule_product_index>.

The thing to be aware of here is the processing order of layout handles.
Roughly it is:

  1. <default>
  2. <[route]_[controller]_[action]>
  3. <custom_handles>

The <PRODUCT_TYPE_bundle> handle belongs to the third type of layout handles, which means it is processed after the <mymodule_product_index> handle.

In essence, you are referencing the block product.info.bundle before it has been declared.

To fix this you will need to use the <PRODUCT_TYPE_bundle> handle as well. Of course this will effect every bundled product display. Using layout XML only there is no clean way around that.

Here are a few suggestions how to solve that problem.

You could create a separate route in your module to show the bundled products, and then include the <PRODUCT_TYPE_bundle> handle using an update directive for that page, too.

In your custom action controller, you could add another layout update handle that is processed after <PRODUCT_TYPE_bundle>.

You could use an event observer to set the template on the product.info.bundle block if it is instantiated. One possibility would be the event controller_action_layout_generate_blocks_after.

You get the idea, there are many ways to work around this, but they require PHP.

Magento 1.9: Add custom block to header

Go to your header.phtml file (app/design/frontend/package/theme/page/html/header.phtml) and place one of the following lines:

<?php echo $this->getChildHtml(); ?>

or

<?php echo $this->getChildHtml('wc-customheadblock'); ?>

Most likely header doesn't render child blocks by default because it would cause some template crashes. On the sidebars, extra childs can be easily appended at the end.

Including magento header outside of magento. Problems with $this-getChildHtml()

To show a block that is generated inside the header block, you need to first create it, then set it as child of the header block.

eg. Here is how I display within Wordpress a Magento header block, including the currency drop-down block that was generated by getChildHtml() inside the original header.phtml:

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

$headerBlock = $layout->createBlock('page/html_header')->setTemplate('page/html/header.phtml');
$currencyBlock = $layout->createBlock('directory/currency')->setTemplate('currency/currency.phtml');
$headerBlock->setChild('currency_selector', $currencyBlock);
$headerBlock = $headerBlock->toHtml();

Then you can write the block where you need it on the page:

echo $headerBlock;

I know it's a little late but hopefully this helps others with this issue.

add block to adminhtml_sales_order_view

You layout code is no longer going to work. Since it has some errors in it. I will point out what I can see.

  1. Block of described type does not exist

    You block type is vendor/additonal. Obviously it is a custom block that is defining by a custom module. It means you need to have a block with class name Vendor_Modulename_Block_Additional that should define in the location app/code/local/Vendor/Modulename/Block/Additional.php. Now here, your block have a name Vendor_ModuleName_Block_Sales_Order_View_AdditonalData (Location is unknown, you didn't provide). That means the block that you defined in layout is undefined and magento will throw some error in your log(if you activated your logs).

  2. Unnecessary before declaration

    See the answer of alanstorm for this THREAD. In short, you can define a before attribute in two cases only. Out of them, most frequently used case is the first one. That is

    your block should comes under a parent block which is of type core/text_list.

    Here the parent block that holds your custom block is order_tab_info block. It is a magento core defined block. So your before attribute is not going to work.

  3. You are trying to make your custom block as parent of a block, that holding your block !!!

    In your block defintion, you are trying to set order_tab_info block as a child of your block. Note that you are already staying inside order_tab_info block. That means your block is now a child of order_tab_info block. Didn't get what I have potrait? OK. consider a situation where a lady carries her child in her womb. Suppose the child is saying..

    "Hey I am the actual mother of my mother!!!!!"

    See.There is no logic in it. Again inside order_tab_info block, you are again redefining your custom block as its child block. It is just like, if the mother(in the above example) says

    "Hey every one, the child that I am carrying now is my child"

    Do you think, is it relevant to redefine it? Every one can understand that the child that carrying by that lady is obviously her child and she is her mother. No need for redefining it. So what you are trying to do here is completely wrong.

Try to make a good idea on magento's layout structure.

Good Luck.

Magento - remove setTemplate action from block

It is not possible to do this without a class rewrite or without some custom PHP calculation via helper & invoked in layout XML.

How to replace a block on the whole site. Magento

If you want to replace every occurance of Mage_Newsletter_Block_Subscribe with your own block My_Module_Block_Subscribe, use a class rewrite. In your modules config.xml:

<global>
<blocks>
<newsletter>
<rewrite>
<subscribe>My_Module_Block_Subscribe</subscribe>
</rewrite>
</newsletter>
</block>
</global>

But judging by your code, you actually do not have a custom block, just a custom template. You could change the template with an observer for the core_block_tohtml_before event, that calls setTemplate('mynewsletter/subscribe.phtml') on the block if its class is Mage_Newsletter_Block_Subscribe.

Magento CMS-Page template not loading after POST request

Ok i found that problem. The script raised an exception very deep in that external code. That causes an Exception at that point. After that Exception the whole content wasn't loading and the complete content field was ignored and was empty.

That was a very tricky problem.



Related Topics



Leave a reply



Submit