I had to do a custom mini cart in Magento 2 to make it match the requirements of our client. Magento 2 mini cart bases on HTML-template loaded and filled by the Knockout js-library. This task is quite complicated, especially for the beginners who haven’t got enough Magento 2 expertise. That’s why I decided to share with you some Magento 2 mini cart issues.
Magento 2 Mini Cart Issues
Knockout js-library Knockout allows using html-templates instead of phtml-templates. Unfortunately, the visibility of the html-templates is worse than the visibility of phtml-templates. Look at the next part of minicart.phtml template that displays a mini cart block on the screen:
<div id="minicart-content-wrapper" data-bind="scope: 'minicart_content'"> <!-- ko template: getTemplate() --><!-- /ko --> </div>
The situation becomes more complicated when you reveal that there is no getTemplate() function in the js-scripts of the Magento_Checkout module.
First of all, you have to determine which UI-element Knockout uses for the DIV element. This part of the task is easy, as the required UI-element scope is specified directly in the data-bind attribute. In this case, you can also use debugging methods. I’ll describe them below.
Now we know that UI-element named minicart_content calls getTemplate() function. Our next step is to open the page source code and find the script that describes minicart_content and its child elements.
<script type="text/x-magento-init"> { "[data-block='minicart']": { "Magento_Ui/js/core/app": {"components":{"minicart_content":{"children":{"subtotal.container":{"children":{"subtotal":{"children":{"subtotal.totals": {"config":{"display_cart_subtotal_incl_tax":0,"display_cart_subtotal_excl_tax":1,"template":"Magento_Tax\/checkout\/minicart\/subtotal\/totals"},"children": {"subtotal.totals.msrp":{"component":"Magento_Msrp\/js\/view\/checkout\/minicart\/subtotal\/totals","config": {"displayArea":"minicart-subtotal-hidden","template":"Magento_Msrp\/checkout\/minicart\/subtotal\/totals"}}}, "component":"Magento_Tax\/js\/view\/checkout\/minicart\/subtotal\/totals"}},"component":"uiComponent","config": {"template":"Magento_Checkout\/minicart\/subtotal"}}},"component":"uiComponent","config":{"displayArea":"subtotalContainer"}},"item.renderer": {"component":"uiComponent","config":{"displayArea":"defaultRenderer","template":"Magento_Checkout\/minicart\/item\/default"},"children":{"item.image": {"component":"Magento_Catalog\/js\/view\/image","config":{"template":"Magento_Catalog\/product\/image","displayArea":"itemImage"}}, "checkout.cart.item.price.sidebar":{"component":"uiComponent","config": {"template":"Magento_Checkout\/minicart\/item\/price","displayArea":"priceSidebar"}}}},"extra_info":{"component":"uiComponent","config": {"displayArea":"extraInfo"}},"promotion":{"component":"uiComponent","config":{"displayArea":"promotion"}}},"config":{"itemRenderer": {"default":"defaultRenderer","simple":"defaultRenderer","virtual":"defaultRenderer"},"template":"Magento_Checkout\/minicart\/content"},"component": "Magento_Checkout\/js\/view\/minicart"}},"types":[]} }, "*": { "Magento_Ui/js/block-loader": "http://et.magenmagic.com/static/version1500468461/frontend/Magenmagic/ettage/en_US/images/loader-1.gif" } } </script>
There is an htmpl-template description which will be returned when the getTemplate() function is called:
"template":"Magento_Checkout\/minicart\/content"
In this case, it means that the required template locates in vendor/magento/module-checkout/view/frontend/web/template/minicart/content.html
Debugging Methods
The hardest part of working with an html-template is that it doesn’t contain any information about UI-element that is used by the Knockout library for this template.
Phtml-templates also won’t provide you with this information. You don’t need to analyze configuration files to reveal it. All you need is to set a breakpoint in the template, enable the debugger and check the block that hides under the variable $this.
Setting a breakpoint in the html-template isn’t a suitable method since the Knockout library fills templates with information. In this case, the breakpoint won’t work.
I’ll share with you some other debugging methods, which don’t require exhausting Magento configuration and files examining.
Debugging Method #1
The first method is to insert a console.log command into the data-bind attribute.
Let’s take a look at it in html-template vendor/magento/module-checkout/view/frontend/web/template/minicart/content.html:
<div class="block-content"> <button type="button" id="btn-minicart-close" class="action close" data-action="close" data-bind="attr: { title: $t('Close') }"> <span translate="'Close'"/> </button> <if args="getCartParam('summary_count')"> <div class="items-total">
Here is the block <if args=”getCartParam(‘summary_count’)”>
The block <if> inside the div-element <div class=”block-content”> is a Magento invention. It equals the Knockout command <!– ko if: getCartParam(‘summary_count’) –>
We need to find the UI-element that calls the getCartParam method. It’s time to insert the console.log command into the data-bind attribute.
We rewrite the code line in the following way:
<div class="block-content" data-bind="uniqueName: console.log($data)"> <button type="button" id="btn-minicart-close" class="action close" data-action="close" data-bind="attr: { title: $t('Close') }"> <span translate="'Close'"/> </button> <if args="getCartParam('summary_count')"> <div class="items-total">
We change only the first line. As a result, we see the next info in a browser console while the page load:
- UiClass {_super: undefined, ignoreTmpls: {…}, _requesetd: {…}, containers: Array(0), exports: {…}, …}
- component:”Magento_Checkout/js/view/minicart”
- containers:[]
- dataScope:””
- elems:ƒ observable()
- exports:{}
- extendProvider:true
- hasUnique:undefined
- ignoreTmpls:{templates: true, childDefaults: true}
- imports:{}
- index:”minicart_content”
- initChildCount:4
- itemRenderer:{default: “defaultRenderer”, simple: “defaultRenderer”, virtual: “defaultRenderer”}
- links:{}
- listens:{}
- maps:{imports: {…}, exports: {…}}
- modules:{storage: “localStorage”}
- name:”minicart_content”
- ns:”minicart_content”
- parentName:””
- parentScope:””
- provider:””
- regions:{subtotalContainer: ƒ, defaultRenderer: ƒ, extraInfo: ƒ, promotion: ƒ, sign-in-popup: ƒ}
- registerNodes:true
- source:undefined
- statefull:{}
- storage:ƒ ()
- storageConfig:{provider: “localStorage”, namespace: “minicart_content”, path: “localStorage:minicart_content”}
- template:”Magento_Checkout/minicart/content”
- tracks:{}
- _elems:(4) [UiClass, UiClass, UiClass, UiClass]
- _requesetd:{localStorage: ƒ}
- _super:undefined
__proto__:UiClass
Now we have the detailed info on UI-element that fills the html-template with data. This UI-element calls the getCartParam (‘summary_count’) method.
At last, we need to check the result that the method’s calling returns.
Debugging Method #2
We know about the UI-element and we need to check the returning result of the getCartParam method.
We need a link to the UI-element to do it. All of UI-elements links are stored in the registry. Run the reg = requirejs(‘uiRegistry’); command in your browser.
After the debugging info analysis on the UI-element, we see the line: index:“minicart_content“
We can easily get the link to the UI-element in the registry using this index. Run the command in your browser: longDesiredReference = reg.get(‘minicart_content’)
Now, we can test the calling of any method of the UI-element in a browser, including the getCartParam: longDesiredReference.getCartParam(‘summary_count’) method
Extra information
As we saw in the example of using the <if args=”getCartParam(‘summary_count’)”> element, Magento developers decided to extend the capabilities of calling Knockout library with the new elements.
Using these elements isn’t a necessity. You can use standard Knockout elements like <!– ko if: getCartParam(‘summary_count’) –>
Nevertheless, Magento elements look better on an IDE screen because they are more contrast than standard Knockout elements.
If you need more info about Magento 2 and Knockout integration check Alan Storm’s article.
Magento 2 Mini Cart Configuration in the Admin Panel
If you want to customize your mini cart, check its configuration in the admin panel first. You may find out that you don’t need extra features.
To configure your mini cart go tap Stores on the admin sidebarar> Configuration> Sales> Checkout> expand Shopping Cart Sidebar.
Here you can set Number of Items to Display Scrollbar and Maximum Number of Items to Display.
For example, if you set a value 4 for both fields, you get this:
Mobecls team provides a wide range of eCommerce development services, starting from SEO and design to custom eCommerce development. Our 10+ years of Magento expertise allow us to provide unique eCommerce solutions taking into account industry and business specifics. If you want to take your business to the next level, we’re ready to help!