Different product layout based on product
Yes you can achieve this thing by writing small code
What you need to do is add layout via event layout_load_before
, you can use this event to add your dynamic layout.
Here is sample code for you, please modify as per your need
what you can do is create events.xml
in your module
[Vendor]/[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">
<!-- for diffrentiate layout.xml on product basis -->
<event name="layout_load_before">
<observer name="load_custom_handler" instance="[Vendor]\[Module]\Observer\LayoutLoadBefore" />
</event>
</config>
In your [Vendor]\[Module]\Observer\LayoutLoadBefore.php
file write below code
<?php
namespace [Vendor]\[Module]\Observer;
class LayoutLoadBefore implements \Magento\Framework\Event\ObserverInterface
{
/**
* @var \Magento\Framework\Registry
*/
private $registry;
public function __construct(
............
\Magento\Framework\Registry $registry,
............
) {
$this->registry = $registry;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$product = $this->registry->registry('current_product');
if (!$product) {
return $this;
}
if ($product->getMyvalue()) { // your condition
$layout = $observer->getLayout();
$layout->getUpdate()->addHandle('your_handle_name');
}
return $this;
}
}
And now go to [Vendor]\[Module]\view\frontend\layout\your_handle_name.xml
file and write your code.
This file only added to your specific condition of product
You can do it using xml for bulk products. for that you will have to override helper and create attribute for that. let me explain you descriptively.
Step 1: Create product attribute 'customlayout'.
- Create cutom product-attribute for custom layout, here I have just created attribute 'customlayout' with type boolean(yes/no).
- Assign this attribute in appropriate attribute-set.
- Now 'customlayout' is visible in products , set yes in those products which you want to set different layout.
Step 2: Override Helper function initProductLayout().
Override above helper function in your custom module and also change in di.xml file to override helper.
app/code/YourCompany/YourModule/etc/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">
<preference for="Magento\Catalog\Helper\Product\View" type="YourCompany\YourModule\Helper\Product\View" />
</config>
in YourCompany\YourModule\Helper\Product\view.php file.
public function initProductLayout(ResultPage $resultPage, $product, $params = null)
{
......
// add handle params
......
if ($params && $params->getBeforeHandles()) {
foreach ($params->getBeforeHandles() as $handle) {
$resultPage->addPageLayoutHandles(['customlayout' => $product->getCustomlayout(), 'id' => $product->getId(), 'sku' => $urlSafeSku], $handle);
$resultPage->addPageLayoutHandles(['type' => $product->getTypeId()], $handle, false);
}
}
$resultPage->addPageLayoutHandles(['customlayout' => $product->getCustomlayout(), 'id' => $product->getId(), 'sku' => $urlSafeSku]);
$resultPage->addPageLayoutHandles(['type' => $product->getTypeId()], null, false);
if ($params && $params->getAfterHandles()) {
foreach ($params->getAfterHandles() as $handle) {
$resultPage->addPageLayoutHandles(['customlayout' => $product->getCustomlayout(), 'id' => $product->getId(), 'sku' => $urlSafeSku], $handle);
$resultPage->addPageLayoutHandles(['type' => $product->getTypeId()], $handle, false);
}
}
........
}
Here I have added custom attribute for custom layout handle.
now you can create custom layout file to use this attribute.
let's create custom handle file.
Step 3: Create layout file for custom layout.
Create layout file in your custom theme/ custom module.
catalog_product_view_customlayout_1.xml
Here you can set your custom changes in it. it will be applied to all the products which have 'customlayout' attibute value is 'yes'.