Magento 2: Display Custom Product Attribute in Checkout Summary

In this blog, I am going to show you how to display custom product attribute in the checkout summary.

In the below example, we will display the product’s brand under the product’s name in the checkout summary.

Step 1: Define a new module,

Create a module.xml file in the below file path to define the new module,

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/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="MyModule_CheckoutSummary" setup_version="1.0.0">
    </module>
</config>

Next, create a registration.php file in the below file path,

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'MyModule_CheckoutSummary',
    __DIR__
);

Step 2: create a file catalog_attributes.xml in the following path

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/etc/frontend/catalog_attributes.xml

In this XML file, we have to include the product’s brand attribute in the quote item, which is not included by default.

<?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="brand" />
    </group>
</config>

Step 3: create a file di.xml in the following path

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/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\Checkout\Model\DefaultConfigProvider">
        <plugin name="checkout-summary-product-attribute" type="MyModule\CheckoutSummary\Plugin\Checkout\Model\DefaultConfigProviderPlugin" />
    </type>
</config>

In the above XML file, we have included the class Magento\Checkout\Model\DefaultConfigProvider which is used to retrieving data in checkout. You can find this class file in the path <Magento_2_Root>/vendor/magento/module-checkout/Model/DefaultConfigProvider.php. In this class, the function getConfig() is returning an array of data which is gonna used in different places in checkout. In this function, we have to include the product’s brand in the array “quoteItemData”.

Step 4: create a file DefaultConfigProviderPlugin.php in the following path

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/Plugin/Checkout/Model/DefaultConfigProvider.php

In this file, create a function afterGetConfig(), where we will add our logic to add the product’s brand information.

<?php
namespace MyModule\CheckoutSummary\Plugin\Checkout\Model;

use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Catalog\Model\ProductRepository as ProductRepository;

class DefaultConfigProviderPlugin extends \Magento\Framework\Model\AbstractModel
{
    protected $checkoutSession;

    protected $_productRepository;

    public function __construct(
        CheckoutSession $checkoutSession,
        ProductRepository $productRepository
    ) {
        $this->checkoutSession = $checkoutSession;
        $this->_productRepository = $productRepository;
    }

    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']);
            $product = $this->_productRepository->getById($quoteItem->getProduct()->getId());
            $result['quoteItemData'][$index]['brand'] = $product->getResource()->getAttribute('brand')->getFrontend()->getValue($product);
        }
        return $result;
    }
}

Step 5: create a file checkout_index_index.xml file in the following path

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/view/frontend/layout/checkout_index_index.xml

We all know that Magento 2 checkout is built up from a series of Knockout JS components. Magento 2 defines each one of these components and their parent/child relationship in a large XML file. So we have to override this in our own theme or module as follows,

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" 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">MyModule_CheckoutSummary/js/view/summary/item/details</item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

The above code is used to load the details.js file from our module instead of core.

Step 6: create a file details.js file in the following path

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/view/frontend/web/js/view/summary/item/details.js

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

define(
    [
        'uiComponent'
    ],
    function (Component) {
        "use strict";
        var quoteItemData = window.checkoutConfig.quoteItemData;
        return Component.extend({
        defaults: {
            template: 'MyModule_CheckoutSummary/summary/item/details'
        },
        quoteItemData: quoteItemData,
        getValue: function(quoteItem) {
            return quoteItem.name;
        },
        getBrand: function(quoteItem) {
            var item = this.getItem(quoteItem.item_id);
            return item.brand;
        },
        getItem: function(item_id) {
            var itemElement = null;
            _.each(this.quoteItemData, function(element, index) {
                if(element.item_id == item_id) {
                    itemElement = element;
                }
            })
            return itemElement;
        }
    });
});

The above code is used to load the template file details.html from our module instead of core.

You can find the original details.js file in the path <Magento_2_Root>/vendor/magento/module-checkout/view/frontend/web/js/view/summary/item/details.js.

Step 7: create a file details.html file in the following path

File Path: <Magento_2_Root> /app/code/MyModule/CheckoutSummary/view/frontend/web/template/summary/item/details.html

<!--
/**
 * Copyright © 2013-2017 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="text: $parent.name"></strong>

            <!-- ko if: (getBrand($parent)) -->
            <div class="product-item-brand">
                <span class="label"><!-- ko i18n: 'Brand:' --><!-- /ko --></span>
                <span class="value" data-bind="text: getBrand($parent)"></span>
            </div>
            <!-- /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)-->
                     <dd class="values" data-bind="html: full_view"></dd>
                 <!-- /ko -->
                 <!-- ko ifnot: ($data.full_view)-->
                     <dd class="values" data-bind="html: value"></dd>
                 <!-- /ko -->
             <!-- /ko -->
             </dl>
        </div>
    </div>
<!-- /ko -->
</div>

You can find the original details.html file in the path <Magento_2_Root>/vendor/magento/module-checkout/view/frontend/web/template/summary/item/details.html.

Finally, you can see the product’s brand name on the checkout summary as follows,

Magento 2: Display Custom Product Attribute in Checkout Summary

Hope this helps.

Leave a Reply

Your email address will not be published. Required fields are marked *