Joe Fletcher
Joe Fletcher

Reputation: 2181

How to sort a category list array alphabetically in Magento

In Magento, I've created a phtml template file with the code below. I got this from this tutorial. Me and others are wondering how to sort this category list alphabetically. The first lines of code create an array with Category IDs. Further down, we can get the Category Name using the ID within the foreach section. But to sort by Name, we need to get the Names in an array before the foreach and then sort by name. How?

<?php
$cats = Mage::getModel('catalog/category')->load(319)->getChildren();
$catIds = explode(',',$cats);
?>
<ul>
<?php foreach($catIds as $catId): ?>
    <li>
        <?php
            $category = Mage::getModel('catalog/category')->load($catId);
            echo '<a href="' . $category->getUrl() . '">';
            echo $category->getName() . '</a>';
        ?>
    </li>
<?php endforeach; ?>
</ul>

Note: 319 is the category id of the parent category for which I want to list subcategories. Also, I'm not putting this is a category page template. I'm inserting as a block in a CMS page (that part is already working).

Upvotes: 3

Views: 22818

Answers (5)

alex
alex

Reputation: 490667

You could build a list of category names first.

<?php
$cats = Mage::getModel('catalog/category')->load(319)->getChildren();
$catIds = explode(',',$cats);

$categories = array();
foreach($catIds as $catId) {
       $category = Mage::getModel('catalog/category')->load($catId); 
       $categories[$category->getName()] = $category->getUrl();
}

ksort($categories, SORT_STRING);
?>

<ul>
<?php foreach($categories as $name => $url): ?>
    <li>
    <a href="<?php echo $url; ?>"><?php echo $name; ?></a>
    </li>
<?php endforeach; ?>
</ul>

I wrote this answer without knowing too much about Magento and just wanting something quickly that worked. Anton's answer is better and more Magentic(?)

Upvotes: 10

user2753425
user2753425

Reputation: 301

First backup your topmenu.phtml then replace the following code in your new topmenu.phtml file

<?php $_helper = Mage::helper('catalog/category') ?>
<?php $_categories = $_helper->getStoreCategories() ?>
<?php

function array_sort($array, $on, $order=SORT_ASC){
    $new_array = array();
    $sortable_array = array();

    if (count($array) > 0) {
        foreach ($array as $k => $v) {
            if (is_array($v)) {
                foreach ($v as $k2 => $v2) {
                    if ($k2 == $on) {
                        $sortable_array[$k] = $v2;
                    }
                }
            } else {
                $sortable_array[$k] = $v;
            }
        }

        switch ($order) {
            case SORT_ASC:
            asort($sortable_array);
            break;
            case SORT_DESC:
            arsort($sortable_array);
            break;
        }

        foreach ($sortable_array as $k => $v) {
            $new_array[$k] = $array[$k];
        }
    }

    return $new_array;
}

?>
<?php
$layer = Mage::getSingleton('catalog/layer');
$_category = $layer->getCurrentCategory();
$currentCategoryId= $_category->getId();
?>
<div class="nav-container">
    <ul id="nav">
    <?php $_helper = Mage::helper('catalog/category') ?>
    <?php $_categories = $_helper->getStoreCategories() ?>
    <?php $currentCategory = Mage::registry('current_category') ?>
    <?php if (count($_categories) > 0){ ?>
        <?php foreach($_categories as $_category){ ?>
            <?php $_category = Mage::getModel('catalog/category')->load($_category->getId()) ?>
            <li><a href="<?php echo $_helper->getCategoryUrl($_category) ?>"><span><?php echo $_category->getName(); ?></span></a>
            <?php $catList = array();?>
            <?php $_subcategories = $_category->getChildrenCategories() ?>
            <?php foreach($_subcategories as $_subCategory){ ?>
                <?php $catList[] = array('name' => $_subCategory->getName(), 'url' => $_subCategory->getUrl(), 'id' => $_subCategory->getId());?>
            <?php } ?>
            <?php $catList = array_sort($catList, 'name', SORT_ASC);?>
            <ul>
            <?php if (count($catList) > 0){ ?>
                <?php $subcat=0?>
                <?php foreach($catList as $_subCategory){ ?>
                    <li><a href="<?php echo $_subCategory['url'] ?>"><span><?php echo $_subCategory['name'] ?></span></a>
                    <?php $subCatList = array();?>
                    <?php $_subSubCat = Mage::getModel('catalog/category')->load($_subCategory['id']);
                    $_subSubCategories = $_subSubCat->getChildrenCategories();?>
                    <?php foreach($_subSubCategories as $_subSubCategory){ ?>
                        <?php $subCatList[] = array('name' => $_subSubCategory['name'], 'url' => $_subSubCategory['url']);?>
                    <?php } ?>
                    <?php $subCatList = array_sort($subCatList, 'name', SORT_ASC);?>
                    <?php if (count($subCatList) > 0){ ?>
                        <ul>
                            <?php foreach($subCatList as $_subSubCat){ ?>
                                <li><a href="<?php echo $_subSubCat['url'] ?>"><span><?php echo $_subSubCat['name'] ?></span></a>
                            <?php } ?>
                            </li>
                        </ul>
                    <?php } ?>
                    </li>
                <?php } ?>

                <?php } ?>
            </ul>
            </li>
        <?php } ?>
    <?php } ?>
    </ul>
</div>

Upvotes: 1

Jongosi
Jongosi

Reputation: 2355

There's a much easier way to do this in the latest Magento (CE 1.7.0.2)+

$children = Mage::getModel('catalog/category')->getCategories(319, 1, true, true);

// iterate through the results
foreach ($children as $category):
    echo '<option value="' . $category->getUrl() . '">' . $category->getName() . '</option>';
endforeach;

The function getChildren() resides at...

app/code/core/Mage/Catalog/Model/Category.php around line 817

There are loads of options. Hope it saves you some time!

Upvotes: 1

bhab
bhab

Reputation: 169

Hi I am using magento 1.4.1.1 and this worked to sort the child categories: use

$cats = Mage::getModel('catalog/category')->load(319)->getChildrenCategories();

to get the children categories of category with id 319 and edit the file at code/core/Mage/catalog/Model/Resource/Eav/Mysql4/category.php at line 582 under the function getChildrenCategories() to change

->setOrder('position','ASC'); 

to

->setOrder('name','ASC);

hope this works for you too.

Upvotes: 1

Anton S
Anton S

Reputation: 12750

You can call

Mage::getModel('catalog/category')->getCollection()->addFieldToFilter('parent_id', '319')->addAttributeToSort('name', 'ASC');

and you'll get the whole bunch sorted right away, rest is just iteration over typical Varien collection. It's a pseudo sample and i don't know if the parent_id is the actual field name in db so you might check that out before you get the right results.

Great read about collections in Magento is written by Alan Storm

Upvotes: 22

Related Questions