Login Contact Us
My cart

Adding a new field to the mini cart in Magento 2 - tutorial

Feb 13, 2020
by Mexbs Team
Magento Tutorials

In this tutorial, we will add a new field "Discount" to the mini cart. That is, if the customer got a discount in his cart, he would now be able to see it in the mini cart.

For example, we created a cart rule that applies a 10% discount on bags.

Here is how the current mini cart looks like with the cart rule applied -

You can see that the discount doesn’t show up in the mini cart, even though it was applied in the cart -

And here is how it will look after our changes -

So let’s go ahead and create our module.

Step 1: Create the basic file structure for your module

Here is how our module’s file structure will look like -

Create the folder app/code/Myvendor/Mymodule and add the following files:
app/code/Myvendor/Mymodule/etc/module.xml
With the following contents:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Myvendor_Mymodule" setup_version="1.0.0" />
</config>

app/code/Myvendor/Mymodule/registration.php
With the following contents:

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

Now when you have the basic module structure, lets proceed to the actual files that will add the "Discount" field to the mini cart.

Step 2: Add the new minicart field to the layout xml file and create the template files

Create a file
app/code/Myvendor/Mymodule/view/frontend/layout/checkout_cart_sidebar_item_renderers.xml
With the following contents:

<?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="discount.container" xsi:type="array">
                                    <item name="component" xsi:type="string">uiComponent</item>
                                    <item name="config" xsi:type="array">
                                        <item name="displayArea" xsi:type="string">subtotalContainer</item>
                                    </item>
                                    <item name="children" xsi:type="array">
                                        <item name="subtotal" xsi:type="array">
                                            <item name="component" xsi:type="string">Magento_Checkout/js/view/checkout/minicart/subtotal/totals</item>
                                            <item name="config" xsi:type="array">
                                                <item name="template" xsi:type="string">Myvendor_Mymodule/minicart/discount</item>
                                            </item>
                                            <item name="children" xsi:type="array">
                                                <item name="subtotal.totals" xsi:type="array">
                                                    <item name="component" xsi:type="string">Magento_Checkout/js/view/checkout/minicart/subtotal/totals</item>
                                                    <item name="config" xsi:type="array">
                                                        <item name="template" xsi:type="string">Myvendor_Mymodule/minicart/discount/inner</item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

This file tells Magento to add the “Discount” as a child in the minicart and sets our template files to it. Now let's add the template files.

Create the file
app/code/Myvendor/Mymodule/view/frontend/web/template/minicart/discount.html with the following content:

<!-- ko if: (cart().discount_amount_no_html < 0) -->
<div class="subtotal">
    <span class="label">
        <!-- ko i18n: 'Discount' --><!-- /ko -->
    </span>

    <!-- ko foreach: elems -->
    <!-- ko template: getTemplate() --><!-- /ko -->
    <!-- /ko -->
</div>
<!-- /ko -->

Create the file app/code/Myvendor/Mymodule/view/frontend/web/template/minicart/discount/inner.html with the following content:

<div class="amount price-container">
    <span class="price-wrapper" data-bind="html: cart().discount_amount"></span>
</div>

Step 3: Provide the value of the new field to be fetched on the frontend

Now the only thing left to do is to provide the value of the “Discount” field to the class \Magento\Checkout\CustomerData\Cart that will be fetched by the minicart on the frontend. To do that, we will use a plugin.

Create the file app/code/Myvendor/Mymodule/etc/di.xml with the following content:

<?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\Cart">         <plugin name="cartPrivateDataDiscount" type="Myvendor\Mymodule\Plugin\Checkout\CustomerData\Cart"/>     </type> </config>

Create the file app/code/Myvendor/Mymodule/Plugin/Checkout/CustomerData/Cart.php with the following content:

<?php
namespace Myvendor\Mymodule\Plugin\Checkout\CustomerData;

class Cart
{
    protected $checkoutSession;
    protected $checkoutHelper;
    protected $quote;

    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Checkout\Helper\Data $checkoutHelper
    ) {
        $this->checkoutSession = $checkoutSession;
        $this->checkoutHelper = $checkoutHelper;
    }
    
    /**
     * Get active quote
     *
     * @return \Magento\Quote\Model\Quote
     */
    protected function getQuote()
    {
        if (null === $this->quote) {
            $this->quote = $this->checkoutSession->getQuote();
        }
        return $this->quote;
    }

    protected function getDiscountAmount()
    {
        $discountAmount = 0;
        foreach($this->getQuote()->getAllVisibleItems() as $item){
            $discountAmount += ($item->getDiscountAmount() ? $item->getDiscountAmount() : 0);
        }
        return $discountAmount;
    }

    public function afterGetSectionData(\Magento\Checkout\CustomerData\Cart $subject, $result)
    {
        $result['discount_amount_no_html'] = -$this->getDiscountAmount();
        $result['discount_amount'] = $this->checkoutHelper->formatPrice(-$this->getDiscountAmount());

        return $result;
    }
}

Testing the module

Now it’s time to test our module.

First, create a cart rule that gives us a 10% discount on the product from the “Bags” category. Afterward, install the module by running the following commands in your SSH:

php bin/magento module:enable Myvendor_Mymodule --clear-static-content
php bin/magento setup:upgrade


If you running Magento on the default or a developer mode, run the following commands:

php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush


Otherwise, if you running Magento on the production mode, run the following commands:

php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
php bin/magento cache:flush


Now try adding a bag to your cart. You should be able to see the discount line in the minicart -

Summing up

In this tutorial, we demonstrated how to add a new field to the mini cart.

Although Magento 2 is quite sophisticated to develop on, once you know how to do that, it is quite easy. Also, the implementations for features on Magento 2 are usually quite elegant because of Magento 2 sophisticated architecture.