Simple Call to Get Category Images & Display in List

25,768

Solution 1

We managed to resolve this ourselves - see fix below.

<?php
    //gets all sub categories of parent category 'Brands'
    $cats = Mage::getModel('catalog/category')->load(6)->getChildren();
    $catIds = explode(',',$cats);

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

    ksort($categories, SORT_STRING);
?>
    <ul>
        <?php foreach($categories as $name => $data): ?>
            <li>
                <a href="<?php echo $data['url']; ?>" title="<?php echo $name; ?>">
                    <img class="cat-image" src="<?php echo $data['img']; ?>" />
                </a>
            </li>   
        <?php endforeach; ?>
    </ul>

Surprised we didn't get more support on this with it being a relatively simple Magento issue. Thanks B00MER for your answer though.

Solution 2

The solution by zigojacko is not ideal because it separately loads in models in a loop. This does not scale well, and with many categories will thrash your database. Ideally, you'd add the images to the child collection.

A faster solution is to add the image attribute to a collection with an ID filter like B00MER:

// Gets all sub categories of parent category 'Brands'
$parent = Mage::getModel('catalog/category')->load(6);

// Create category collection for children
$childrenCollection = $parent->getCollection();
// Only get child categories of parent cat
$childrenCollection->addIdFilter($parent->getChildren());
// Only get active categories
$childrenCollection->addAttributeToFilter('is_active', 1);

// Add base attributes
$childrenCollection->addAttributeToSelect('url_key')
        ->addAttributeToSelect('name')
        ->addAttributeToSelect('all_children')
        ->addAttributeToSelect('is_anchor')
        ->setOrder('position', Varien_Db_Select::SQL_ASC)
        ->joinUrlRewrite();

// ADD IMAGE ATTRIBUTE
$childrenCollection->addAttributeToSelect('image');

?>
<ul>
    <?php foreach($childrenCollection as $cat): ?>
        <li>
            <a href="<?php echo $cat->getURL(); ?>" title="<?php echo $cat->getName(); ?>">
                <img class="cat-image" src="<?php echo $cat->getImageUrl(); ?>" />
            </a>
        </li>   
    <?php endforeach; ?>
</ul>

Solution 3

Give this method a try instead of your $img = $category->getImageUrl(); to $img = getCategoryImage($category);

function getCategoryImage($category) {
    $categoryCollection = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->getCollection()->addAttributeToSelect('image')->addIdFilter($category->getId());

    foreach($categoryCollection as $category) {
        return $category->getImageUrl();
    }
}

(now defunct) Reference: http://www.magentocommerce.com/boards/viewthread/5026/P45/

Share:
25,768
zigojacko
Author by

zigojacko

Founder and CEO of the The Clubnet Group and Director of Search &amp; Operations at Clubnet Digital, a UK (Plymouth) based full service digital agency. We help businesses perform better on the web.

Updated on July 20, 2022

Comments

  • zigojacko
    zigojacko almost 2 years

    I'm displaying a list of sub categories by parent category ID and am wanting to display the category image in place of a category name.

    Here is what I have so far...

    <div id="menu_brands">
    <div class="brand_head">
        <h3><?php echo $this->__('Browse By Brand') ?></h3>
    </div>
    <div class="brand_list">
        <?php
            $cats = Mage::getModel('catalog/category')->load(6)->getChildren();
            $catIds = explode(',',$cats);
    
            $categories = array();
                foreach($catIds as $catId) {
                    $category = Mage::getModel('catalog/category')->load($catId); 
                    $categories[$category->getName()] = $category->getUrl();
                    $img = $category->getImageUrl(); //I suspect this line is wrong
            }
    
            ksort($categories, SORT_STRING);
        ?>
    
            <ul>
                <?php foreach($categories as $name => $url): ?>
                    <li>
                        <!--<a href="<?php echo $url; ?>"><?php echo $name; ?></a>-->
                        <a href="<?php echo $url; ?>" title="<?php echo $name; ?>">
                            <img src="<?php echo $img; ?>" width="auto" alt="<?php echo $name; ?>" /> <!--I suspect this line is wrong-->
                        </a>
                    </li>
                <?php endforeach; ?>
            </ul>
    </div>
    </div>
    

    I've tried countless ways to display the images in place of the category names but nothing seems to make the images appear. Currently with the above, the output is an empty 'img src' so there is clearly an error with what I'm trying (and probably a better way of achieving what I'm after).

    Please could someone kindly point out what the problem is?

    If it's of any relevance, what I intend to do afterwards is then display the category images in a grid format (3 or 4 per line).

    Many thanks in advance.

  • zigojacko
    zigojacko about 12 years
    Fatal error: Call to undefined function getCategoryImage() in //path// on line 49 '$img = getCategoryImage($category);' (is line 49)
  • zigojacko
    zigojacko about 12 years
    Should the functions be declared from within the same file? Currently they are in the relevant extensions Navigation.php along with all the others. Thanks
  • nero
    nero about 9 years
    Thanks for this Robert, this is quite a bit more elegant.
  • Nikhil Bansal
    Nikhil Bansal about 9 years
    This works very well, thanks Robert! To anyone that might want to get the thumbnail instead of the category use $childrenCollection->addAttributeToSelect('thumbnail'); and then call $cat->getThumbnail() in the foreach