Custom Product View Based on Attribute Set Name
-
06-05-2021 - |
質問
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:
解決
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
];
}
}