4

In my magento 2 store I need to return and print a custom product attribute in mini cart for each product in the cart. But it seems data are load using KO js so I have no idea , how to get attribute value please help me

1

Whole minicart rendering process is explained clearly here https://mage2.pro/t/topic/905

Under checkout module, you have CustomerData/Cart.php folder which does the rendering of the cart items. Each items are rendered based on the product type.

So, for Example, if you want to modify configurable product, go to configurable product module CustomerData folder.

For simple products, you need to look into the checkout module CustomerData/DefaultItem.php doGetItemData() To load Custom attributes over there and pass it as additional JSON param, you can load the product obj and get the value

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productObj = $objectManager->get('Magento\Catalog\Model\Product')->load($product_id);
$short_desc = $productObj->getShortDescription();

You need to rewrite the Core modules to add your custom attribute values on minicart.

0

For displaying product attribute in minicart

1. Create file catalog_attributes.xml Vendor/Module/etc

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

2.Create di.xml in Vendor/Module/etc

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
   <preference for="Magento\Checkout\CustomerData\DefaultItem" type="Vendor\Module\CustomerData\DefaultItem" />
</config>

3.Create file DefaultItem.php inside Vendor\Module\CustomerData

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

namespace Vendor\Module\CustomerData;

use Magento\Framework\App\ObjectManager;

/**
 * Default item
 */
class DefaultItem extends \Magento\Checkout\CustomerData\DefaultItem
{
         /**
         * @var \Magento\Catalog\Helper\Image
         */
        protected $imageHelper;

        /**
         * @var \Magento\Msrp\Helper\Data
         */
        protected $msrpHelper;

        /**
         * @var \Magento\Framework\UrlInterface
         */
        protected $urlBuilder;

        /**
         * @var \Magento\Catalog\Helper\Product\ConfigurationPool
         */
        protected $configurationPool;

        /**
         * @var \Magento\Checkout\Helper\Data
         */
        protected $checkoutHelper;

        /**
         * Escaper
         *
         * @var \Magento\Framework\Escaper
         */
        private $escaper;
    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\Framework\Escaper $escaper = null
    ) {
        $this->configurationPool = $configurationPool;
        $this->imageHelper = $imageHelper;
        $this->msrpHelper = $msrpHelper;
        $this->urlBuilder = $urlBuilder;
        $this->checkoutHelper = $checkoutHelper;
        $this->escaper = $escaper ?: ObjectManager::getInstance()->get(\Magento\Framework\Escaper::class);
    }

    protected function doGetItemData()
    {
        $imageHelper = $this->imageHelper->init($this->getProductForThumbnail(), 'mini_cart_product_thumbnail');
        $productName = $this->escaper->escapeHtml($this->item->getProduct()->getName());

        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_id' => $this->item->getProduct()->getId(),
            'product_name' => $productName,
            'product_sku' => $this->item->getProduct()->getSku(),
            'product_url' => $this->getProductUrl(),
            'product_has_url' => $this->hasProductUrl(),
            'product_price' => $this->checkoutHelper->formatPrice($this->item->getCalculationPrice()),
            'product_price_value' => $this->item->getCalculationPrice(),
            'product-attribute' => $this->item->getProduct()->getProductAttribute(),
            'product_image' => [
                'src' => $imageHelper->getUrl(),
                'alt' => $imageHelper->getLabel(),
                'width' => $imageHelper->getWidth(),
                'height' => $imageHelper->getHeight(),
            ],
            'canApplyMsrp' => $this->msrpHelper->isShowBeforeOrderConfirm($this->item->getProduct())
                && $this->msrpHelper->isMinimalPriceLessMsrp($this->item->getProduct()),
        ];
    }

}
?>

4.Create File defualt.html inside Current Theme app/design/frontend/Vendor/Themename/Magento_Checkout/web/template/minicart/item

<!--
/**
 * 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 -->
            </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 ifnot: Array.isArray(option.value) -->
                                <span data-bind="html: option.value"></span>
                            <!-- /ko -->
                        </dd>
                        <!-- /ko -->
                    </dl>
                </div>
            </div>
            <!-- /ko -->
            <!-- ko if: product-attribute -->
            <div data-bind="html: 'Product Attribute : ' + product-attribute"></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>
  • This isn't the correct way to do this. You can't overwritte protected method with di.xml preference. He needs to create plugin for Magento\Checkout\CustomerData\AbstractItem::getItemData() which calls doGetItemData() to modify it – Trenox Oct 18 '18 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.