3

I have created a new category attribute using a setup script and now it is showing on the backend and assigned values (it is just a boolean attribute). the attribute name on EAV entity table is is_home_category .And now I'm trying to get its values on frontend

$categories = $this->getStoreCategories(true, true, true);

foreach ($categories as $category):
   echo $category->getIsHomeCategory()
endforeach;

But it returns nothing , could someone help me

4 Answers 4

8

Proper way is to in the Install/Upgrade script:

$eavSetup->addAttribute(
    \Magento\Catalog\Model\Category::ENTITY,
    'my_custom_attribute',
    [
        // ...
        'used_in_product_listing' => true, // for category pages
        'visible_on_front' => true, // for frontend??
        'is_used_in_grid' => true, // for category pages
        'is_visible_in_grid' => true // for category pages
    ]
);

also on the collection do:

$collection->addAttributeToSelect('my_custom_attribute')

and then in the template you can just call:

$category->getMyCustomAttribute()
// or
$category->getData('my_custom_attribute');

If still not work run below command:

php bin/magento in:reindex
3
  • 3
    What do you mean with 'also on the collection do' Jul 21, 2017 at 7:37
  • Also when i try to use this in my phtml fille it just says that $category is undefined Jul 21, 2017 at 7:40
  • I have set the visible_on_front as true, but still, in front-end, the value has not shown, but if I used the registry('current_category') the custom attribute has listing
    – senthil
    Jun 29, 2018 at 10:39
1

Previous answers are correct only if you explicitly indicates which attributes you want with addAttributeToSelect('is_home_category') or addAttributeToFilter('is_home_category') but this has limitations.

If you want your attribute to be always loaded with addAttributeTSelect('*'), you also have to create a new file etc/catalog_attributes.xml in your module and put the following code in it:

<?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="catalog_category">
        <attribute name="is_home_category"/>
    </group>
</config>

Then flush your caches and now every new category collection with addAttributeToSelect('*') will contains the field is_home_category if the category has a value for this attribute.

Note that this XML file can also contains data for other type of entites like products, you can see a lot of its usages if your search in Magento's core modules.

0

In your extension you should override the Category model (which contains all the data) and add a method to obtain the new attribute. In this way you can get the data in your view.

So first you have to create a file app\code\VENDOR\EXTENSION-NAME\etc\di.xml

<?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\Catalog\Model\Category" type="VENDOR\EXTENSION-NAME\Model\Category" />
</config>

If you already have this file, just add the <preference> tag.

Create the Category.php file in app\code\VENDOR\EXTENSION-NAME\Model\. This file should contain the following (or something like it):

<?php

namespace VENDOR\EXTENSION-NAME\Model;

class Category extends \Magento\Catalog\Model\Category
{
    public function getIsHomeCategory()
    {            
        return $this->getCustomAttribute('is_home_category');            
    }
}

Flush your cache, and now you should be able to call this getIsHomeCategory function.

5
  • I think we should not override core functions May 4, 2016 at 11:45
  • 1
    Since getIsHomeCategory isn't a core function this is not the case.
    – 11mb
    May 4, 2016 at 11:58
  • no I mean Magento\Catalog\Model\Category class May 4, 2016 at 14:10
  • I think it is the only way to achieve this. A plugin (interceptor) can only hook into existing (public) functions. Also, this is the way Magento does it. For example take a look at module-catalog-search/etc/di.xml. Here the SearchCollectionInterface is overwritten. When you check the class in this module you will see it extends the original one. (Maybe one improvement may be to prefer an interface instead of a class. But the idea remains the same)
    – 11mb
    May 12, 2016 at 8:14
  • There is absolutely no point for doing it. It will impact performance heavily. Dec 22, 2016 at 8:06
0

You can use this:

$categoryId = 3;
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$category = $_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
echo $category->getName();
echo $category->getData('<attribute_code>');

Or you can do this:

namespace Vendor\Module\Block;
class CustomBlock extends \Magento\Framework\View\Element\Template 
{
protected $_categoryFactory;    

public function __construct(
\Magento\Catalog\Model\CategoryFactory $categoryFactory,
\Magento\Framework\View\Element\Template\Context $context,
) {
    $this->_categoryFactory = $categoryFactory;
    parent::__construct($context);
}

public function getCategoryData($attrCode)
{
    $categoryId = '43';
    $category = $this->_categoryFactory->create()->load($categoryId);
    $categoryAttributeName = $category->getData($attrCode);
    return $categoryName;
}
}
1
  • Here it should be return $categoryAttributeName; Apr 25 at 10:49

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.