2

This is the source for my doubt. Please have a a look on this question, answer and answer's comment.

Basically the question demands to include a core/template block inside header block. For this we can use this code in layout XML.

<reference name="header">
    <block type="core/template" name="test_name" as="test_as" template="test/test.phtml" />
</reference>

and the test.phtml look like this.

<p><?php echo $this->__('Can you see me ?'); ?></p>

In order to see the content of my template, I need to call my test block inside header block as like this. This is because, header block is of type page/html_header and the block will not automatically convert its content to html as other core block does. So this is how we can call test block in header block.

<div><?php echo $this->getChildHtml('test_as') ?></div>

Note that, I am using the as property of test block to invoke that block in header block. Upto this everything is clear for me. But the actual doubt starts here.

Doubt :- If I didn't specify the as property in my test block and if I call my test block and then invokes the block as like this,

 <div><?php echo $this->getChildHtml('test_name'); ?></div>

it works and show the content of test.phtml in frontend. This also works.

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

How it is possible to show the block output, by invoking that block with its name in its parent block ????

I am asking this because, there were lot of occasions in which I didn't specify as property that leaves a block not rendered. (even if I use name property of my block)

I know, magic happens here. But I can't just understand what exactly happens here.

public function getChildHtml($name = '', $useCache = true, $sorted = false)
{
    if ($name === '') {
        if ($sorted) {
            $children = array();
            foreach ($this->getSortedChildren() as $childName) {
                $children[$childName] = $this->getLayout()->getBlock($childName);
            }
        } else {
            $children = $this->getChild();
        }
        $out = '';
        foreach ($children as $child) {
            $out .= $this->_getChildHtml($child->getBlockAlias(), $useCache);
        }
        return $out;
    } else {
        return $this->_getChildHtml($name, $useCache);
    }
}

So any help mostly appreciated .

Thanks in Advance

3

The magic actually happens in Mage_Core_Block_Abstract::insert():

public function insert($block, $siblingName = '', $after = false, $alias = '')
{

    //...

    if ($block->getIsAnonymous()) {
        $this->setChild('', $block);
        $name = $block->getNameInLayout();
    } elseif ('' != $alias) {
        $this->setChild($alias, $block);
        $name = $block->getNameInLayout();
    } else {
        $name = $block->getNameInLayout();
        $this->setChild($name, $block);
    }

If there is no alias specified, the name is automatically used as alias.

  • Fabulous !!!! This is what I looking for a long time. Thank you so much for revealing the magic. :) – Rajeev K Tomy Sep 11 '15 at 8:14
2

When you don't pass anything to getChildHtml() the below part gets executed

  if ($name === '') {
        if ($sorted) {
            $children = array();
            foreach ($this->getSortedChildren() as $childName) {
                $children[$childName] = $this->getLayout()->getBlock($childName);
            }
        } else {
            $children = $this->getChild();
        }
        $out = '';
        foreach ($children as $child) {
            $out .= $this->_getChildHtml($child->getBlockAlias(), $useCache);
        }
        return $out;
    } 

This basically gets the list of children object either sorted or unsorted from either the layout object or Mage_Core_Block_Abstract::$_children

Whenever you do $this->loadLayout(); in a controller, it basically loads the blocks from xml handle and add the block objects to the layout model and subsequently the children blocks are also added to their parent's _children property. This happens in this function

Mage_Core_Block_Abstract::setChild($alias, $block)

{
        if (is_string($block)) {
            $block = $this->getLayout()->getBlock($block);
        }
        if (!$block) {
            return $this;
        }

        if ($block->getIsAnonymous()) {
            $suffix = $block->getAnonSuffix();
            if (empty($suffix)) {
                $suffix = 'child' . sizeof($this->_children);
            }
            $blockName = $this->getNameInLayout() . '.' . $suffix;

            if ($this->getLayout()) {
                $this->getLayout()->unsetBlock($block->getNameInLayout())
                    ->setBlock($blockName, $block);
            }

            $block->setNameInLayout($blockName);
            $block->setIsAnonymous(false);

            if (empty($alias)) {
                $alias = $blockName;
            }
        }

        $block->setParentBlock($this);
        $block->setBlockAlias($alias);
        $this->_children[$alias] = $block;
        return $this;
    }

So this is how

$this->getChildHtml('<As attribute of block>')
and $this->getChildHtml(); // to retrieve all child block html

Work!

I am trying to get a block when it's name attribute is mentioned in the layout file but the as property is not. I am not able to retrieve the html for that block in Magento 1.9

  • getChildHtml() will load all child blocks. But my question is how getChildHtml('block_name') worked ? – Rajeev K Tomy Aug 27 '14 at 4:45
  • I tried it on the checkout_onepage_index handle but wasn't able to get the block using: getChildHtml('block_name') in Magento 1.9 Have you tried this? – Paras Sood Aug 27 '14 at 6:44
  • @parasood : Ya that is what I am asking. We cannot get a block in a template file using its name. block names are used only to refer them in layout handles. In order to refer them in template file as property is used. – Rajeev K Tomy Aug 27 '14 at 8:45
  • We are on the same page then ;) I was saying the same thing. – Paras Sood Aug 27 '14 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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