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
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; ?>
  • 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 '15 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 '15 at 10:00
  • I updated ans but it is working only levels (1,2 & 3) – Abdul Dec 28 '15 at 10:04
  • Please tell me why do you need to double <?php endif; ?><?php endif; ?>? – Sylon Dec 28 '15 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 '15 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

  • Unfortunately it does not work...:-( – Sylon Dec 27 '15 at 16:47
  • 1
    Works on Magento 1.9 – TheRealJAG Jan 18 '18 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);
?>
  • Thanks for the answer!!! Unfortunately, I do not understand how it's all put together to get the final result ... :-( – Sylon Dec 28 '15 at 11:55
  • I added a full example, hope it helps – Fabian Schmengler Dec 28 '15 at 12:10
  • Apparently I'm doing something wrong ... I copy your code "Summari" file left.phtml. Page is not working...:-( – Sylon Dec 28 '15 at 12:18
  • Sorry, I wrote it on top of my head without testing and forgot a semicolon before the last }. Try again – Fabian Schmengler Dec 28 '15 at 12:21
  • Tell me, please, this code can be used for menu accordion? – Sylon Dec 28 '15 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.

  • Loading categories in a loop is not good advice, it seriously hurts the performance. – Fabian Schmengler Dec 28 '15 at 11:14
  • @fschmengler its easy way to do it rather than writing other thousands of LOCs. – Fayyaz Khattak Dec 28 '15 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 – Fabian Schmengler Dec 28 '15 at 11:18
  • @fschmengler may be this could help you: Mage::getModel('catalog/category_api')->tree($parentID); data will be in array format. – Fayyaz Khattak Dec 28 '15 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. – Fabian Schmengler Dec 28 '15 at 11:52

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.