Magento 2
Layout handles can be added by using a plugin on \Magento\Catalog\Helper\Product\View::initProductLayout
The $params
argument can control the order handles are added and subsequently merged when the layout is generated. $params
is an optional argument, but should be an instance of Magento\Framework\DataObject
when passed.
Handles are added in the following order:
$params->getBeforeHandles()
catalog_product_view_type_{{type}}
catalog_product_view_sku_{{sku}}
$params->getAfterHandles()
Example plugin where a custom layout handle is added based on a product attribute. The new layout handle will apply changes to Magento's core bundle product layout and must be added after catalog_product_view_type_bundle
.
etc/frontend/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Helper\Product\View">
<plugin name="custom_module_helper_product_view" type="Vendor\Namespace\Plugin\Helper\Product\View" />
</type>
</config>
Plugin/Helper/Product/View.php
<?php
declare(strict_types=1);
namespace Vendor\Namespace\Plugin\Helper\Product;
use Magento\Bundle\Model\Product\Type;
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;
class View
{
const HANDLE = 'my_custom_handle_for_getting_things_done';
/**
* @var DataObjectFactory
*/
private $dataObjectFactory;
/**
* @param DataObjectFactory $dataObjectFactory
*/
public function __construct(
DataObjectFactory $dataObjectFactory
) {
$this->dataObjectFactory = $dataObjectFactory;
}
/**
* @param \Magento\Catalog\Helper\Product\View $subject
* @param \Magento\Framework\View\Result\Page $resultPage
* @param \Magento\Catalog\Api\Data\ProductInterface $product
* @param null|DataObject $params
* @return array
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function beforeInitProductLayout(
\Magento\Catalog\Helper\Product\View $subject,
\Magento\Framework\View\Result\Page $resultPage,
\Magento\Catalog\Api\Data\ProductInterface $product,
?DataObject $params = null
): array {
if ($product->getTypeId() !== Type::TYPE_CODE) {
return [$resultPage, $product, $params];
}
if ($params === null) {
$params = $this->dataObjectFactory->create();
}
/*
* This is an example setting the layout based on a custom
* attribute. Anything, such as attribute set, could be used
* for driving the logic below.
*/
$simpleKit = $product->getCustomAttribute('some_attribute');
if ($simpleKit !== null && (bool)$simpleKit->getValue() === true) {
$afterHandles = $params->getAfterHandles() ?? [];
$afterHandles[] = self::HANDLE;
$params->setAfterHandles($afterHandles);
}
return [$resultPage, $product, $params];
}
}