Magento – Check if block rendered and displayed on the current page

blockslayoutmagento-1magento2render

Is there any way I can check if a block is displayed on the current page?

I have a block my.banner with simple image. This block is added to the left sidebar on many different types of pages, e.g. on category pages, on custom CMS pages etc.

<default>
    <reference name="header">
        <block type="mymodule/header" name="my_header" template="header.phtml" />
    </reference>
</default>
<cms_page>
    <reference name="left">
        <block type="mymodule/banner" name="my.banner" template="banner.phtml" />
    </reference>
</cms_page>
<catalog_category_default>
    <reference name="left">
        <block type="mymodule/banner" name="my.banner" template="banner.phtml" />
    </reference>
</catalog_category_default>
...

Then, in another block my_header in the header I need to programmatically check if my.banner block will be actually displayed on the current page. If it's not displayed, then in the header I need to display additional info for customers.

I can check if the my.banner exists in the layout:

$block = $this->getLayout()->getBlock('my.banner');
if ($block !== false)
{
    //...banner exists
}

But this is not a solution, because the problem is that admin can any time disable the left sidebar (e.g. on selected category page). And if the left sidebar was removed, then my.banner will not be displayed even if it's added to the sidebar in layout.

  1. So is there any way I can check if my.banner block will be actually rendered and displayed on the page?

  2. And if it's possible in Magento 1, what is equivalent in Magento 2?

Best Answer

Not in the way you want it. The problem is that at the time the header is rendered, you can't know if another block will be rendered at a later point. As you already noticed, there are other factors besides the block being part of the layout hierarchy, for example:

  • will getChildHtml() of the parent block be called?
  • is module output disabled?
  • is the block dynamically removed somewhere between rendering of the head and rendering of the blocks parent?
  • will the parent even be rendered?

So you will need some trickery. A possible workaround is to make the check in another block that is rendered after your block, for example as child of before_body_end and then move your alternative content to the header with JavaScript.

For this to work you must also make a change in your banner block because by default there is no flag that says "the block was rendered".

In Magento 1, you can use the _afterToHtml() method for that:

protected function _afterToHtml()
{
    $this->setData('i_was_rendered', true);
}

Then later you can check it like this:

if (! $layout->getBlock('my.banner')->getData('i_was_rendered_')) {
}
Related Topic