2

I created a new product type, and I want to create a product page in the frontend. How can I customize catalog_product_view.xml without affecting other product types?

3 Answers 3

5

You need to override the layout like this.

catalog_product_view_type_simple.xml -> Simple Product

catalog_product_view_type_virtual.xml -> Virtual Product

catalog_product_view_type_configurable.xml -> Configurable Product

catalog_product_view_type_downloadable.xml -> Downloadable Product

catalog_product_view_type_bundle.xml -> Bundle Product

catalog_product_view_type_grouped.xml -> Grouped Product 

catalog_product_view_type_custom.xml -> Custom Product Type

After updating the product layout in the product view. Then you can maintain product design by updating another layout also.

Example: Shopping Cart

checkout_cart_configure_type_{TYPE}.

Please check the default file: vendor/magento/module-checkout/view/frontend/layout/checkout_cart_configure_type_simple.xml Here they update the layout You also should to use this for your custom type.

vendor/magento/module-configurable-product/view/frontend/layout/checkout_cart_configure_type_configurable.xml
vendor/magento/module-checkout/view/frontend/layout/checkout_cart_configure_type_simple.xml
vendor/magento/module-bundle/view/frontend/layout/checkout_cart_configure_type_bundle.xml

Cart Item Rendererd

vendor/magento//module-configurable-product/view/frontend/layout/checkout_onepage_review_item_renderers.xml -> Configurable Product
vendor/magento//module-downloadable/view/frontend/layout/checkout_onepage_review_item_renderers.xml -> Downloadable Product
vendor/magento//module-bundle/view/frontend/layout/checkout_onepage_review_item_renderers.xm -> Bundle Product
vendor/magento//module-checkout/view/frontend/layout/checkout_onepage_review_item_renderers.xml -> All Product
vendor/magento//module-grouped-product/view/frontend/layout/checkout_onepage_review_item_renderers.xml -> Group Product

You need to create if your layout is not loaded proper in cart item. Please use the default file as a reference.

If you need to show your layout in PDF and order all section there are many files you need to create and update it.

Example: Print Creditmemo

Reference Files

vendor/magento//module-grouped-product/view/frontend/layout/sales_order_print_creditmemo_renderers.xml -> Group Product
vendor/magento//module-bundle/view/frontend/layout/sales_order_print_creditmemo_renderers.xml -> Bundle Product
vendor/magento//module-sales/view/frontend/layout/sales_order_print_creditmemo_renderers.xm -> All Product
vendor/magento//module-downloadable/view/frontend/layout/sales_order_print_creditmemo_renderers.xml -> Downloadable Product

Sample Code

<referenceBlock name="sales.order.print.creditmemo.renderers">
    <block class="Magento\Sales\Block\Order\Item\Renderer\DefaultRenderer" name="sales.order.print.creditmemo.renderers.custom" as="custom" 
           template="VendorName_ModuleName::order/creditmemo/items/renderer/default.phtml"/>
</referenceBlock>

There are many files that need to update if you show your custom product everywhere in the store. If you did not find any file for a particular layout please add comments or content to me. or You can get it in core module

3
  • I would also add that you should create a layout file checkout_cart_configure_type_{{TYPE}}.xml, in order to manage the product view page when edited from the cart. Inside it, call the following instruction : <update handle="catalog_product_view_type_{{TYPE}}"/>, replacing {{TYPE}} with your custom type name. Take a look at the file vendor/magento/module-checkout/view/frontend/layout/checkout_cart_configure_type_simple.xml for more info
    – Cladiuss
    Jun 27, 2023 at 8:57
  • @Cladiuss You are right you can feel free to edit my post and add your points there or you can also add your post here.
    – Msquare
    Jun 27, 2023 at 9:00
  • Done, I also added some explaination about where this magic happens.
    – Cladiuss
    Jun 27, 2023 at 9:34
2

As already said in @Msquare answer, there are native handlers created by Magento for each product types.

There are created with this template : catalog_product_view_type_{{TYPE}}, where {{TYPE}} is your custom type name (which has been defined in your product_types.xml file).

For a custom type named "custom", you can create a file called catalog_product_view_type_custom.xml where you can add your specific layout instructions.

The same process happens when editing a product in your shopping cart : Magento will create handlers for each product types with this template : checkout_cart_configure_type_{{TYPE}}.

So you will also need to create a file called checkout_cart_configure_type_custom.xml, in which you can call the first handle name :

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

Take a look at the file vendor/magento/module-checkout/view/frontend/layout/checkout_cart_configure_type_simple.xml for a example.


Explaination

This dynamic handles are added in the \Magento\Catalog\Helper\Product\View::initProductLayout method, with this specific instruction :

$resultPage->addPageLayoutHandles(['type' => $product->getTypeId()], null, false);

This method is called both in the Catalog Product View controller, and in the Checkout Cart Configure controller, which is why they both have those specific handles.

Note : The whishlist module also uses this method to create those specifics handles when configuring a whishlist item. They will look like : whishlist_index_configure_type_{{TYPE}}.

1

For example new product type is customtype, file layout name is catalog_product_view_customtype.

You can use event name layout_load_before for load this layout, you will check the product detail page if it is product type customtype => you will load layout catalog_product_view_customtype.

In etc/frontend/events.xml:

<event name="layout_load_before">
    <observer name="custom_layout_load_option" instance="Module\Custom\Observer\Layout\Load"/>
</event>

In Load.php:

<?php

namespace Module\Custom\Observer\Layout;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Catalog\Model\ProductFactory;

class Load implements ObserverInterface
{
    protected RequestInterface $request;
    protected ProductFactory $productFactory;
    public function __construct
    (
        RequestInterface $request,
        ProductFactory $productFactory
    )
    {
        $this->request = $request;
        $this->productFactory = $productFactory;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $fullActionName = $observer->getEvent()->getFullActionName(); // you get layout name here
        $layout = $observer->getEvent()->getLayout();
        $handler = '';
        if ($fullActionName == 'catalog_product_view') { // if it true, continue check product type
            // get product id by param
            $productId = $this->request->getParam('id');
            // get product type using productId
            $type = $this->productFactory->create()->load($productId, 'entity_id')->getTypeId();
            if ($type) {
                $handler = 'catalog_product_view_customtype';
            }
        }
        if ($handler) {
            $layout->getUpdate()->addHandle($handler);
        }
    }
}
1
  • 1
    While this might work, there is a natively a layout handler created by Magento for each product type : catalog_product_view_type_{{TYPE}}. You are also reloading the product from the database, instead of using the repository which will load it from the cache.
    – Cladiuss
    Jun 27, 2023 at 8:37

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.