Question

I am trying to create a different product view based on the Attribute Set Name (not ID, or specific attribute value). I've looked at a couple different tickets here already, and have tried to implement this using a plugin for beforeInitProductLayout ... but I can't seem to get it to work.

Magento 2 - Layout based on attribute set

Layout handle from attribute set

Vendor/Namespace/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="vendor_namespace_helper_product_view" type="Vendor\Namespace\Plugin\Helper\Product\View" />
    </type>
</config>

Vendor/Namespace/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Namespace" setup_version="1.0.0">
    </module>
</config>

Vendor/Namespace/Plugin/Helper/Product/View.php

namespace Vendor\Namespace\Plugin\Helper\Product;

use Magento\Bundle\Model\Product\Type;
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;

class View
{
    const PRODUCT_LAYOUT_HANDLE = 'catalog_product_view_boxedcard';

    /**
     * @var DataObjectFactory
     */
    private $dataObjectFactory;

    /**
     * @param DataObjectFactory $dataObjectFactory
     */
    public function __construct(
        DataObjectFactory $dataObjectFactory
    ) {
        $this->dataObjectFactory = $dataObjectFactory;
    }

    public function beforeInitProductLayout(
        \Magento\Catalog\Helper\Product\View $view,
        \Magento\Framework\View\Result\Page $resultPage,
        $product,
        $params = null
    )
    {

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');
        $attributeSet = $objectManager->create('Magento\Eav\Api\AttributeSetRepositoryInterface');
        $attributeSetRepository = $attributeSet->get($product->getAttributeSetId());
        $attribute_set_name = $attributeSetRepository->getAttributeSetName();

       if ($attribute_set_name == "Boxed Card Image Roles") {
           if (!$params) {
               $params = new \Magento\Framework\DataObject();
           }
               $afterHandles = $params->getAfterHandles();
               if (!$afterHandles) {
                   $afterHandles = array();
               }
               $afterHandles[] = PRODUCT_LAYOUT_HANDLE;
               $params->setAfterHandles($afterHandles);
           }
           return [$resultPage, $product, $params];
        }
}

Vendor/Namespace/view/frontend/layout/catalog_product_view_boxedcard.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>

    <referenceBlock name="product.info.media.image" remove="true"/>

        <referenceContainer name="product.info.media">
            <block class="Magento\Catalog\Block\Product\View\Gallery" name="boxed.card.gallery" template="Vendor_Namespace::product/view/gallery.phtml" />
        </referenceContainer>
    </body>
</page>

When I go to products on my local site that have this Product Attribute Set, it says the page can't be found and renders like this:

enter image description here

Was it helpful?

Solution

Based on the instructions found here, https://www.atwix.com/magento-2/add-custom-layout-handle-to-product-page-magento-2/, I was able to get it to work.

Vendor/Namespace/Plugin/Helper/Product/View.php

namespace Vendor\Namespace\Plugin\Helper\Product;

use Magento\Catalog\Helper\Product\View as ProductViewHelper;
use Magento\Catalog\Model\Product;
use Magento\Framework\DataObject;
use Magento\Framework\View\Result\Page as ResultPage;
use Magento\Framework\View\Result\Page;

class View
{
   const PRODUCT_LAYOUT_HANDLE = 'catalog_product_view_boxedcard';
    /**
     * @param  ProductViewHelper $subject
     * @param  Page            $resultPage
     * @param  Product         $product
     * @param  null|DataObject $params
     * @return array
     */
    public function beforeInitProductLayout(
        ProductViewHelper $subject,
        $resultPage,
        $product,
        $params
    ) {

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');
        $attributeSet = $objectManager->create('Magento\Eav\Api\AttributeSetRepositoryInterface');
        $attributeSetRepository = $attributeSet->get($product->getAttributeSetId());
        $attribute_set_name = $attributeSetRepository->getAttributeSetName();

        if ($resultPage instanceof ResultPage && $attribute_set_name == "Boxed Card Image Roles") {
            $resultPage->addHandle([static::PRODUCT_LAYOUT_HANDLE]);
        }
        return [
            $resultPage,
            $product,
            $params
        ];
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top