13

How can i get current category in magento2 ?

I want to get category name and category id in custom phtml file.

Makwana Ketan
  • 1,380
  • 1
  • 14
  • 22
  • Most of the answers here use the `Registry` class, which is deprecated since a while. Is there a way without using `Registry`? – jrswgtr Oct 06 '20 at 12:01

5 Answers5

26

The above to seem correct, but I think that jumping straight to the Registry is not the best approach. Magento provides a Layer Resolver that already encapsulates that functionality. (See the TopMenu Block in the Catalog Plugins)

I suggest injecting the \Magento\Catalog\Model\Layer\Resolver class and using that to get the current category. Here is the code :

<?php

namespace FooBar\Demo\Block;

class Demo extends \Magento\Framework\View\Element\Template
{
    private $layerResolver;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        array $data = []
    ) {
        parent::__construct($context, $data);

        $this->layerResolver = $layerResolver;
    }

    public function getCurrentCategory()
    {
        return $this->layerResolver->get()->getCurrentCategory();
    }
}

Here is what the actual getCurrentCategory() method does in the Resolver Class.

public function getCurrentCategory()
{
    $category = $this->getData('current_category');
    if ($category === null) {
        $category = $this->registry->registry('current_category');
        if ($category) {
            $this->setData('current_category', $category);
        } else {
            $category = $this->categoryRepository->get($this->getCurrentStore()->getRootCategoryId());
            $this->setData('current_category', $category);
        }
    }

    return $category;
}

As you can see, it does still use the registry but it provides a fallback in case that fails.

drew7721
  • 1,622
  • 18
  • 20
  • 2
    +1 for not reinventing the wheel! It isn't *exactly* what the OP asked for, but it's probably a better solution than the other answers due to the fallback mechanism. I know it was for me. – Eric Seastrand Dec 29 '17 at 13:21
15

Magento sets registry for categories being accessed. So, to get currenct category, use following method:

/**
 * @param \Magento\Framework\Registry $registry
 */

protected $_registry;

public function __construct(
    \Magento\Framework\Registry $registry
) {
    $this->_registry = $registry;
}

and then use:

$category = $this->_registry->registry('current_category');//get current category

Now you can access the collection and fetch details such as $category->getName()

Manish Joy
  • 476
  • 3
  • 17
10

No need to use the object manager or inject class. You can use a built-in helper class Magento\Catalog\Helper\Data in the following way.

<?php 
    $catalogHelperData = $this->helper('Magento\Catalog\Helper\Data');
    $categoryObject = $catalogHelperData->getCategory();
    $categoryId = $categoryObject->getId();
    $categoryName = $categoryObject->getName();
?>

This code snippet should work for any phtml (built-in or custom) file which is related to product listing page or product detail page.

Milan Chandro
  • 2,342
  • 1
  • 18
  • 25
9

Try this code. this will definitely help you.

<?php 
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');//get current category
    echo $category->getId();
    echo $category->getName();
?>
Makwana Ketan
  • 1,380
  • 1
  • 14
  • 22
  • Thanks @Makwana Ketan – Nikunj Vadariya Jun 13 '16 at 13:14
  • 12
    Doesn't respect dependency injection principle – Yonn Trimoreau Mar 03 '17 at 09:33
  • 2
    Any reason for flagging my comment out ? @Makwana, you should better learn from your mistakes and share good practises (maybe fix your answer) instead of bullying people like this – Yonn Trimoreau Apr 10 '17 at 07:16
  • 2
    I agree with @YonnTrimoreau you should follow dependency injection principles. Using object manager directly is a bad practice – Macas Apr 12 '17 at 14:56
  • 2
    Yup, it's really bad practice to use the OM directly like this. From [official Magento dev docs](http://devdocs.magento.com/guides/v2.0/extension-dev-guide/object-manager.html) - Magento prohibits the direct use of the ObjectManager in your code because it hides the real dependencies of a class. – Josh Davenport-Smith Apr 18 '17 at 16:34
  • 2
    well, it will work fine. But use of objectManager in Magento is not appreciated. – Manish Joy Jun 27 '17 at 06:44
  • Object manger should not be used here, follow DI principles – PRashant PUrohit Aug 24 '21 at 10:00
  • This answer really needs a clear disclaimer explaining the caveats as it's bad practice and a commonly found characteristic in stores suffering from stability and performance problems. Currently, it teaches developers bad practices, despite the all the comments below. A template should only use what the block provides, if the block does not provide it, you extend, alter, etc. the block so you can call it. I would only allow this as a fallback for critical functionality, a last resort. – FROSIT Mar 08 '23 at 22:14
0

In *.phtml files at Category page can get Category data with following snippet:

$currentCategory = $this->helper('Magento\Catalog\Helper\Data')->getCategory();
Alex
  • 769
  • 1
  • 11
  • 18