In trying to come up with my own solution to my other active question, I've been trying to add child blocks to my own custom block so that I can use them as renderers for the product options, thus replicating the general way that product forms are rendered on the product page.
The problem is that I get an error stating that the block I'm trying to add already exists. Taking that into account, I have tried several methods of determining if the child block already exists and none of them have worked yet.
Attempt 1 (check to see if we can get the child block)
protected function _prepareLayout() {
if (!$this->getChildBlock('default')) {
$childBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\View\Options\Type\DefaultType', 'product.info.options.default');
$childBlock->setTemplate('Magento_Catalog::product/view/options/type/default.phtml');
$this->addChild('default', $childBlock);
}
return parent::_prepareLayout();
}
Attempt 2 (check to see if the name already exists in layout)
protected function _prepareLayout() {
$layout = $this->getLayout()
if (!$layout->getChildName($this->getNameInLayout(), 'default')) {
$childBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\View\Options\Type\DefaultType', 'product.info.options.default');
$childBlock->setTemplate('Magento_Catalog::product/view/options/type/default.phtml');
$this->addChild('default', $childBlock);
}
return parent::_prepareLayout();
}
Attempt 3 (check local variable to determine if this code has already been run)
protected function _prepareLayout() {
if (!$this->_layoutPrepared) {
$childBlock = $this->getLayout()->createBlock('Magento\Catalog\Block\Product\View\Options\Type\DefaultType', 'product.info.options.default');
$childBlock->setTemplate('Magento_Catalog::product/view/options/type/default.phtml');
$this->addChild('default', $childBlock);
$this->_layoutPrepared = true;
}
return parent::_prepareLayout();
}
In each attempt, I have received the frontend error of "We're sorry, an error has occurred while generating this content." (which is spectacularly helpful considering error display is turned on).
From the exception log, I find this error twice: report.CRITICAL: Element with ID 'form_0.default' is already defined.
which tells me that the code appears to be running multiple times.
What I gather from this is that somehow the code is being run three times: once successfully, and twice with errors. If I comment out the code, the child block cannot be found at all so it is not the case that there is a block with the same alias. It also doesn't matter what the alias is, as this has been tested with multiple variations.
I can't see any reason why _prepareLayout
would get called multiple times, nor why it wouldn't be able to find the already existing child blocks and prevent the duplication using the code I have tried.
Any assistance in resolving this issue would be welcomed.
For reference, if relevant, this is Magento Commerce 2.2.2.