Getting the product SKU in the header mini-cart
As far as I know, the header minicart will get the data from customer data
vendor/magento/module-checkout/view/frontend/web/js/view/minicart.js
define([
'uiComponent',
'Magento_Customer/js/customer-data',
'jquery',
'ko',
'sidebar'
], function (Component, customerData, $, ko) {
'use strict';
......
this.cart = customerData.get('cart');
......
}
Look into the customer data js vendor/magento/module-customer/view/frontend/web/js/customer-data.js
, we can get the customer data from local storage. For example, in your browser console, run the line: localStorage.getItem('mage-cache-storage')
, we also can get the cart information.
{
"cart": {
"summary_count": 1,
....
"items": [
{
......
"qty": 1,
"item_id": "11728",
"configure_url": "http://magento2-demo/checkout/cart/configure/id/11728/product_id/1817/",
"is_visible_in_site_visibility": true,
"product_name": "Breathe-Easy Tank",
"product_url": "http://magento2-demo/breathe-easy-tank.html",
"product_has_url": true,
"canApplyMsrp": false
}
],
.......
}
}
Navigate to vendor/magento/module-checkout/CustomerData/DefaultItem.php
protected function doGetItemData()
{
.......
return [
'options' => $this->getOptionList(),
'qty' => $this->item->getQty() * 1,
'item_id' => $this->item->getId(),
'configure_url' => $this->getConfigureUrl(),
'is_visible_in_site_visibility' => $this->item->getProduct()->isVisibleInSiteVisibility(),
'product_name' => $this->item->getProduct()->getName(),
'product_url' => $this->getProductUrl(),
'product_has_url' => $this->hasProductUrl(),
.....
}
vendor/magento/module-checkout/CustomerData/AbstractItem.php
/**
* {@inheritdoc}
*/
public function getItemData(Item $item)
{
$this->item = $item;
return \array_merge(
['product_type' => $item->getProductType()],
$this->doGetItemData()
);
}
To get the SKU item, I think we need to add data to getItemData()
(Should try with Plugin). And then override the template html vendor/magento/module-checkout/view/frontend/web/template/minicart/item/default.html
<div class="product-item-details">
<!-- ko text: product_sku --><!-- /ko -->
Update Magento 2.1.0 version
In the Magento 2.1.0, you only need to override default.html
. This is because the method doGetItemData
has already the product sku.
Firstly, very good explanation from @Khoa TruongDinh about the flow of getting item in minicart template.
how can I change them around to add or remove product details?
I found a way how you can extend minicart template with custom attributes of the product. To do that first you need to override vendor/magento/module-checkout/CustomerData/DefaultItem.php with DI Preferences
Create app/code/Vendor/Module/etc/di.xml ot override DefaultItem object
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Checkout\CustomerData\DefaultItem" type="Vendor\Module\Preferences\MiniCartItem" />
</config>
Then create new object to override doGetItemData() method and add custom_attribute with key product_custom_attribute
File: app/code/Vendor/Module/Preferences/MiniCartItem.php
namespace Vendor\Module\Preferences;
class MiniCartItem extends \Magento\Checkout\CustomerData\DefaultItem
{
public function __construct(
\Magento\Catalog\Helper\Image $imageHelper,
\Magento\Msrp\Helper\Data $msrpHelper,
\Magento\Framework\UrlInterface $urlBuilder,
\Magento\Catalog\Helper\Product\ConfigurationPool $configurationPool,
\Magento\Checkout\Helper\Data $checkoutHelper,
\Magento\Catalog\Helper\Output $helper,
\Magento\Catalog\Model\Product $productModel
) {
$this->configurationPool = $configurationPool;
$this->imageHelper = $imageHelper;
$this->msrpHelper = $msrpHelper;
$this->urlBuilder = $urlBuilder;
$this->checkoutHelper = $checkoutHelper;
$this->helper = $helper;
$this->productModel = $productModel;
}
/**
* {@inheritdoc}
*/
protected function doGetItemData()
{
$imageHelper = $this->imageHelper->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail');
$product = $this->productModel->load($this->item->getProduct()->getId());
return [
'options' => $this->getOptionList(),
'qty' => $this->item->getQty() * 1,
'item_id' => $this->item->getId(),
'configure_url' => $this->getConfigureUrl(),
'is_visible_in_site_visibility' => $this->item->getProduct()->isVisibleInSiteVisibility(),
'product_name' => $this->item->getProduct()->getName(),
'product_url' => $this->getProductUrl(),
'product_has_url' => $this->hasProductUrl(),
'product_price' => $this->checkoutHelper->formatPrice($this->item->getCalculationPrice()),
'product_image' => [
'src' => $imageHelper->getUrl(),
'alt' => $imageHelper->getLabel(),
'width' => $imageHelper->getWidth(),
'height' => $imageHelper->getHeight(),
],
'product_custom_attribute' => $this->helper->productAttribute($product, $product->getCustomAttribute(), 'custom_attribute'),
'canApplyMsrp' => $this->msrpHelper->isShowBeforeOrderConfirm($this->item->getProduct())
&& $this->msrpHelper->isMinimalPriceLessMsrp($this->item->getProduct()),
];
}
}
Notice that I am injecting
\Magento\Catalog\Model\Product $productModel
to the construct method because I need to load full product data to access my custom_attribute. If there is a better way please tell me.
And finally you can display the new attribute in
view/frontend/web/template/minicart/item/default.html:
<div class="product-item-details">
<!-- ko text: product_custom_attribute --><!-- /ko -->