Magento2 | PWA | GraphQL

Display Product attribute in checkout summary and minicart in Magento2


In this post, we will check how we can get product attribute (or a custom attribute) in checkout cart summary section as well as on minicart.

In our post we will display product manufacturer name next to the product name.

First of all we have to include the manufacturer attribute in the quote item as in not included by default.

Let's start it by creating custom module.

You can find complete module on Github




Create folder inside app/code/Magelearn/CartAttributes

Add registration.php file in it:
<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magelearn_CartAttributes', __DIR__);
Add composer.json file in it:
{
    "name": "magelearn/module-cartattributes",
    "description": "Add additional attribute to the Cart/minicart on Magento2 Site.",
    "type": "magento2-module",
    "license": "OSL-3.0",
    "authors": [
        {
            "email": "info@mage2gen.com",
            "name": "Mage2Gen"
        },
        {
            "email": "vijaymrami@gmail.com",
            "name": "vijay rami"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magelearn\\CartAttributes\\": ""
        }
    }
}
Add etc/module.xml file in it:
<?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="Magelearn_CartAttributes" setup_version="1.0.0"/>
</config>
To display custom product attribute in Quote Item object, we will create catalog_attributes.xml file.

Create catalog_attributes.xml file inside app/code/Magelearn/CartAttributes/etc folder.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="manufacturer"/>
    </group>
</config>

Custom attributes are not loaded by default when you work with a quote object in Magento.

For that, You will need to create catalog_attributes.xml file in "etc" directory of your module. You need to define the attribute names belonging to the corresponding group.

Magento 2 uses the following groups by default.

1. quote_item

The quote items group contains attributes to be added to selected products, that are assigned to quote items. If you want to access the product attribute value on checkout from the quote item – you just need to specify the attribute name within the quote_item group.

2. wishlist_item

This group contains attributes to be loaded for the products assigned to wishlist items. You can specify the attribute name within this group if you need it to be accessible from wishlist item.

3. catalog_product

The catalog product item group is being processed by Catalog Product Flat Indexer (as well as the quote_item group) in order to retrieve attribute codes to be added to flat tables.

4. catalog_category

This group is intended to define the category attributes to be added to selection during category collection preparation process before loading in Magento\Catalog\Model\ResourceModel\Category\Tree class.

5. unassignable

This group contains a list of attributes that cannot be unassigned from an attribute set.

6. used_in_autogeneration

This group contains a list of attributes that allows autogeneration on admin’s product edit form.

The vendor/magento/module-checkout/CustomerData/DefaultItem.php class is used for retrieving data for each item in mini cart.

In this class the function doGetItemData() is returning an array of the item's data. As we can see the product manufacturer data is not included in that array. So we have to override this function. 

Create di.xml file inside app/code/Magelearn/CartAttributes/etc/frontend folder.

<?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\Checkout\CustomerData\DefaultItem">
        <plugin name="minicart-product-attribute" type="Magelearn\CartAttributes\Plugin\Checkout\CustomerData\DefaultItem" disabled="false" sortOrder="10"/>
    </type>
</config>

Create DefaultItem.php file inside app/code/Magelearn/CartAttributes/Plugin/Checkout/CustomerData folder.

<?php

namespace Magelearn\CartAttributes\Plugin\Checkout\CustomerData;
use Magento\Quote\Model\Quote\Item;

class DefaultItem
{
    public function aroundGetItemData($subject, \Closure $proceed, Item $item) {
        $data = $proceed($item);
		$_product = $item->getProduct();
		$result = [];
        $result['manufacturer'] = $_product->getResource()->getAttribute('manufacturer')->getFrontend()->getValue($_product);
        return array_merge($data,$result);
    }
}

Now that we have the data that we need to display. For that we have to override the default template file.

As we can see /vendor/magento/module-checkout/view/frontend/layout/checkout_cart_sidebar_item_renderers.xml file, which is responsible for rendering the mini cart items.

And the template that is used in /vendor/magento/module-checkout/view/frontend/web/template/minicart/item/default.html

To override the files above, we create a checkout_cart_sidebar_item_renderers.xml file under /app/code/Magelearn/CartAttributes/view/frontend/layout folder.

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="minicart">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="minicart_content" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="item.renderer" xsi:type="array">
                                    <item name="component" xsi:type="string">uiComponent</item>
                                    <item name="config" xsi:type="array">
                                        <item name="displayArea" xsi:type="string">defaultRenderer</item>
                                        <item name="template" xsi:type="string">Magelearn_CartAttributes/minicart/item/default</item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Also we copy the /vendor/magento/module-checkout/view/frontend/web/template/minicart/item/default.html template file under /app/code/Magelearn/CartAttributes/view/frontend/web/template/minicart/item/default.html and we add the product manufacturer data next to the product name by adding the code below.

<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<li class="item product product-item" data-role="product-item">
    <div class="product">
        <!-- ko if: product_has_url -->
        <a data-bind="attr: {href: product_url, title: product_name}" tabindex="-1" class="product-item-photo">
            <!-- ko foreach: $parent.getRegion('itemImage') -->
                <!-- ko template: {name: getTemplate(), data: item.product_image} --><!-- /ko -->
            <!-- /ko -->
        </a>
        <!-- /ko -->
        <!-- ko ifnot: product_has_url -->
        <span class="product-item-photo">
            <!-- ko foreach: $parent.getRegion('itemImage') -->
                <!-- ko template: {name: getTemplate(), data: item.product_image} --><!-- /ko -->
            <!-- /ko -->
        </span>
        <!-- /ko -->

        <div class="product-item-details">
            <strong class="product-item-name">
                <!-- ko if: product_has_url -->
                <a data-bind="attr: {href: product_url}, html: product_name"></a>
                <!-- /ko -->
                <!-- ko ifnot: product_has_url -->
                    <!-- ko text: product_name --><!-- /ko -->
                <!-- /ko -->
                <!-- ko if: manufacturer -->
                    <p data-bind="html: manufacturer, style: {'font-weight': 'bold'}"></p>
                <!-- /ko -->
            </strong>

            <!-- ko if: options.length -->
            <div class="product options" data-mage-init='{"collapsible":{"openedState": "active", "saveState": false}}'>
                <span data-role="title" class="toggle"><!-- ko i18n: 'See Details' --><!-- /ko --></span>

                <div data-role="content" class="content">
                    <strong class="subtitle"><!-- ko i18n: 'Options Details' --><!-- /ko --></strong>
                    <dl class="product options list">
                        <!-- ko foreach: { data: options, as: 'option' } -->
                        <dt class="label"><!-- ko text: option.label --><!-- /ko --></dt>
                        <dd class="values">
                            <!-- ko if: Array.isArray(option.value) -->
                                <span data-bind="html: option.value.join('<br>')"></span>
                            <!-- /ko -->
                            <!-- ko if: (!Array.isArray(option.value) && option.option_type == 'file') -->
                                <span data-bind="html: option.value"></span>
                            <!-- /ko -->
                            <!-- ko if: (!Array.isArray(option.value) && option.option_type != 'file') -->
                                <span data-bind="text: option.value"></span>
                            <!-- /ko -->
                        </dd>
                        <!-- /ko -->
                    </dl>
                </div>
            </div>
            <!-- /ko -->

            <div class="product-item-pricing">
                <!-- ko if: canApplyMsrp -->

                <div class="details-map">
                    <span class="label" data-bind="i18n: 'Price'"></span>
                    <span class="value" data-bind="i18n: 'See price before order confirmation.'"></span>
                </div>
                <!-- /ko -->
                <!-- ko ifnot: canApplyMsrp -->
                <!-- ko foreach: $parent.getRegion('priceSidebar') -->
                    <!-- ko template: {name: getTemplate(), data: item.product_price, as: 'price'} --><!-- /ko -->
                <!-- /ko -->
                <!-- /ko -->

                <div class="details-qty qty">
                    <label class="label" data-bind="i18n: 'Qty', attr: {
                           for: 'cart-item-'+item_id+'-qty'}"></label>
                    <input data-bind="attr: {
                           id: 'cart-item-'+item_id+'-qty',
                           'data-cart-item': item_id,
                           'data-item-qty': qty,
                           'data-cart-item-id': product_sku
                           }, value: qty"
                           type="number"
                           size="4"
                           class="item-qty cart-item-qty">
                    <button data-bind="attr: {
                           id: 'update-cart-item-'+item_id,
                           'data-cart-item': item_id,
                           title: $t('Update')
                           }"
                            class="update-cart-item"
                            style="display: none">
                        <span data-bind="i18n: 'Update'"></span>
                    </button>
                </div>
            </div>

            <div class="product actions">
                <!-- ko if: is_visible_in_site_visibility -->
                <div class="primary">
                    <a data-bind="attr: {href: configure_url, title: $t('Edit item')}" class="action edit">
                        <span data-bind="i18n: 'Edit'"></span>
                    </a>
                </div>
                <!-- /ko -->
                <div class="secondary">
                    <a href="#" data-bind="attr: {'data-cart-item': item_id, title: $t('Remove item')}"
                       class="action delete">
                        <span data-bind="i18n: 'Remove'"></span>
                    </a>
                </div>
            </div>
        </div>
    </div>
</li>

After adding above code when you run magento commands, your custom attribute (manufacturer name) will display at sidebar Minicart items.

Next, we will going to check how to display additional attribute (manufacturer) on checkout summary section.

Now Create file di.xml inside /app/code/Magelearn/CartAttributes/etc/ folder. 

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Model\DefaultConfigProvider">
        <plugin name="checkout-summary-product-attribs" type="Magelearn\CartAttributes\Plugin\Checkout\Model\DefaultConfigProvider" />
    </type>
</config>

Create DefaultConfigProvider.php file inside app/code/Magelearn/CartAttributes/Plugin/Checkout/Model/ folder.

<?php
namespace Magelearn\CartAttributes\Plugin\Checkout\Model;

use Magento\Checkout\Model\Session as CheckoutSession;

class DefaultConfigProvider
{
    /**
     * @var CheckoutSession
     */
    protected $checkoutSession;

    /**
     * Constructor
     *
     * @param CheckoutSession $checkoutSession
     */
    public function __construct(
        CheckoutSession $checkoutSession
    ) {
        $this->checkoutSession = $checkoutSession;
    }

    public function afterGetConfig(
        \Magento\Checkout\Model\DefaultConfigProvider $subject,
        array $result
    ) {
        $items = $result['totalsData']['items'];
        foreach ($items as $index => $item) {
            $quoteItem = $this->checkoutSession->getQuote()->getItemById($item['item_id']);
            $result['quoteItemData'][$index]['manufacturer'] = $quoteItem->getProduct()->getAttributeText('manufacturer');
        }
        return $result;
    }
}

Create checkout_index_index.xml file inside app/code/Magelearn/CartAttributes/view/frontend/layout folder.

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="sidebar" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="summary" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="cart_items" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="details" xsi:type="array">
                                                            <item name="component"
                                                                  xsi:type="string">Magelearn_CartAttributes/js/view/summary/item/details</item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Now copy the file from vendor/magento/module-checkout/view/frontend/web/js/view/summary/item/details.js and put inside app/code/Magelearn/CartAttributes/view/frontend/web/js/view/summary/item/details.js 

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

define([
    'uiComponent',
    'escaper'
], function (Component, escaper) {
    'use strict';
	var quoteItemData = window.checkoutConfig.quoteItemData;
    return Component.extend({
        defaults: {
            template: 'Magelearn_CartAttributes/summary/item/details',
            allowedTags: ['b', 'strong', 'i', 'em', 'u']
        },
		quoteItemData: quoteItemData,
        /**
         * @param {Object} quoteItem
         * @return {String}
         */
        getNameUnsanitizedHtml: function (quoteItem) {
            var txt = document.createElement('textarea');

            txt.innerHTML = quoteItem.name;

            return escaper.escapeHtml(txt.value, this.allowedTags);
        },

        /**
         * @param {Object} quoteItem
         * @return {String}Magento_Checkout/js/region-updater
         */
        getValue: function (quoteItem) {
            return quoteItem.name;
        },
        getManufacturer: function(quoteItem) {
            var item = this.getItem(quoteItem.item_id);
            return item.manufacturer;
        },
        getItem: function(item_id) {
            var itemElement = null;
            _.each(this.quoteItemData, function(element, index) {
                if (element.item_id == item_id) {
                    itemElement = element;
                }
            });
            return itemElement;
        }
    });
});
Now Create template file details.html inside app/code/Magelearn/CartAttributes/view/frontend/web/template/summary/item folder. by copying file from module-checkout/view/frontend/web/template/summary/item/details.html and add manufacturer name below product name.
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->

<!-- ko foreach: getRegion('before_details') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
<div class="product-item-details">

    <div class="product-item-inner">
        <div class="product-item-name-block">
            <strong class="product-item-name" data-bind="html: getNameUnsanitizedHtml($parent)"></strong>
            <!-- ko if: (getManufacturer($parent))-->
                <strong class="product-item-manufacturer" data-bind="text: getManufacturer($parent)"></strong>
            <!-- /ko -->
            <div class="details-qty">
                <span class="label"><!-- ko i18n: 'Qty' --><!-- /ko --></span>
                <span class="value" data-bind="text: $parent.qty"></span>
            </div>
        </div>
        <!-- ko foreach: getRegion('after_details') -->
            <!-- ko template: getTemplate() --><!-- /ko -->
        <!-- /ko -->
    </div>

    <!-- ko if: (JSON.parse($parent.options).length > 0)-->
    <div class="product options" data-bind="mageInit: {'collapsible':{'openedState': 'active'}}">
        <span data-role="title" class="toggle"><!-- ko i18n: 'View Details' --><!-- /ko --></span>
        <div data-role="content" class="content">
            <strong class="subtitle"><!-- ko i18n: 'Options Details' --><!-- /ko --></strong>
            <dl class="item-options">
                <!--ko foreach: JSON.parse($parent.options)-->
                <dt class="label" data-bind="text: label"></dt>
                    <!-- ko if: ($data.full_view)-->
                    <!-- ko with: {full_viewUnsanitizedHtml: $data.full_view}-->
                    <dd class="values" data-bind="html: full_viewUnsanitizedHtml"></dd>
                    <!-- /ko -->
                    <!-- /ko -->
                    <!-- ko ifnot: ($data.full_view)-->
                    <!-- ko with: {valueUnsanitizedHtml: $data.value}-->
                    <dd class="values" data-bind="html: valueUnsanitizedHtml"></dd>
                    <!-- /ko -->
                    <!-- /ko -->
                <!-- /ko -->
            </dl>
        </div>
    </div>
    <!-- /ko -->
</div>
<!-- ko foreach: getRegion('item_message') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->

Now Run all necessary magento comamnd. After you will see your Manufacturer name will be display in checkout summary box.

Hope this article will help you to modify checkout and minicart page data. 😀

1 Comments On "Display Product attribute in checkout summary and minicart in Magento2"

thanks for this extention...
i want to show custome product attributes on shopping cart page

https://prnt.sc/187fzf2

thanks bhai

Back To Top