Is there a way to hide categories that don't have active products?
Or, even better, only show categories that have active products and stock.
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It only takes a minute to sign up.
Sign up to join this communityThe easiest way to do this is to only rewrite the Mage_Catalog_Block_Navigation
block:
=> In the method _renderCategoryMenuItemHtml()
you want to replace the loop
foreach ($children as $child) {
if ($child->getIsActive()) {
$activeChildren[] = $child;
}
}
=> with this:
foreach ($children as $child) {
if ($child->getIsActive() && $this->_hasProducts($child->entity_id)) {
$activeChildren[] = $child;
}
}
=> and similarly in the method renderCategoriesMenuHtml()
replace the code
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive()) {
$activeCategories[] = $child;
}
}
=> with this:
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive() && $this->_hasProducts($child->entity_id)) {
$activeCategories[] = $child;
}
}
=> Finally add the method we were just using in our code:
protected function _hasProducts($category_id) {
$products = Mage::getModel('catalog/category')->load($category_id)
->getProductCollection()
->addAttributeToSelect('entity_id')
->addAttributeToFilter('status', 1)
->addAttributeToFilter('visibility', 4);
return ( $products->count() > 0 ) ? true : false;
}
Bear in mind that the method checks each category individually by using the catalog/category model. So, if you have many categories, you might want to rewrite the code to not run into performance issues. In a smaller store we are running, this works fine.
There is no built-in feature for hiding empty categories (but you can manually select Is active = No for each category in admin area->catalog->manage categories)
Here is a link on a great post from Josh Prattski's blog, where he wrote step-by-step walkthrough on how-to make an extension for this purpose.
If you just want to hide them in the catalog navigation you could add an if condition in the template to check for amount of products in that category.
Maybe this would help too.
Go to the backend of your webshop.
Then to
Catalog > Category > Manage Category
, choose your category, and select theDisplay settings
tab.
The label Display Mode
could be set to
Show static block only
.
What worked for me is to create a template category tree and implement a condition function which renders the category tree:
foreach ($children as $child)
{
if ($child->getIsActive() && $this->_hasProducts($child->entity_id))
{
$activeChildren[] = $child;
}
}
function _hasProducts:
protected function _hasProducts($category_id) {
$products = Mage::getModel('catalog/category')->load($category_id)
->getProductCollection()
->addAttributeToSelect('entity_id')
->addAttributeToFilter('status', 1)
->addAttributeToFilter('visibility', 4);
return ( $products->count() > 0 ) ? true : false;
}
You can execute following sql to disable all categories without products.
UPDATE `catalog_category_entity_int` AS `status`
INNER JOIN `eav_attribute` AS `attr` ON `attr`.`attribute_code` = 'is_active'
AND `attr`.`entity_type_id` = 3
AND `status`.`attribute_id` = `attr`.`attribute_id`
SET `status`.`value` = IF((SELECT COUNT(`index`.`product_id`)
FROM `catalog_category_product_index` AS `index`
WHERE `index`.`category_id` = `status`.`entity_id` GROUP BY `index`.`category_id`) > 0, 1, 0)
WHERE `status`.`store_id` = 0
More details you can find here http://quicktips.ru/all/hide-all-categories-without-products-and-show-categories-with-pr/
what I've did to hide empty categories is to rewrite Mage_Catalog_Model_Resource_Category_Tree
load()
function.
I've to join product collection with category collection like below.
$collection = Mage::getResourceModel('catalog/product_collection');
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
$collection->getSelect()->join(
array('product_category' => Mage::getSingleton('core/resource')->getTableName('catalog/category_product_index')),
'product_category.product_id = e.entity_id',
array('')
);
$collection->getSelect()->where('product_category.category_id = '.$this->_table.'.entity_id');
$select->columns(array('product_count' => $collection->getSelectCountSql()));
add this code before $arrNodes = $this->_conn->fetchAll($select);
this line.
And wrap this code with this condition, this class called from frontend and backend model also
if(!Mage::getSingleton('admin/session')->isLoggedIn())
I've added extra field product_count which contains actual active product count.
I am using a 3rd party module to display category on the top menu and I've put condition based on product count when the menu is rendered.