I want to be able to pass data to the getChildHtml() call. The reason is, the output of the block is dependant upon a product type. So i want to pass the product to the getChildHtml so that it can decide on the output.

I am doing this inside template/checkout/cart/item/default.phtml.

Ideally, the call would look like:

echo $this->getChildHtml('child_block_name', $_item);

Then my block can get the product type from the item and display the correct output.

Since it is definitely not possible to pass this data to getChildHtml - how else can this type of behaviour be achieved without having to rewrite the core block

The two solutions i currently have are as follows (neither very attractive):

1 - Create a helper and access the html output via the helper instead of letting a block and template render it ala $this->helper('my_module')->getItemHtml($_item);

2 - Access the child block and setData on it inside the template:

 $this->getChild('child_name')->setData('item', $_item);
 echo $this->getChildHtml('child_name')

I think in terms of the Magento architecture, number 2 is the lesser of two evils, but it is darn ugly looking inside a template.

  • Can you instead provide the 'data' in the registry or session that the child block makes use of? Are you using this in an iterator? What's the use case?
    – philwinkle
    Commented May 15, 2013 at 22:19
  • I dont think the registry would help here as the desired output is dependent upon a cart items product type. So this must be passed to the block in some way so that the correct data can be output. The use case is display some extra info on the cart item, but it depends on product type Commented May 15, 2013 at 22:21
  • You can create product-type attributes - perhaps you create differing attributes based on product types? If you'd rather create your own block we can certainly advise in that direction but there may be some other built-in win here that I'm trying to sniff out...
    – philwinkle
    Commented May 15, 2013 at 22:24
  • Well, it is a product level attribute that i am accessing, but the way it is displayed depends on the product type. A grouped product will render the same attribute slightly differently than say a simple product. I am using a block and template for each different flavour of output Commented May 15, 2013 at 22:28
  • I have updated my question with some ideas i have which i am contemplating but am not 100% comfortable with Commented May 15, 2013 at 22:33

4 Answers 4


You can add a method on the parent block to fetch the child depending on the product type (I've seen this kind of logic a couple of times in core or something similar):

class ParentBlock 
    public function getIntuitiveNameChild($item)
        return $this->getChild("intuitive_child")
                    // You can also decide the product type in this setter, in the Child block.

    public function getIntuitiveNameChildDinamically($item)
        return $this->getChild("intuitive_child_" . $item->getProductType())

// parent tpl
// i suggest you avoid getChildHtml(), unless you're certain that methods won't need to be called from the tpl
echo $this->getIntuitiveNameChild($_item)
          // ->someOtherMethod()

Still, seeing how you modify the layout xml to add children blocks, you may be interested in how Magento decided to work with rendering markup depending on product types in Mage_Sales_Block_Items_Abstract::getItemHtml() and Mage_Checkout_Block_Cart_Abstract::getItemHtml().

  • This method bypasses the layout structure and produces blocks that are tightly coupled (like everything in Magento...) Commented Feb 21, 2019 at 17:20

The above solution wont work if you are displaying child block in foreach loop.

For that you need to use following code:

foreach ($blocks as $block) {
    $this->getChild("child.block")->setData("my_data", $any_data);
    echo $this->getChildHtml('child.block', false);

In child.block you can use $this->getMyData() to get the data. Using this strategy the child block will always get the latest data from parent.

The second parameter of getChildHtml() is $useCache. Setting it to false prevents the first output to be cached and forces rendering the child again.


A block that can receive data is called a widget; though this can be done via multiple block definitions (based on the properties of $_item).

Magento does something very similar in the core by loading the payment method block based on the method's short code:

    <?php echo $this->getChildHtml('payment.method.'.$_code) ?>

You could do the same with this pseudo-code:

if($type = $_item->getTypeId()){
    $this->getChildHtml('my.block.' . $type);

All that would require would be to have a different block type for each product type - bundle, simple, configurable, virtual, grouped. Not so bad, really.

If you really want to use a widget - it would be something to the effect of your second idea in your edited question:

echo $this->getLayout()->createBlock('yourcompany/widget_class')->setType($_item->getTypeId())->toHtml();

Creating a widget probably outside of the scope of this answer - but it's not terribly difficult, and has the advantage of being able to be repurposed for CMS blocks, though for your use case I don't think that is applicable.

For more information on creating a widget:


  • I am not 100% convinced this is a good approach to this which I havent accepted the answer. Commented May 16, 2013 at 8:20
  • 1
    Only a widget block can receive data? What do you mean? All blocks can receive data. A widget is something different in Magento terms.
    – nevvermind
    Commented May 16, 2013 at 15:55
  • I never said they couldn't; I'm saying, by definition, a widget requires data input to display something conditionally.
    – philwinkle
    Commented May 16, 2013 at 15:57

For Magento 2, you can use

foreach ($blocks as $block) {
    $block->getChildBlock("child.block")->setData("my_data", $any_data);
    echo $block->getChildHtml('child.block', false);

To get the data,


  • setData is not defined for bool.
    – jstuardo
    Commented Jul 23, 2021 at 22:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.