2

I've declared a plugin that creates and adds a block programmatically if a condition is true. However, my code outputs nothing, it's like if the created block is not rendered at all.

etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\View\Element\AbstractBlock">
        <plugin name="Vendor_Module" type="Vendor\Module\Plugin\AppendBlockPlugin"/>
    </type>
</config>

Plugins/AddBlockPlugin.php

public function beforeToHtml(AbstractBlock $block)
{
    if (($block instanceof Block\Product\View)
        && $block->getNameInLayout() === 'product.info'
    ) {
        $template = 'Vendor_Module::block.phtml';

        $block->addChild(
            'custom_block',
            \Vendor\Module\Block\Block::class,
            compact('template')
        );
    }
}

I've made some debugging to this code to ensue that the custom block renders without any errors and that the ->addChild method is actually being called, but still no output for the block I added.

2

You can do this by event.

use event:

layout_generate_blocks_after

On this event add your block to product.info.

Event:

<?php
namespace [MyVendor]\[MyModule]\Observer;

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

class AddAChildBlock implements ObserverInterface
{
    const TEMPLATE_TO_ADD = '[OtherVendor]_[OtherModule]::template.phtml';
    const PARENT_BlOCK_NAME = 'product.info';
    public function execute(Observer $observer)
    {
        /** @var \Magento\Framework\View\Layout $layout */
        $layout = $observer->getLayout();
        $blocks = $layout->getAllBlocks();
        foreach ($blocks as $key => $block) {
             $template = 'Vendor_Module::block.phtml';
            /** @var \Magento\Framework\View\Element\Template $block */
            if ($block->getNameInLayout() == self:PARENT_BlOCK_NAME) {
                $blocks->addChild(
                'custom_block',
                 \Vendor\Module\Block\Block::class,
                    [
                        'template' => $template
                    ]
                );
            }
        }
    }
}

Also, your parent template file means product.info you need to add the code

echo $block->getChildHtml('custom_block);

to show the child block content

  • That's still not showing any output of the custom block, although (again), I made sure that the ->addChild method is being called. – user61389 Dec 22 '17 at 10:37
  • I see that you have added the echo part to your answer. But, how can I achieve that while maintaining modularity? – user61389 Dec 22 '17 at 12:45
  • 1
    If you parent block does not have $block->getChildHtml() function then it is not easy to add the child block on render parent phtml . Only possible to add child block on after html generetation of parent template file . – Amit Bera Dec 22 '17 at 13:54

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.