How to list categories in the header in OpenCart

I’m working on a one column layout theme for OpenCart. This of course means that there are no sidebars at the left or right hand side so, as well as putting the cart in the header area, I needed to list the top level categories in the header. This is how I did it without editing the OpenCart source code.

I searched the OpenCart forums for a long time and didn’t find a solution I was happy with. All the solutions I found involved creating new modules and/or editing source code to include them in the header. Finally, with only a basic knowledge of PHP, I decided to jump in and try and write my own solution, and after a lot of trial and error (and many, many error messages) I got it working and it seems to work without any issues.

I started with the getCategories function from catalog/controller/module/category.php. Here it is:

protected function getCategories($parent_id, $current_path = '') {
$category_id = array_shift($this->path);
$output = '';
$results = $this->model_catalog_category->getCategories($parent_id);
if ($results) {
$output .= '<ul>';
}
foreach ($results as $result) {
if (!$current_path) {
$new_path = $result['category_id'];
} else {
$new_path = $current_path . '_' . $result['category_id'];
}
$output .= '<li>';
$children = '';
if ($category_id == $result['category_id']) {
$children = $this->getCategories($result['category_id'], $new_path);
}
if ($this->category_id == $result['category_id']) {
$output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '"><b>' . $result['name'] . '</b></a>';
} else {
$output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '">' . $result['name'] . '</a>';
}
$output .= $children;
$output .= '</li>';
}
if ($results) {
$output .= '</ul>';
}
return $output;
}

I put this in the header template file, header.tpl, and ran it but it threw up a lot of errors. I then went through it bit by bit and stripped it right down. I could detail the whole process but that would be dull. In the end, the code that worked was this:

<?php
$this->load->model('tool/seo_url');
$results = $this->model_catalog_category->getCategories();
if ($results) {$output = '<ul>';}
foreach ($results as $result) {
$output .= '<li>';
$new_path = $result['category_id'];
$unrewritten = HTTP_SERVER.'index.php?route=product/category&path='.$new_path;
$rewritten = $this->model_tool_seo_url->rewrite($unrewritten);
$output .= '<a href="'.str_replace('&', '&amp;', $rewritten).'">'.$result['name'].'</a>';
$output .= '</li>';
}
if ($results) {$output .= '</ul>';}
echo $output;
?>

And that’s all you need. No extra modules or adding code to four or five files. Just put the above code in your header and it will list your top-level categories. It works with both the default URL structure and with the SEO friendly URL option. If you want to create a navigation bar that also displays sub-categories, in drop-downs for example, you’ll probably have to do something different, but I’m happy with this solution. It’s light, doesn’t affect the OpenCart source code, and I’m not a huge fan of drop-downs anyway.

This entry was posted in OpenCart Mods. Bookmark the permalink.

26 Responses to How to list categories in the header in OpenCart

  1. Matt89fe says:

    Hi!
    thank’s for your knowledge sharing
    but how can i display sub-categories?

  2. Craig says:

    Hi Matt, glad I was of some help. I haven’t worked out a way to display sub-categories yet that I’m completely happy with. Channelcommerce has posted a way to do it which is pretty good here:
    http://forum.opencart.com/viewtopic.php?f=23&t=14674

  3. Matt89fe says:

    Yes, i read this just before than your post but your solution it’s better since it’s light and to cite you: “No extra modules or adding code to four or five files”

  4. Craig says:

    Hi Matt, happy to hear you think mine is better. I’ve adapted the script for you so that it lists sub-categories too. It only lists the first sub-level, but you should be able to extend it if you have more than one sub-level. You can find it here:
    How to list all categories and sub-categories in the header in OpenCart

  5. Matt89fe says:

    I’m glad to read this :)
    I’ll give a try but i’m sure it’s work a charm!

    I’ll tell you asap!

  6. Craig says:

    Hi Matt. I discovered a bug in the script that stopped it working on the home page when SEO URLs were being used. I needed to load the seo_url tool. I’ve fixed it now in both versions, as you’ll see from the first line of the code.

  7. Matt89fe says:

    wow, it works very very well!!
    contact me via my mail address and tell me your paypal account (or similar) ;) i’ll be glad to buy you a coffee or beer or something ;)
    greetings from italy

  8. steve firth says:

    Awesome job m8 …

    nice n brief, v effective and worked like a charm!

  9. Pingback: How to highlight current category in the header in OpenCart | DIY E-Commerce

  10. Pingback: How to exclude some categories when listing categories in the header in OpenCart | Craig Murray

  11. Robert says:

    Hi!

    I tried out your code snippet and it works fine! Thanks.

    But I would also like to add the category image in the header. I tried searching the OC forum but I didn’t find what I was looking for.

    Perhaps you have a clue how to do this? :)

  12. Craig says:

    Hi Robert,
    The getCategories() function also retrieves the image data for the category. To output that image info all you need to output is $result['image']. If there is an image it will have a value such as this: data/imac_1.jpg. If there is no image it will be empty, so you’ll need to check for that and output the location of a placeholder image instead.
    Hope that helps.

  13. silk says:

    First many many thanks for this masterpiece it is so simple and works fine. I had been looking many nights before I found this.
    Like the post before I want to display the categories image instead of the text. I tried as it was suggested but I guess I missed something since only the names of the images are displayed and not the pictures. I am not a php programmer and only adjust scripts so I guess I missed something. Could you please direct me to the right path?

    $output .= $result['image'];

    Here is you see:
    data/button1_.pngdata/button2.pngdata/button3.pngdata/button4.pngdata/button5.png

    Thank you for you kind assistance
    Cheers
    Silk

  14. Craig says:

    Hi Silk, thanks for the compliments. Basically all you have to do is link to each image using the output. Currently it is outputing “data/button1_.png” etc.

    All you have to do is add the route to the image before that. It will be something like this: http://www.yoursite.com/image/cache/

    So when outputing the results, just add this (or your own version of this):

    <img src="http://www.yoursite.com/image/cache/<?php echo $result['image']; ?>">

    If you need anymore help, please get in touch.

  15. silk says:

    Thank you for your help.
    I tried
    <!– $output .= '<a href=”‘.str_replace(‘&’, ‘&’, $rewritten).’”>’.<img src="http://www.mydomain.com/image/cache/”>.’</a>’; –>

    in all kinds of variations. However I get 2 the following messages: wrong “>” or wrong “string”. Do you have any idea?
    Thank you again
    Silk

  16. Craig says:

    Hi Silk, I think it should be like this:

    $output .='<img src="http://www.yoursite.com/image/cache/'.$result['image'].'" />';

    Let me know if that works.

  17. silk says:

    Hi Craig
    Thank you again for your help. The images do show now!
    I had to use /image/data/ instead of /images/cache/
    Only the category links are lost now. I tried to look things up in my php handbooks. However either the category images or the links work but they never go together. If you have an answer at hand how I get the images with the links I would very appreciate it.
    However I really do like your work and appreciate your help. Therefore I have tried to do my little bit to help you with your Christmas drinks.
    Cheers, Silk

  18. Craig says:

    Hi Silk, firstly many thanks for the kind donation. It’s very much appreciated. Secondly, try this and let me know if it works.

    $output .= '<a href="'.str_replace('&', '&amp;', $rewritten).'"><img src="http://www.yoursite.com/image/data/'.$result['image'].'" alt="'.$result['name'].'" /></a>';

  19. silk says:

    GREAT!!!!!
    (This time I had to delete data/ :-)

    It works fine. As soon the site is finished I will send you the link to see it.

    Many thanks, Silk

  20. Craig says:

    Very cool. Glad to be of help. Look forward to seeing the site.
    All the best, Craig

  21. Tobbe says:

    Hi!
    Great work, thank you very much. Do you know how to do this?
    When i choose a category from the header I would like the category box to show only the sub-categories from that main category. I have search the oc forum and cannot find a solution that works. The solutions i have found dos not work properly.
    V 1.4.9.3

    Regards Tobbe

  22. Craig says:

    Hi Tobbe,
    You’re in luck. Just today I posted a solution to your problem on the OpenCart forums.
    http://forum.opencart.com/viewtopic.php?f=20&t=24594.
    Let me know if that is what you are after.
    Craig

  23. Tobbe says:

    Hi,
    That is what I am after, but I get an error message. I have posted a comment in the forum. I hope you can tell me what’s wrong.
    Thank you very much.
    Tobbe

  24. Craig says:

    Hi Tobbe, my bad – I made a schoolboy error. Have posted a fix now.

  25. Dirk says:

    Hi Craig,

    I was thrilled i finally found the solution i was looking for but my menu just shows up verticaly, not horizontal. Also the textlinks are basic with a dot you get without css or someting:

    I copied a complete headerfile from someone elses site where it did work as a test and it doesn’t work with me. I’m using the latest version of open cart.

    Hope you can help!

    Thanks

  26. Craig says:

    Hi Dirk,

    Yes, the output is just an unsorted list. You need to add styles in the stylesheet to turn it into a navigation bar. Here is one solution:
    http://www.alistapart.com/articles/slidingdoors/

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=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>