1

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

1 Answer 1

1

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.

<?php

namespace OX\DisplayPdpWithAttributeSet\Plugin\Helper\Product;

use Magento\Catalog\Block\Product\View as ViewBlock;
use Magento\Catalog\Helper\Product\View as ProductViewHelper;
use Magento\Catalog\Model\Product;
use Magento\Eav\Api\AttributeSetRepositoryInterface;
use Magento\Framework\DataObject;
use Magento\Framework\View\Result\Page;

class View
{
    const PRODUCT_LAYOUT_HANDLE = 'catalog_product_view_attribute_set_attributecode';

    /**
     * @var AttributeSetRepositoryInterface
     */
    private $attributeSetRepository;

    /**
     * @var ViewBlock
     */
    private $productViewBlock;

    /**
     * View constructor.
     *
     * @param AttributeSetRepositoryInterface $attributeSetRepository
     * @param ViewBlock                       $productViewBlock
     */
    public function __construct(
        AttributeSetRepositoryInterface $attributeSetRepository,
        ViewBlock $productViewBlock
    ) {
        $this->attributeSetRepository = $attributeSetRepository;
        $this->productViewBlock       = $productViewBlock;
    }

    /**
     * @param ProductViewHelper $subject
     * @param Page              $resultPage
     * @param Product           $product
     * @param null|DataObject   $params
     *
     * @return array
     */
    public function beforeInitProductLayout(
        ProductViewHelper $subject,
        Page $resultPage,
        Product $product,
        ?DataObject $params = null
    ) {
        $currentProduct   = $this->productViewBlock->getProduct();
        $attributeSetId   = $currentProduct->getAttributeSetId();
        $attributeSet     = $this->attributeSetRepository->get($attributeSetId);
        $attributeSetName = $attributeSet->getAttributeSetName();

        if ($attributeSetName == "attribute code") {
            $resultPage->addHandle(self::PRODUCT_LAYOUT_HANDLE);
        }

        return [
            $resultPage,
            $product,
            $params
        ];
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.