1

I have a file left.phtml for a vertical menu. I want to get all subcategories of specific category ID3. I have this code.

<?php if (!Mage::registry('current_category')) return ?>
<?php
$categoryId = 3;
$category = Mage::getModel('catalog/category')->load($categoryId);
$_categories = $category->getChildrenCategories();
?>
<?php $_count = is_array($_categories)?count($_categories):$_categories->count(); ?>
<?php if($_count): ?>
<div class="block block-layered-nav block-layered-nav--no-filters">
    <div class="block-content toggle-content open">
        <dl id="narrow-by-list2">
            <dt><?php echo $this->__('Каталог') ?></dt>
            <dd>
                <ol>
                <?php foreach ($_categories as $_category): ?>
                    <?php if($_category->getIsActive()): ?>
                    <li>
                        <a href="<?php echo $this->getCategoryUrl($_category) ?>"<?php if ($this->isCategoryActive($_category)): ?> class="current"<?php endif; ?>>
                            <?php echo $this->escapeHtml($_category->getName()) ?>
                        </a>
                    </li>
                    <?php endif; ?>
                <?php endforeach ?>
                </ol>
            </dd>
        </dl>
        <script type="text/javascript">decorateDataList('narrow-by-list2')</script>
    </div>
</div>
<?php endif; ?>

Example:

Category ID 3 (level 0)
  Category (level 1)
    Subcategory (level 2)
      Subcategory (level 3)
    Subcategory
      Subcategory (level 3)
    Subcategory
      Subcategory (level 3)
  Category (level 1) 
    Subcategory 
    Subcategory
    Subcategory
  Category (level 1) 
    Subcategory
    Subcategory
    Subcategory

4 Answers 4

3

Try this::

<?php $_helper = Mage::helper('catalog/category') ?>
<?php $categoryId = 3;?>
<?php $category = Mage::getModel('catalog/category')->load($categoryId) ?>
<?php $_categories = $category->getChildrenCategories() ?>

<?php if (count($_categories) > 0): ?>
    <ul>
        <?php foreach($_categories as $_category): ?>
            <li>
                <a href="<?php echo $_helper->getCategoryUrl($_category) ?>"><?php echo $_category->getName() ?></a>
                <?php $_category = Mage::getModel('catalog/category')->load($_category->getId()) ?>
                <?php if($_category->hasChildren()):?>
                <?php $_subcategories = $_category->getChildrenCategories() ?>
                    <ul>
                        <?php foreach($_subcategories as $_subcategory): ?>
                            <li>
                                <a href="<?php echo $_helper->getCategoryUrl($_subcategory) ?>"><?php echo $_subcategory->getName() ?></a>
                                <?php $_category2 = Mage::getModel('catalog/category')->load($_subcategory->getId()) ?>
                                <?php if($_category2->hasChildren()):?>
                                <?php $_subcategories2 = $_category2->getChildrenCategories() ?>
                                    <ul>
                                        <?php foreach($_subcategories2 as $_subcategory2): ?>
                                            <li>
                                                <a href="<?php echo $_helper->getCategoryUrl($_subcategory2) ?>"><?php echo $_subcategory2->getName() ?></a>
                                            </li>
                                        <?php endforeach; ?>
                                    </ul>
                                <?php endif; ?>

                            </li>
                        <?php endforeach; ?>
                    </ul>
                <?php endif; ?>
            </li>
        <?php endforeach; ?>
    </ul>
<?php endif; ?>
12
  • Abdul, the code display only the first level. But I need to output all levels (1,2,3). Please help, get all categories and subcategories.
    – Sylon
    Dec 28, 2015 at 9:33
  • then you are create one 'Recursive Function' for get all sub categories in block file and this function use in .phtml file
    – Abdul
    Dec 28, 2015 at 10:00
  • I updated ans but it is working only levels (1,2 & 3)
    – Abdul
    Dec 28, 2015 at 10:04
  • Please tell me why do you need to double <?php endif; ?><?php endif; ?>?
    – Sylon
    Dec 28, 2015 at 10:50
  • <?php if($_category->hasChildren()):?> and second <?php <?php if (count($_subcategories) > 0): ?> no need both u can use only one above
    – Abdul
    Dec 28, 2015 at 11:09
3

Here is code you can use:

$children = Mage::getModel('catalog/category')->getCategories(3);
foreach ($children as $category) {
      echo $category->getName();
}

Thanks to @clockworkgeek for the answer

2
  • Unfortunately it does not work...:-(
    – Sylon
    Dec 27, 2015 at 16:47
  • 1
    Works on Magento 1.9
    – TheRealJAG
    Jan 18, 2018 at 23:07
2

To get a collection of subcategories, with their subcategories, and so on, of a given category $parentCategory, you can use:

$subcategoryCollection = Mage::getModel('catalog/category')
    ->getCollection()
    ->addFieldToFilter('path', ['like' => $parentCategory->getData('path') . '/%']);

(as described here: https://stackoverflow.com/q/5564647/664108)

This is a single collection load, so there is no need for additional load() methods on the category model, as in the recursive solutions.

But since you want to output the categories as tree, you can also use the category tree model, which uses the same method internally:

$categoryTree = Mage::getResourceModel('catalog/category')->getCategories(3, 0, true);

The parameters are:

  • category_id
  • recursion_level (0 for no limit)
  • sorted

$categoryTree is now a Varien_Data_Tree_Node_Collection instance that contains all category data in tree form. Use it as follows:

<?php foreach ($categoryTree as $_category): ?>
    <?php if($_category->getIsActive()): ?>
    <li>
        <a href="<?php echo $this->getCategoryUrl($_category) ?>"<?php if ($this->isCategoryActive($_category)): ?> class="current"<?php endif; ?>>
            <?php echo $this->escapeHtml($_category->getName()) ?>
        </a>

        <?php foreach ($_category->getChildren() as $_subCategory): ?>

            // repeat for second level, or create a function and use recursion for arbitrary deep nesting

        <?php endforeach; ?>
    </li>
    <?php endif; ?>
<?php endforeach ?>

$_category is a Varien_Data_Tree_Node instance, so getChildren() is not the same method as the one in the category model and it does not have all the other methods, but it's a Varien_Object that contains the category data, so all the magic getters work.


Summary

Here is a complete code example with recursive function, that you can copy and paste into your template and modify as needed (the function needs at least PHP 5.4 to work, I hope that's not a problem):

<?php
$categoryId = 3;
$categoryTree = Mage::getResourceModel('catalog/category')->getCategories($categoryId, 0, true);
$printCategories = function($nodes) use (&$printCategories) {
    ?><ol>
    <?php foreach ($nodes as $_category): ?>
        <?php if($_category->getIsActive()): ?>
        <li>
            <a href="<?php echo $this->getCategoryUrl($_category) ?>"<?php if ($this->isCategoryActive($_category)): ?> class="current"<?php endif; ?>>
                <?php echo $this->escapeHtml($_category->getName()) ?>
            </a>

            <?php $printCategories($_category->getChildren()); ?>

        </li>
        <?php endif; ?>
    <?php endforeach; ?>
    </ol>
    <?php
};
$printCategories($categoryTree);
?>
6
  • Thanks for the answer!!! Unfortunately, I do not understand how it's all put together to get the final result ... :-(
    – Sylon
    Dec 28, 2015 at 11:55
  • I added a full example, hope it helps Dec 28, 2015 at 12:10
  • Apparently I'm doing something wrong ... I copy your code "Summari" file left.phtml. Page is not working...:-(
    – Sylon
    Dec 28, 2015 at 12:18
  • Sorry, I wrote it on top of my head without testing and forgot a semicolon before the last }. Try again Dec 28, 2015 at 12:21
  • Tell me, please, this code can be used for menu accordion?
    – Sylon
    Dec 28, 2015 at 13:42
0

This is another way to get child category using Category Tree:

public function getCategoryTree()
{
    $model = Mage::getModel('catalog/category_api');
    $treeData = $model->tree();
    return $this->_sendJsonRespond('success', $treeData, null, null);
}

Hope this may work for you.

6
  • Loading categories in a loop is not good advice, it seriously hurts the performance. Dec 28, 2015 at 11:14
  • @fschmengler its easy way to do it rather than writing other thousands of LOCs. Dec 28, 2015 at 11:16
  • Sorry but that's not an excuse for crappy code. Loading EAV models is really expensive in Magento. I'll add an answer without thousand lines of code Dec 28, 2015 at 11:18
  • @fschmengler may be this could help you: Mage::getModel('catalog/category_api')->tree($parentID); data will be in array format. Dec 28, 2015 at 11:49
  • Using the API might be an option, feel free to update your answer. But I am not looking for a solution, just added an own answer using the category tree resource model. Dec 28, 2015 at 11:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.