lion

Magento Subcategories on Category Pages

By default Magento will only display a category’s direct subcategories in the form of a neat list in the left hand navigation. This is all well and good, but oftentimes something more visual is required which will encourage the user to click though.

If you’ve chosen not to list products in your parent category this basically leaves a large white space in your content area, which could be much better utilised as an area to display your subcategories! Here’s the method…

1. Create catalog/category/sub.phtml

First, create a new file in your theme, which will be used to display your current category’s subcategories. The code to do this is below:

<?php
$category = Mage::getSingleton('catalog/layer')->getCurrentCategory();
$categories = $category->getCollection()
        ->addAttributeToSelect(array('name', 'thumbnail'))
        ->addAttributeToFilter('is_active', 1)
        ->addIdFilter($category->getChildren())
?>
<ul class="subcategories">
    <?php foreach ($categories as $category): ?>
        <li>
            <a href="<?php echo $category->getUrl() ?>"><img src="<?php echo Mage::getBaseUrl('media') . 'catalog' . DS . 'category' . DS . $category->getThumbnail() ?>" alt="<?php echo $this->htmlEscape($category->getName()) ?>" />
                <span><?php echo $category->getName() ?></span></a>
        </li>
    <?php endforeach; ?>
</ul>

In the code above we’re simply loading the category children that belong to the current category, and display them with their names and thumbnails in an unordered list. You could alternatively add ‘image’ to the addAttributeToSelect() call, then use the following to bring out the category image, rather than the thumbnail:

$category->getImageUrl()

2. Create Static Block

Go to CMS > Static Blocks and create a new static block with the following information:

Name: Subcategories
Code: subcategories
Status: Enabled
Content:

{{block type="core/template" template="catalog/category/sub.phtml"}}

This simply assigns the template we’ve just created with a ‘core/template’ block type to this static block.

3. Assign Static Block to Parent Category

Find the parent category that you want to show subcategories on, then go to the ‘Display Settings’ tab. Switch ‘Display Mode’ to either ‘Static block only’ or ‘Static block and products’, then choose your newly create ‘Subcategories’ block from the ‘CMS Block’ menu. Then save.

Config Categories
Configure your category to show the static block

If you check your sites frontend you should now see the subcategories appearing:

Subcategories
Subcategories in all their beauty

I’ve added the CSS I used in my example below to get you started. Thanks for reading!

.subcategories li { float: left; display: block; text-align: center; margin: 10px}
.subcategories li span { display: block; margin: 8px 0}
  • pete

    Hi – Looks like exactly what I need, but where is catalog/category/ files? I am using filezilla.

    • http://twitter.com/joemikepress Michael Press

      I know you posted this two months ago but I figured I would reply so that future visitors have a reference. The full file path is:

      app/design/frontend/default/THEMENAME/template/catalog/category/

      Replace THEMENAME with the name of the Magento theme you’re currently using.

  • Antonio Mineiro

    Nice one, Thanks.

  • Shane Taylor

    This seems like a very easy method. But I’d like to have it just be the default behaviour for all categories that have sub categories instead of having to change all the categories to display a static block. Future maintainers may miss that detail when configuring the many options. How does one add this functionality directly into the theme layout?

  • http://twitter.com/joemikepress Michael Press

    Thanks Adam, this worked great!

  • involatus

    Yeah, works great.
    But how is it possible to show it as the same order as in normal Menu. I’m not sure what’s now the sort criteria.

    What needs to be added? Thanks!

  • Dan ward

    Involatus – what you are looking for in terms of sort order is: ->setOrder(‘position’, ‘ASC’)

    Add this line of code before the addIdFilter and it will pull them out in the right order :)

  • Andy Lewis

    Is there a way to modify the code in order to list out subcategories of subcategories? For instance, I have a garage, then my options that work are painted and vinyl. Then Under painted, I want to show sizes like 10×12, 12×24, etc. When I try to use the same configuration, I get the original painted image on the 10×12 page as well. Any help would be appreciated.

    Thanks!

    • Andy Lewis

      Can anyone help me with this?

  • Graeme

    Great solution, thanks. Just one thing though (as already mentioned by Francois). Where should I insert the CSS code you provided? Without this it just appears as a vertical list (I’m new to all this stuff as well). Thanks in advance.

  • Rp

    This is what I am looking for but the $category->getThumbnail() does not return anything even though I have uploaded a thumbnail for the category. All is get is the Alt value. Ideas?

    • Rp

      Never mind. Uploaded thumb to the parent category, not the sub category. Working now. Thanks for this!

  • Dan Siop

    How can I show the description of the subcateogry?

    • Adam Moss

      Simply load it into your addAttributeToSelect(‘description’), and call with $category->getDescription();

  • David Liberacion

    Awesome! Thank you! Works like a charm. In my case I just have to change echo Mage::getBaseUrl('media') . 'catalog' . DS . 'category' . DS . $category->getThumbnail() to echo Mage::getBaseUrl('media') . 'catalog' . '/' . 'category' . '/' . $category->getThumbnail() For some reason DS place instead of / in the url.

  • Ben Y

    Hi. Adam – Thanks for the easy tutorial. I’ve managed to get it all working apart from the styling. I need the last image on each row to have no padding on the right. I’ve attached an image to show where I mean. Can anyone point me in the right direction? Many thanks

    • Tom Foyster

      Hi Ben. What you’ll need to do is add a class to every third item so you can reference it in the CSS and remove the margin. The theory is;

      – Set up a count variable that iterates every time your foreach loop is processed

      – Using the Modulus (see below) operator, you can see if this is the 3rd item in the row

      – If so, add a class to the li or a element to remove the margin.

      I’ve included a but of psuedo code below (check out the Modulus operator here http://www.php.net/manual/en/language.operators.arithmetic.php)

      $count = 0;
      foreach(categories) {
      $count++;
      $class = ”;
      if($count % 3 == 0) {
      $class = ‘no-margin’;
      }
      echo ‘…’;

      }

      Thats the rough code, let me know how you get on!

    • Adam Moss

      Hi Ben, I’ve done a tutorial about modulus here: http://www.creare.co.uk/alternating-php-loops-with-modulus

  • Ben Y

    Image

    • Adam Moss

      Hi Ben, you need to work out the width & padding you need on each image to make it even. You’ll need to remove the margin/padding from every third image so you’ll want to put an iterator into your loop which says ‘if this is image 3, then add this class’ which will remove the margin/padding.

  • Vicki

    Hello – Thank you for the tutorial. I have this all working but the urls generated for sub categories appear with // at the end of the link instead of the correct url path e.g. /accessories.html – Any ideas? Thanks in advance.

    • Tom Foyster

      Hi Vicki – can you share the code that produces the links on your page? Thanks :)

  • Jai Molloy

    Hello Adam, great work. I have used this in 2 projects, but both have asked to have the subcategories to show in the order of the backend, not the order of ID. How can we do that?

    • Jai Molloy

      And here is the solution to my question:

      $category = Mage::getSingleton(‘catalog/layer’)->getCurrentCategory();
      $categories = $category->getCollection()
      ->addAttributeToSelect(array(‘name’, ‘thumbnail’))
      ->addAttributeToFilter(‘is_active’, 1)
      ->addAttributeToSort(‘position’)
      ->addIdFilter($category->getChildren())

      • Tom Foyster

        Nicely done Jai, exactly the way I would have done it!

        • Jai Molloy

          I have a problem with another navigational issue (not related to anything from you guys), that others may find usefull. I have tried to get help on stackexchange and the magento forums (littered with spambots).

          Would you guys be able to help, simple stupid thing, very useful.

          Let me know.

      • http://www.waaab.net/ Attila Bogozi

        Great. Thanks
        What if I need the sub-sub categories?

  • mitchel

    Sir,

    Thank you for the instructions!

    I have a question.
    The subcategories are now under each other, how can I set them next to each other?
    The names of the subcategories are now at the right of the image, how can i set them under the image?

    Thank you,
    Mitchel

  • didip

    Thanks,
    I added the code via XML instead of a block, because the block somehow wasn’t working.
    I’m now trying to figure out how to add category description to have some SEO on the page. Does anyone have a solution?

  • Fields

    Hey Adam,

    Great writeup. Just one question (which seems to be pretty popular below)…how do you make it so the products are arranged in columns? I see the CSS code, but I’m not sure on the placement.

    Thanks

  • mitchel

    Hi Adam,

    I have a question, how can I make the subcategories alfabetic?

    With best regards,
    Mitchel Kooyman

    • Nath

      Hi,

      Did you find how to make the subcategories alfabetic ?

      regards,
      Nath

      • Jai Molloy

        you need to use it like this:

        $category = Mage::getSingleton(‘catalog/layer’)->getCurrentCategory();
        $categories = $category->getCollection()
        ->addAttributeToSelect(array(‘name’, ‘thumbnail’))
        ->addAttributeToFilter(‘is_active’, 1)
        ->addAttributeToSort(‘name’, ‘ASC’);
        ->addIdFilter($category->getChildren())

        • jscar

          should you have the semi-colon after ->addAttributeToSort(‘name’, ‘ASC’)

          • Jai Molloy

            looking at it now, after almost a year of it working and it being online… you are right 😉

  • Uththama Gamage

    Nice Work, How to display 3rd and 4th level Subcategories on this method? Does anyone can help

    • Bhargav Mehta

      Hey,
      Did you find out the way to do it?

  • http://www.homegardenandconservatory.co.uk Gillian

    where does the CSS go?

  • http://www.homegardenandconservatory.co.uk Gillian

    Thank you – worked a treat!

    How do I make the subcategories appear as a grid rather than a list?

  • Bhargav Mehta

    Hi,
    How can I show second level and 3rd level sub categories in static block?

  • Vikas Rana

    really nice post thanx a lot for sharing

  • AJL

    Thank you! I had to change “thumbnail” to “image” in addAttributeToSelect() and then change the image path to src=”getImageUrl() ?>” in order to use my category pictures. Exactly what I needed otherwise!

    • http://www.mathewporter.co.uk/ Mathew Porter

      I also changed thumbnail to image, but had to change src to getImageUrl() ?> with Magento 1.9.2

  • http://succulentas.com Samuel Nieves

    None of these are work for 1.9.2. I’ve tried what AJL and @matt_porter:disqus changed, but no luck.

  • Made

    Hi guys, that’s tutorial it’s working on magento 1.9, so i say big thanks that’s helpfull. But i want to display the children inside subcategories.
    for example, i have categories like : Brand, and inside Brand there’re categories again like KTZ, Boutique and etc.
    how to make like that using the code above.

  • Mike

    I put the css code at the bottom of skin/frontend/default//css/styles.css

  • Eric

    Not able to get it to list out left to right will only show list top to bottom. Added CSS and it seems right but still no luck in getting it to show side by side

  • Darren

    Hi guys, has anyone got a fix / method for using this with 1.9.2.3 – the new version cache’s static blocks now so when you go into subcategories the block does not update to list the current sub categories. Any ideas would be great..

    • Markus Peikert

      Hi Darren,
      did you find a solution, i have the Cache Problem too now!?
      Best regards
      Markus

      • meshan

        Hi

        I am having same issue cache problem, have you found solution?

  • David Lumley

    I am new to MAgento and assume I am asking a fundamental question here – I have installed without any skin or theme so am trying to work out where Ireate the category directory for the php above (sub.phtml)
    I am assuming root/app/code/core/Mage/Catalog but am not confident :)

  • Darren Hurley

    Hi, you will find you need to put the .sub.phtml in the app/design/frontend/default/your-theme/template/catalog/category/sub.phtml hope it helps. You should never need to touch any core files.

  • Brian

    I have changed “thumbnail” to “image” and using src=”getImageUrl() ?>” to get the category image. It gives the path to the image but not the file name. Any ideas? I’m using 1.9.2.4

  • sapna

    Hi, i have tried this tutorial . It is not working for me , Can you please help me i am using 1.9 version.