How to add static blocks to main navigation dropdown?

How to add static blocks to main navigation dropdown? © forwardcom@sxc.hu

Many stores require some additional information in the main navigation drop-down section. Displaying only subcategories might not always be enough and I noticed this is becoming a trend on shopping sites now days. Although there are many ways to accomplish this (including building you own custom module) I would like to show you a more clever way that will allow you to use static blocks and easily connect them with product categories. To better understand what I am talking about see the sample image of the end result below.

Static block in main navigation

The idea

Magento 1.6 and earlier
The general idea is to use static blocks because they are easily editable and can hold many different types of content. The problem with static blocks is that you cannot assign them directly to product categories in Magento, or can you? Here’s an idea, set the “Identifier” value of the static block to be the same as the “URL Key” of the desired category. Now you have a logical connection between your static block and a product category. We just have to display the appropriate static blocks in the main navigation drop-down.

Magento 1.7
Now, in version 1.7 Magento introduced a completely new way of rendering menu items (thanks Johnboy for reminding me) that require some changes for this to work. The general idea is the same as above (for Magento 1.6) but this time we need to use something else instead of “URL Key” to connect our static block to a category. This time we will use the category ID value with a simple string prefix.

The implementation

Magento 1.6 and earlier
To implement this simple idea we need to override a core Magento block class and add a few lines of code to a single function. How simple is that 🙂

  1. First we need to override the core Magento block class by copying the block file from core to local folder. We are going to use “Mage_Catalog_Block_Navigation”class so we need to copy:
    /app/code/core/Mage/Catalog/Block/Navigation.php

    to

    /app/code/local/Mage/Catalog/Block/Navigation.php

    If you don’t have a folder structure in your local folder you will need to create it.

  2. Find the protected function _renderCategoryMenuItemHtml (should begin at around line 218). This is the function that will render all the menu items which is exactly what we need.
  3. Now find this piece of code (lines 309-312):
    $html[] = '<ul class="level' . $level . '">';
    $html[] = $htmlChildren;
    $html[] = '</ul>';
  4. Add the following code just above the line with the closed ul tag:
    $staticBlock = trim($this->getLayout()->createBlock('cms/block')->setBlockId(strtolower($category->getUrlKey()))->toHtml());
    if(!empty($staticBlock)){
    	$html[] = '<span class="nav-static-block" style="background:#fff; border-top:1px solid #ccc; padding:10px;">';
    	$html[] = $staticBlock;
    	$html[] = '</span>';
    }

    The end result should look like this:

    $html[] = '<ul class="level' . $level . '">';
    $html[] = $htmlChildren;
    $staticBlock = trim($this->getLayout()->createBlock('cms/block')->setBlockId(strtolower($category->getUrlKey()))->toHtml());
    if(!empty($staticBlock)){
    	$html[] = '<span class="nav-static-block" style="background:#fff; border-top:1px solid #ccc; padding:10px;">';
    	$html[] = $staticBlock;
    	$html[] = '</span>';
    }
    $html[] = '</ul>';

    The implementation is simple, check if there is a static block with the identifier value that is the same as the current category URL Key. If so, add the static block to the menu.

    I used some inline CSS for the sake of simplicity but you should use your own.

  5. Now you need to create a static block with the identifier value set to whatever category URL Key you want and you are all done! I used the default Magento sample data and created a static block with the identifier set to “furniture” because that is the URL Key of the Furniture category.

Magento 1.7
This time we need to override a different Magento core class because in 1.7 Magento uses  Mage_Page_Block_Html_Topmenu to render the main menu.

  1. First we need to override the core Magento block class by copying the block file from core to local folder. We need to copy:
    /app/code/core/Mage/Page/Block/Html/Topmenu.php

    to

    /app/code/local/Mage/Page/Block/Html/Topmenu.php

    If you don’t have a folder structure in your local folder you will need to create it.

  2. Find the protected function _getHtml (should begin at around line 84).
  3. Now find this piece of code (lines 121-123):
    $html .= '<ul>';
    $html .= $this->_getHtml($child, $childrenWrapClass);
    $html .= '</ul>';
  4. Add the following code just above the line with the closed ul tag:
    $staticBlock = trim($this->getLayout()->createBlock('cms/block')->setBlockId($child->getId())->toHtml());
    if(!empty($staticBlock)){
    	$html .= '<span style="background:#fff; border-top:1px solid #ccc; padding:10px;">';
    	$html .= $staticBlock;
    	$html .= '</span>';
    }

    The end result should look like this:

    $html .= '<ul class="level' . $childLevel . '">';
    $html .= $this->_getHtml($child, $childrenWrapClass);
    $staticBlock = trim($this->getLayout()->createBlock('cms/block')->setBlockId($child->getId())->toHtml());
    if(!empty($staticBlock)){
    	$html .= '<span class="nav-static-block" style="background:#fff; border-top:1px solid #ccc; padding:10px;">';
    	$html .= $staticBlock;
    	$html .= '</span>';
    }
    $html .= '</ul>';

    The implementation is simple, check if there is a static block with the identifier value set to current category ID with a prefix “category-node-“. If so, add the static block to the menu. The prefix is used because if you inspect the value of $chlid->getId() you will see that it returns a category ID with that prefix so, for example, if the category ID is “10” you will get “category-node-10”. I used this value because it is unique for each individual category.

    I used some inline CSS for the sake of simplicity but you should use your own.

  5. Now you need to create a static block with the identifier value set to whatever category Prefix+Category ID you want and you are all done! I used the default Magento sample data and created a static block with the identifier set to “category-node-10” because Furniture category has the id of 10. That’s it.

Hope you’ll find this post helpful.

You made it all the way down here so you must have enjoyed this post! You may also like:

Custom category menu navigation in Magento Petar Sambolek
Petar Sambolek, | 16

Custom category menu navigation in Magento

Create Magento Dropdown Login in a few minutes Petar Sambolek
Petar Sambolek, | 17

Create Magento Dropdown Login in a few minutes

Modify “Interface locale” dropdown in administration Tomas Novoselic
, | 18

Modify “Interface locale” dropdown in administration

28 comments

  1. Is there a way in Magento 1.7 that the category can be a Top Navigation and at the same time it’s a subnavigation from another Top Menu? I’m trying to understand your code if this can help me. Looking forward to it. Thanks!

  2. Hi, I just tried under magento 1.9.1.0. But it not works. I think the problem is my static block is not associate with one of the categories. I’m confused of your words ” If so, add the static block to the menu.” Can you help me out?
    Regards!

  3. Anyone tried this with more than 1 category. I have it working but when I add a second category its populated with the same block content as the first. Caches cleared, flushed and reindexed but no dice.

  4. Regarding all the comments about floating the static block, this post is about functionality and how you can connect a category with a static block in the main navigation menu. Position and HTML structure of elements is not what I was aiming for because it depends on a particular design and template. On the other hand, it’s simple HTML and CSS which should not be a problem for a developer working in Magento.

  5. Nice tutorial, but one problem, the images are not https secured, which causes the page only partially secured. The Https Color bar is disappeared at secure pages, like login, my account, etc.

  6. I have same question aswell like Lucia had before. How can I move the static block to the right? I see no option to implement float:right anywhere in the code

    Lucia G.
    10-07-2012 at 20:03 | #

    First of all, Thank you so much for your posting.
    It’s really what I need. awesome!
    It could be added some images with static block.

    May I ask a favor of you?

    How can I move a static block to right side of the sub categories instead bottom side?

  7. If I use the standard template (default) it works great, but when I use my own template I don’t see a change when I edit the file app/code/local/Mage/Page/Block/Html/Topmenu.php . Can anyone help me?

  8. Hi

    Add these lines in template/page/html/topmenu.phtml

    <a class="level-top" href="getUrl() ?>”>__(‘Home’) ?> <a href="getUrl(‘customer-service’) ?>” class=””>Customer Service

  9. Hi ,

    Use this to remove p tags

    $html .= ”;
    $html .= $this->_getHtml($child, $childrenWrapClass);
    $staticBlock = trim($this->getLayout()->createBlock(‘cms/block’)->setBlockId($child->getId())->toHtml());
    if(!empty($staticBlock)){
    $html .= ”;
    $staticBlock =preg_replace(array(‘##’, ‘##’), ”, $staticBlock, 1);
    $html .= $staticBlock;
    $html .= ”;
    }
    $html .= ”;

  10. Dear Inchoo,

    thanks for this article. Im my case I want to replace the whole main navigation with a static block and I wonder where I can add this code: getLayout()->createBlock(‘cms/block’)->setBlockId(‘navigation’)->toHtml(); ?>. I also tried to add navigation to my page.xml but this does not work. Please help me…

    Best regards,
    Marcus

  11. Thanks for the tutorial, works great for adding in a graphic to the nav on a project that im working on.

    Just wondering if I could possibly get the block to be generated outside of the that is built?

  12. Hi guys, this tutorial is awesome, got it working great except my nav won’t load the static blocks on the product pages. Works fine on home and category pages. Anyone else having this problem?

  13. i did the same steps for magento 1.7 but for topmenu.php it still uses the con\re one & don’t over ride it how can i over ride it?

  14. First of all, Thank you so much for your posting.
    It’s really what I need. awesome!
    It could be added some images with static block.

    May I ask a favor of you?

    How can I move a static block to right side of the sub categories instead bottom side?

  15. Hey Srdjan,

    Great article. Do you know if it’s also possible to get the category id for each item in the navigation and to be able to add extra CSS classes for certain dropdowns to style them differently?

    1. Yes you can get the category id for both versions (1.6 and 1.7). It’s just a little bit different.
      For Magento 1.6: $category->getId();
      For Magento 1.7: substr($child->getId(), strrpos($child->getId(), ‘-‘) + 1);
      The thing is, in Magento 1.7 $child->getId() returns a string with the “category-node-“ prefix (you get the following format “category-node-4”) so we need to extract the id from it by using some standard PHP sting functions.

      As for the CSS classes I added one (“nav-static-block”) for categories that have static blocks but you can use the category id from above to specify the class for every item in the menu which you can then style with CSS.

  16. No problem, the changes caught me out with a module I had been working. Took me a while to work out why the hell my extra menu item had dissappeared.

    1. Thank you Johnboy for pointing that out. I updated the post to include a version that works in Magento 1.7

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.