22

I'm trying to retrieve the current product's attributes in a block in Magento 2.

I can get a product, like ID 1:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager
               ->create('\Magento\Catalog\Model\ProductRepository')
               ->getById(1);

I don't know how to get the ID of the current product though.

How could I do that?

5
  • u can call function getProduct() in Magento\Catalog\Block\Product\View
    – xanka
    Feb 17 '16 at 9:13
  • where are u want to get current product?
    – Amit Bera
    Feb 17 '16 at 9:27
  • I'm adding a module to show the product's specifications (attributes) in a tab on the product page. Problem solved via $block->getProduct() per answer from Rahil Patel. Feb 17 '16 at 22:26
  • Please check below links mageplaza.com/how-get-current-product-category-magento-2.html You can get current product using registry. Thanks !! Nov 30 '17 at 10:46
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – Jarnail S
    Sep 13 '18 at 10:22
16

In order to get the current product, one of the recommended ways is:

  1. Extend or use block class: Magento\Catalog\Block\Product\View\AbstractView.
  2. Get product using: $block->getProduct() in your phtml file.
8
  • 7
    Or you can try this $this->_coreRegistry->registry('product'); as well!! Feb 17 '16 at 9:15
  • #2 works very well. Not sure why I couldn't figure that out myself. Thanks for your help! Feb 17 '16 at 22:25
  • Could you help as to i get the error in load() to get the product id $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $currentproduct = $objectManager->create('Vendor\Module\Model\Queue')->load($productId);
    – Sushivam
    Aug 22 '16 at 7:13
  • 2
    AbstractView starts with capital A Magento\Catalog\Block\Product\View\AbstractView Jan 11 '17 at 15:14
  • 4
    \Magento\Catalog\Block\Product\View\AbstractView is deprecated Apr 13 '19 at 12:48
36

Although other answers are correct, they're not the recommended/proper solution either.

Using the ObjectManager is absolutely prohibited in Magento 2. So please don't rely on this solution, but use proper DI to achieve this instead. To learn how to use DI in Magento 2, see this resource: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/depend-inj.html

Extending AbstractView is not necessary. If you look at the original function in the AbstractView, you can see Magento used the registry to fetch the product. You don't need to extend a specific class to do this, simply inject Magento\Framework\Registry into your constructor and request the "product" registry item.

Full code example:

<?php

// Example = Module namespace, Module = module name, rest of the namespace is just for example only, change this to whatever it is in your case.
namespace Example\Module\Block\Frontend\Catalog\Product\General;

use Magento\Catalog\Model\Product;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Registry;
use Magento\Framework\View\Element\Template;

class Information extends Template
{

    /**
     * @var Registry
     */
    protected $registry;

    /**
     * @var Product
     */
    private $product;

    public function __construct(Template\Context $context,
                                Registry $registry,
                                array $data)
    {
        $this->registry = $registry;

        parent::__construct($context, $data);
    }


    /**
     * @return Product
     */
    private function getProduct()
    {
        if (is_null($this->product)) {
            $this->product = $this->registry->registry('product');

            if (!$this->product->getId()) {
                throw new LocalizedException(__('Failed to initialize product'));
            }
        }

        return $this->product;
    }

    public function getProductName()
    {
        return $this->getProduct()->getName();
    }

}
7
  • welcome to Magento SE. If you have comments on other answers, please use the "add a comment" link to do so. Please write an answer that stands on it's own as much as possible and don't rely on other answers. Other answers might be deleted or might "disappear" to the lower regions of the page.
    – 7ochem
    Nov 28 '16 at 19:30
  • 1
    @7ochem apologies, it said I wasn't allowed to comment yet, that's why I did it like this, I'll use proper comments in the future. :) Dec 4 '16 at 9:31
  • I already have module and can you please guide how to use your function in my current module? AND i would say, you explanation is best one which i need to implement in my module. Thanks
    – Sharma
    Nov 7 '17 at 6:47
  • Hi Sharma, it's hard to say exactly without seeing the code, but the idea remains the same: in your constructor (the one with 2 underscores), add a new argument and inject Magento\Framework\Registry into your block. Then, use the registry to get the product like this: $this->product = $this->registry->registry('product'); Nov 8 '17 at 7:59
  • 4
    Registry is deprecated and the method of @rafael-corrêa-gomes has to be used instead. Apr 26 '19 at 7:56
18

If you are using Magento 2.1 or major, you can use this helper because the old method was deprecated.

...
use Magento\Catalog\Helper\Data;
...

public function __construct(
        Context $context,
        Data $helper,
        array $data = []
    ){
        $this->context = $context;
        $this->helper = $helper;
        $this->data = $data;
        parent::__construct($context, $data);
    }

...

public function getProduct(){
    if(is_null($this->_product)){
        $this->_product = $this->helper->getProduct();
    }
    return $this->_product;
}
2
  • Does not work in the template Magento_Checkout\templates\cart\item\renderer\actions\edit.phtml
    – Black
    Aug 6 '20 at 13:58
  • 1
    Interestingly, this helper just calls the deprecated registry method :D
    – Luke
    Jul 21 at 13:24
0

@Wesley Vestjens solution worked for me as well. Just make sure to pay attention to the access modifier, as private might not be what you want if you are using getProduct() in your template. In the above example it works as getProductName() is the public method to use.

1
  • 2
    It's generally recommended not to give entire objects to a template, but instead pass the data that it requires and nothing more. That's why getProduct() is private and getProductName() is public. In the newer Magento versions (2.2 / 2.3 and on) these methods are also considered deprecated and View Models should be used instead. Mar 23 '19 at 15:50
0

As mentioned "ObjectManager is absolutely prohibited" and "Registry is deprecated", the following atwix registry alternative appears to represent the current correct approach to the original question by using Service and ViewModel.

https://www.atwix.com/magento-2/alternatives-for-deprecated-registry-class-magento-2-3/

https://github.com/Atwix/atwix-blog-magento2-registry-deprecated-solutions

Get Product Service: https://github.com/Atwix/atwix-blog-magento2-registry-deprecated-solutions/blob/master/app/code/Atwix/RegistryAlternative/Service/GetCurrentProductService.php

1

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.