0

I'd like to be able to show sub-categories as images for specific categories (cms pages / cms blocks). I do not want categories to appear that do not have images.

I have figured out how to put the root categories on my home page with the following code I dug up and modified. It will only show root categories that have images, those that do not have images will not appear:

file: categorylisting.phtml

<div class="list-category">

<?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 $open = $this->isCategoryActive($_category); ?>
<?php  
$cur_category=Mage::getModel('catalog/category')->load($_category->getId());
$layer = Mage::getSingleton('catalog/layer');
$layer->setCurrentCategory($cur_category);
if ($immagine = $this->getCurrentCategory()->getImageUrl()):
?>     

<div class="item-category">
            <div class="linkimage">

                <a href="<?php echo $this->getCategoryUrl($_category)?>">
                <img src="<?php echo $immagine ?>" alt="<?php echo $this->htmlEscape($this->getCurrentCategory()->getName()) ?>" width="135" height="135" />
                </a>
                <div class="name-category">
                <a href="<?php echo $this->getCategoryUrl($_category)?>"><?php echo $_category->getName()?></a>
                </div>                    


            </div>

Then on a CMS page I use:

{{block type="catalog/navigation" name="catalog.categories" template="catalog/navigation/categorylisting.phtml"}}

This works great for root categories.

I'd like to show the sub-categories by specifying category X. I'm not sure if there is a variable I could use with the snipped used for the CMS page or CMS block?

What is the best way to display sub-categories of a specified category in a CMS page or CMS block using the above code?

9
+50

The things I do for a bounty....This is a fully functional module that will list your subcategories in a category page or you can use it to show them in a static page or block by passing a category id to the block. Let's name the module Easylife_Subcategories.
Create the following files.
(read carefully and pay attention to the comments inside the code)

app/etc/module/Easylife_Subcategories.xml - the declaration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Subcategories>
            <codePool>local</codePool>
            <active>true</active>
            <depends>
                <Mage_Catalog />
            </depends>
        </Easylife_Subcategories>
    </modules>
</config>

app/code/local/Easylife/Subcategories/etc/config.xml - the configuration file

<?xml version="1.0"?>
<config>
    <modules>
        <Easylife_Subcategories>
            <version>1.0.0</version>
        </Easylife_Subcategories>
    </modules>
    <global>
        <blocks>
            <easylife_subcategories>
                <class>Easylife_Subcategories_Block</class>
            </easylife_subcategories>
        </blocks>
    </global>
    <frontend>
        <layout>
            <updates>
                <easylife_subcategories>
                    <file>easylife_subcategories.xml</file>
                </easylife_subcategories>
            </updates>
        </layout>
    </frontend>
</config>

app/code/local/Easylife/Subcategories/Block/Subcategories.php - the subcategories block

<?php
class Easylife_Subcategories_Block_Subcategories extends Mage_Core_Block_Template {
    public function getChildCategories() {
        $categoryId = $this->getCategoryId();
        $children = Mage::getModel('catalog/category')->getCollection()
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('parent_id', $categoryId) //get only the children
            ->addAttributeToFilter('is_active', 1) //get only active children
            ->addAttributeToFilter('thumbnail', array('notnull'=>1)) //only the ones with thumbnails
            //if you want to use the 'image' attribute instead of thumbnail comment the line above and uncomment the one below
            //->addAttributeToFilter('image', array('notnull'=>1)) //only the ones with images
            ->addAttributeToSort('position');
        return $children;
    }
    public function getCategoryId() {
        if (!$this->hasData('category_id')) {
            if (Mage::registry('current_category')) {
                $this->setData('category_id', Mage::registry('current_category')->getId());
            }
            else {
                $this->setData('category_id', Mage::app()->getStore()->getRootCategoryId());
            }

        }
        return $this->getData('category_id');
    }
}

app/design/frontend/base/default/template/easylife_subcategories/subcategories.phtml - the template that renders the subcategories. You can also place it inside you theme, but by putting it in base/default you make it available for all themes.

<?php $categories = $this->getChildCategories();?>
<?php if ($categories->count(0)) : ?>
    <div class="category-children">
        <?php foreach($categories as $child): ?>
            <div class="item">
                <a href="<?php echo $child->getUrl(); ?>" title="<?php echo Mage::helper('core')->escapeHtml($child->getName()) ?>">
                    <?php if ($child->getThumbnail()) : ?> <!-- if you are using the 'image' attribute replace  `getThumbnail` with `getImage`-->
                        <img class="child-image" alt="<?php echo Mage::helper('core')->escapeHtml($child->getName())?>" src="<?php echo Mage::getBaseUrl('media').'catalog/category/'.$child->getThumbnail() ?>" /><!-- if you are using the 'image' attribute replace  `getThumbnail` with `getImage`-->
                    <?php endif;?>
                </a>
                <a href="<?php echo $child->getUrl(); ?>" title="<?php echo Mage::helper('core')->escapeHtml($child->getName()) ?>"><?php echo $child->getName()?></a>
            </div>
        <?php endforeach; ?>
    </div>
<?php endif;?>

app/design/frontend/base/default/layout/easylife_subcategories.xml - the layout file

<?xml version="1.0"?>
<layout>
    <easylife_subcategories>
        <reference name="content">
            <block type="easylife_subcategories/subcategories" template="easylife_subcategories/subcategories.phtml" name="subcategories" before="-" />
        </reference>
    </easylife_subcategories>
    <catalog_category_layered>
        <update handle="easylife_subcategories" />
    </catalog_category_layered>
    <catalog_category_default>
        <update handle="easylife_subcategories" />
    </catalog_category_default>
</layout>

This will add the subcategories list in every category page at the top of the page.
If you want to add it somewhere in the middle of the page make the layout file from above look like this:

<?xml version="1.0"?>
<layout>
    <easylife_subcategories>
        <reference name="category.products">
            <block type="easylife_subcategories/subcategories" template="easylife_subcategories/subcategories.phtml" name="subcategories" before="-" />
        </reference>
    </easylife_subcategories>
    <catalog_category_layered>
        <update handle="easylife_subcategories" />
    </catalog_category_layered>
    <catalog_category_default>
        <update handle="easylife_subcategories" />
    </catalog_category_default>
</layout>

and add in app/design/frontend/{package}/{theme}/catalog/category/view.phtml the following line, in the place where you want the subcategories to be listed.

<?php echo $this->getChildHtml('subcategories')?>

If you don't want to add the subcategories block to all the categories then you can skip the creation of the layout file.

You can add the subcategories block inside any cms page or cms block by using this {{block}} directive

{{block type="easylife_subcategories/subcategories" template="easylife_subcategories/subcategories.phtml" category_id="10"}}

Replace 10 in the directive above with the parent category id you need.
If you don't specify a category id like below

{{block type="easylife_subcategories/subcategories" template="easylife_subcategories/subcategories.phtml"}}

and you show the block in a category page, the subcategories of that category will be listed. It is useful if you want to show the subcategories for only a few parent categories. You just create a cms block and use that block for the categories you need in Display mode->CMS Block field of the categories you want without having to create one block for each category.

If you use the code in a static page then all the top level categories will be shown.

  • @sr_magento. Don't use Mage_Catalog_Block_Navigation block. It is cached and you can get into trouble when you turn block cache on. I will modify the answer and show you how you can use your own block. Give me a few minutes – Marius Jun 2 '14 at 12:07
  • @sr_magento. Check the updated answer. – Marius Jun 2 '14 at 12:13
  • @sr_magento. Yep it should work like that – Marius Jun 2 '14 at 13:01
  • Then create a template '[namespace]_[module]/catalog/subcategories.phtml' --> so /app/design/frontend/default/default/template/Easylife/subcategories.phtml? And when you say [namespace]_[module] does that mean Easylife_Locale ? – SR_Magento Jun 3 '14 at 13:47
  • 1
    @sr_magento If you want to give money away, give to charity the amount that you think this answer is worth and we call it even. :) – Marius Jun 5 '14 at 13:14
5

This may help you:

 <?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> 
  • Okay but can this be used to specify a specific category? If I wanted to show sub-categories from category 123? – SR_Magento Jun 2 '14 at 11:59
  • $cats = Mage::getModel('catalog/category')->load(123)->getChildren(); – TBI Infotech Jun 2 '14 at 12:22

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.