8

I'm trying to get the URL key of any given category with the ID. I have this;

$categoryId = 3;
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$object_manager = $_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
print_r($object_manager->getData());

And this works (in the print_r there is the URL key I need), but category #3 is the top-level category. Whenever I try any subcategory (say ID 5) I get a blank array. I'm just lost for words, can't figure it out.

In Magento 1.x I used to do this: Mage::getModel('catalog/category')->load($catID)->getUrl() and that worked.

TL;DR: This code works, change the ID to a (correct) category ID and change getData() to getUrl() for the complete category url, or getName() for the category name.

22

In order to get the category url you need to use the \Magento\Catalog\Model\Category function getUrl() like so:

$category->getUrl()

Also, you can get url by CategoryRepositoryInterface

nameSpace ['Your_nameSpace'] 
use Magento\Catalog\Api\CategoryRepositoryInterface;
class ['Your_Class_name']
    protected $_storeManager;
    protected $categoryRepository;
    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\CategoryRepository $categoryRepository,
    ) {
        .........
        $this->_storeManager = $storeManager;
        $this->categoryRepository = $categoryRepository;
    }

     public  function getCategory()
    {
            $category = $this->categoryRepository->get($categoryId, $this->_storeManager->getStore()->getId());

        return $category->getUrl();
    }
} 
  • Thank you :) Changing getData to getUrl was the right call. – Alex Timmer Aug 5 '16 at 6:08
  • Working fine, Up voted for you – Pushpendra Singh Oct 16 '17 at 11:34
  • Good answer, very helpful. +1 – Shoaib Munir Apr 2 at 4:31
11

Always try to use repository. You need to inject following way:

/**
 * @var \Magento\Catalog\Helper\Category
 */
protected $categoryHelper;

/**
 * @var \Magento\Catalog\Model\CategoryRepository
 */
protected $categoryRepository;


public function __construct(
    \Magento\Catalog\Helper\Category $categoryHelper,
    \Magento\Catalog\Model\CategoryRepository $categoryRepository,

) {
    $this->categoryHelper = $categoryHelper;
    $this->categoryRepository = $categoryRepository;
}

For category url

$categoryId = 3;
$categoryObj = $this->categoryRepository->get($categoryId);
echo  $this->categoryHelper->getCategoryUrl($categoryObj);
  • Awesome, thank you. I was attempting to loop through IDs with the CategoryModel which was reloading the same data through iterations. You saved me after a bunch of head scratching! – domdambrogia Apr 9 '18 at 17:32
4

You can try below code.

$categoryId = 5;
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$object_manager = $_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
echo "<pre>";
print_r($object_manager->getData());

Before you use a category id you have confirm category id exists in admin or it will return an empty array.

Let me know if you have any questions.

  • Uh yeah, that's the exact code I wrote in the OP. But you are correct, I tried on some ID's that I thought existed, but didn't. – Alex Timmer Aug 5 '16 at 6:07
1

I found that when I need category urls from different domains (per store view), I had to create a new Url object per store view.

use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\Framework\UrlFactory;

class CacheWarmer
{
    /** @var CollectionFactory */
    protected $categoryCollectionFactory;

    /** @var \Magento\Store\Model\StoreManagerInterface */
    protected $storeManager;

    /** @var UrlFactory */
    protected $urlFactory;

    public function __construct(
        CollectionFactory $categoryCollectionFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        UrlFactory $urlFactory
    )
    {
        $this->categoryCollectionFactory = $categoryCollectionFactory;
        $this->storeManager = $storeManager;
        $this->urlFactory = $urlFactory;
    }

    /**
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function execute()
    {
        $stores = $this->storeManager->getStores();

        foreach ($stores as $store) {

            $this->storeManager->setCurrentStore($store);

            $collection = $this->categoryCollectionFactory->create();
            $collection->addUrlRewriteToResult();
            $collection->addIsActiveFilter();

            $urlCreator = $this->urlFactory->create();

            /** @var Category $category */
            foreach ($collection as $category) {

                $requestPath = $category->getRequestPath();
                if (!$requestPath) {
                    continue;
                }

                $url = $urlCreator->getDirectUrl($category->getRequestPath());

                $result = @file_get_contents($url);
            }
        }
    }
}
0

This works fine on my custom block (using category repository and DI):

/**
 * Constructor
 */
public function __construct(
  \Magento\Catalog\Model\CategoryRepository $categoryRepository,
  // ...
) 
{
  $this->_categoryRepository = $categoryRepository;
  // ...
}


/**
 * Return the category object by its id.
 * 
 * @param categoryId (Integer)
 */
public function getCategory($categoryId)
{
  return $this->getCategoryRepository()->get($categoryId);
}


/**
 * Category repository object
 */
protected $_categoryRepository;

Finally, within a template file I just use:

$this->getCategory(3)->getUrl()
0

@andrea Please update getCategory method. Either it works well.

/**
 * Return the category object by its id.
 * 
 * @param categoryId (Integer)
 */
public function getCategory($categoryId)
{
  return $this->_categoryRepository->get($categoryId);
}

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.