Magento 2 – Different Product Layout Based on Product

layoutmagento2magento2.2product

What I have tried so far

As the title describes. How can one implement different layouts per product based on a value on that product (in this case a custom EAV on the Product entity)

At first I thought I'd create a custom product type for these type of products. This would work fine. Although you cannot change the product types for existing products.

Then I thought I could make a new page layout, though you can not add content to the product layout.

Lastly I thought I would simply add all these products in a category and change the product view there (via Design > Layout update XML) but this would involve the end user writing XML which is something I'd like to avoid if possible. Same goes for changing the Design > Layout update XML for each product.

Other info:

I have create a Magento module which should replace the product image with a different view. Currently I have overwritten (in my module) the view/frontend/layout/catalog_product_view.xml with my custom content (removing the original image/video blocks and adding my own blocks) this works fine though ALL products now have the new layout.

All products are simple products currently

Best Answer

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