1

I need to display the block in product detail page for bundle product only so I just add preference to overwrite Magento/Catalog/Controller/Product/View

Then alter the product detail page controller execute method like below.

// Render page
$page = $this->resultPageFactory->create();

if($this->_type->getById($productId)->getTypeId()=='bundle')
{
    $block=$page->getLayout()->createBlock('Vendor\Module\Block\Index\Index');
    $page->getLayout()->getBlock('content')->append($block);
}      

$this->viewHelper->prepareAndRender($page, $productId, $this, $params);
return $page;

but it always throws error like

PHP Fatal error: Call to a member function append() on boolean

I need to add my block to <referenceContainer name="content">

2 Answers 2

1

Why not just add your layout update to catalog_product_view_type_bundle.xml?

But in answer to your problem: You're creating a new $page from a factory. This page has not been added any child elements yet; other methods do that further on in the chain. That's why $page->getLayout()->getBlock('content') returns false: the 'content'-container does not yet exist.

0

Extending @GielBerkers answer, you can use an observer to modify layout programatically once it's ready.

Nspace/Module/etc/frontend/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="core_layout_render_element">
    <observer name="Nspace_Module::modify_block" instance="Nspace\Module\Observer\ModifyBlock" />
</event>

Nspace/Module/Observer/ModifyBlock.php

<?php

namespace Nspace\Module\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class ModifyBlock implements ObserverInterface
{
  protected $_scopeConfig;
  private static $_layoutSet = false;

  public function __construct(
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  ) {
    $this->_scopeConfig = $scopeConfig;
  }

 public function execute(Observer $observer)
 {
    // Run this only once
    if(ModifyBlock::$_layoutSet) { return; }
    ModifyBlock::$_layoutSet = true;

    $layout = $observer->getLayout();

    // Optional step if you need to remove somethig
    $children = $layout->getChildBlocks('content');
    foreach($children as $key => $childB) 
    {
        if($childB->getType() === [some_type]) 
        {
            $layout->unsetElement($key);
            break;
        }
    }

    // Add a new block
    $layout->createBlock('Vendor\Module\Block\Index\Index', 'custom-index-index');
    $layout->setChild('content', 'custom-index-index', 'custom-index-index');
    return;
 }
}
3
  • can you please explain these parameter 'custom-index-index', 'custom-index-index' in setChild() Function
    – Waqar Ali
    Commented May 21, 2019 at 9:11
  • @Waqar Ali these are elementName and alias for child block or container.
    – Alan
    Commented May 22, 2019 at 14:19
  • can u please explain in context of magento
    – Waqar Ali
    Commented May 23, 2019 at 6:10

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.