OpenCart header navigation (three level list)

OpenCart header navigation (three level list)Recently, I had a bite of Open Cart to build a new website for a client. Its still in development, but the outcome seems promising. I have to say, as much as I had heard about Open Cart, it really is a great piece of web application. My journey with shopping carts have been restless. I have had tough times with OSCommerce, played enough with ZenCart, dealt with the terrible NiagaKit, and even adventured on my favorite enterprise level Magento. While Magento is still the best for me, Open Cart is just the next one for me. Reason why Open Cart is behind Magento is only because of the number of features that it has. For my carts that need enterprise love, I use Magento for them. For all others, Open Cart is my choice now.

So, I was modding a custom made theme for a client who will be selling products on his very own Open Cart. I realized that it did not have header navigation. Actually, it did not have category list tables. The current category.tpl template file calls the categories available for the viewed page only. While Open Cart will be implementing listed categories in the next version, my client couldn’t wait. So I had to do what I had to do.

Google! Thats where I found Craig Murrays neat category list code. The code works, but apparently he limited it to two level navigation only. The parent and a child. I think for a shopping cart, the maximum navigation levels should be three rather than two. In my clients case who was selling hijabs, she needed three level navigation. eg: hijab -> the type of hijab -> the material. So I took Craig’s code and modified it into a three-level navigation. The generated list item will look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<ul>
   <li>First Level</li>
   <li>First Level
      <ul>
         <li>Second Level</li>
         <li>Second Level
            <ul>
               <li>Third Level</li>
               <li>Third Level</li>
            </ul>
         </li>
         <li>Second Level</li>
       </ul>
   </li>
   <li>First Level</li>
</ul>

Once you have this list, you can give it some CSS touch and use Superfish or most other jQuery scripts to add the animation effect for added functionality. Now here is the PHP code to generate this list (along with descriptions on what each line does):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php 
 
$this->load->model('tool/seo_url');
 
$results = $this->model_catalog_category->getCategories();  									// get the categories
 
if ($results) {$output = '<ul class="you-can-define-a-class-here-for-your-javascripts">';}  									// if there are categories available, start off with the unordered list tag
 
foreach ($results as $result) {																	// for each result
	$output .= '<li>';																			// put a list item tag
	$new_path = $result['category_id'];															// get the id of this category
	$unrewritten = HTTP_SERVER.'index.php?route=product/category&path=' . $new_path;			// if the seo url is disabled, this will be the path
	$rewritten = $this->model_tool_seo_url->rewrite($unrewritten);								// otherwise, it will be this one
	$output .= '<a href="' . $rewritten . '">' . $result['name'] . '</a>';						// finally, generate the category name and wrap its link
 
	$sub_results = $this->model_catalog_category->getCategories($new_path);						// if this result has a sub-list, get the set of new categories
 
	if ($sub_results) {$output .= '<ul>';}														// if this is a subresult, start off with an unordered list tag
 
	foreach ($sub_results as $sub_result) {														// for each of this subresult item
		$output .= '<li>';																		// put a list item tag
		$new_sub_path = $sub_result['category_id'];												// get its category
		$sub_unrewritten = $unrewritten.'_'. $new_sub_path;										// if the seo is disabled, this will be the path
		$sub_rewritten = $this->model_tool_seo_url->rewrite($sub_unrewritten);					// otherwise, it will be this one
		$output .= '<a href="' . $sub_rewritten . '">' . $sub_result['name'] . '</a>';			// now, generate the category name and wrap its link
 
		$third_sub_results = $this->model_catalog_category->getCategories($new_sub_path);		// if this result has a sub-list, get the set of new categories
 
		if ($third_sub_results) {$output .= '<ul>';}											// if this is a subresult, start off with an unordered list tag
 
		foreach ($third_sub_results as $third_sub_result) {										// for each of this third level item
			$output .= '<li>';																	// give it an opening list tag
			$third_sub_path = $third_sub_result['category_id'];									// get its category
			$third_sub_unrewritten = $sub_unrewritten.'_'.$third_sub_path;						// if seo is disabled, this is the path
			$third_sub_rewritten = $this->model_tool_seo_url->rewrite($third_sub_unrewritten);	// if its enabled, this will be the path
			$output .= '<a href="'.$third_sub_rewritten.'">'.$third_sub_result['name'].'</a>';	// call the category name and wrap with its link
			$output .= '</li>';																	// now close this list item
		}
 
		if ($third_sub_results) {$output .= '</ul>';}											// if this was the third list, clost the list
			$output .= '</li>';																	// then or otherwise, close the second level list tag
	}
	if ($sub_results) {$output .= '</ul>';}														// if all sub results have been listed, close the second level
		$output .= '</li>';																		// then or otherwise close first list parent
}
if ($results) {$output .= '</ul>';}																// then close the first level list table
echo $output; 																					// now produce the results
?>

I hope that helps for some of you guys looking forward to add this to your Open Carts. Open Source..ftw!

Shahz

Print
  1. Patrick
    #1 written by Patrick  (2 years ago)

    Thanks! I really like your code but would like to add a feature:

    I’d like to assign a class to that li-tag which is active.
    Like:

    Could you help me out?

    Best, Patrick

  2. Shahz
    #2 written by Shahz  (2 years ago)

    Pretty simple if you ask me..If you want to assign the same class to every list item, change these lines:
    $output .= ‘< li >‘;
    to:
    $output .= ‘< li class="the-class-name" >‘;

    and if you want to assign dynamic classes to each of the list items, since each category has its own id, and since we are calling out each id using the $new_path variable, you can integrate the $new_path variable within the $output variable..

    Hope that helps :)

  3. Patrick
    #3 written by Patrick  (2 years ago)

    Oh thank you. But I only want to output the class “active” for that li-element which belongs to the current page/category.

    For example: If I have a category called “shoes”, I just want to add the class (to that particular li which contents the link to cat. “shoes”) if a page of that category (or subcat.) is displayed.

    Goal is to highlight the current/active category in the list-menue.

  4. George
    #6 written by George  (2 years ago)

    Works great! Thank you so much

  5. dominikus
    #7 written by dominikus  (2 years ago)

    thanks for sharing, I’m try to implemented ;)

  6. visitor
    #8 written by visitor  (2 years ago)

    thanks, nice work!!

  7. Tone
    #10 written by Tone (2 years ago)

    Works Great. Great Appreciation. How do i assign a class to only lists that are expanding again for ex:

    Example
    Example
    Example Expanding

    Example

    Example

    The reason is i want to be able to put an arrow Background to show theres more on that list.

    thanks

    • Shahz
      #11 written by Shahz  (2 years ago)

      Dependnig on your code, here is one way to do it:
      Replace:
      $output .= ‘‘;
      to:
      $output .= ‘‘;

      • Shahz
        #12 written by Shahz  (2 years ago)

        Ignore that..It didn’t post the html..lol..

        $output .= ‘‘;
        to:
        $output .= ‘‘;

        • Shahz
          #13 written by Shahz  (2 years ago)

          Ignore that too..Read the comment #2 up there..

  8. sijo thomas
    #14 written by sijo thomas  (1 year ago)

    when i put this code in header.tpl i’m getting this Error: Could not load model tool/seo_url!
    I’m using Open Cart v1.5.0.5….Any help will be appreciated….

  9. sijo thomas
    #15 written by sijo thomas  (1 year ago)

    ya its woking …..nice and great script…

  10. vishu
    #16 written by vishu  (1 year ago)


    sijo thomas:

    i’m also getting this Error: Could not load model tool/seo_url!
    I’m using Open Cart v1.5.0.5….Any help will be appreciated

    when i put this code in header.tpl i’m getting this Error: Could not load model tool/seo_url!
    I’m using Open Cart v1.5.0.5….Any help will be appreciated….

  11. Allen Conquest
    #17 written by Allen Conquest  (1 year ago)

    I think v1.5.x has changed the way is works. Look at information/sitemap.tpl to see how the categories are now retrieved.

    I’ve not tried it yet, but I think the line is: $this->load->model(‘catalog/category’);

  12. Allen Conquest
    #18 written by Allen Conquest  (1 year ago)

    Ok, I got it working using a few modification. It’s not doing the SEO rewrites, I’m not sure how to do that at the moment:

    //$this->load->model(‘tool/seo_url’);
    $this->load->model(‘catalog/category’);

    $results = $this->model_catalog_category->getCategories(0);

    if($results)
    {
    $output = ”;
    }

    $output .= ‘Home‘;

    $counter = 0;

    foreach ($results as $result)
    {
    // HTML
    $output .= ”;

    // Grab the specific category, reset each loop
    $new_path = $result['category_id'];

    // Prepare the URL
    $unrewritten = HTTP_SERVER.’index.php?route=product/category&path=’ . $new_path;

    // Pass it to the SEO URL tool
    // $rewritten = $this->model_tool_seo_url->rewrite($unrewritten);

    // Output the path and category name
    $output .= ‘‘ . $result['name'] . ‘‘;

    $counter++;

    // Next level deep with the current category as the parameter.
    // Children of
    $sub_results = $this->model_catalog_category->getCategories($new_path);

    // If there are subs
    if ($sub_results)
    {
    // HTML
    $output .= ”;
    }

    foreach ($sub_results as $sub_result)
    {
    // HTML
    $output .= ”;

    // Allocate the new sub category
    $new_sub_path = $sub_result['category_id'];

    // Get the raw URL and prepare it
    $sub_unrewritten = $unrewritten.’_’. $new_sub_path;

    // Rewrite it
    // $sub_rewritten = $this->model_tool_seo_url->rewrite($sub_unrewritten);

    // Output as usual
    $output .= ‘‘ . $sub_result['name'] . ‘‘;

    // Grab the specific category, reset each loop
    $new_sub_path = $sub_result['category_id'];

    // Next level deep with the current category as the parameter.
    // Children of
    $sub_sub_results = $this->model_catalog_category->getCategories($new_sub_path);

    // If there are subs
    if ($sub_sub_results)
    {
    // HTML
    $output .= ”;
    }
    else
    {
    $output .= ”;
    }

    $counter2 = 0;
    foreach ($sub_sub_results as $sub_sub_result)
    {
    // HTML
    $output .= ”;

    // Allocate the new sub category
    $new_sub_sub_path = $sub_sub_result['category_id'];

    // Get the raw URL and prepare it
    $sub_sub_unrewritten = $unrewritten.’_’. $new_sub_path.’_’.$new_sub_sub_path;

    // Rewrite it
    // $sub_rewritten = $this->model_tool_seo_url->rewrite($sub_unrewritten);

    // Rewrite it
    // $sub_sub_rewritten = $this->model_tool_seo_url->rewrite($sub_sub_unrewritten);

    // Output as usual
    $output .= ‘‘ . $sub_sub_result['name'] . ‘‘;
    $output .= ”;
    $counter2++;
    }

    if ($sub_sub_results)
    {
    // Close off children UL
    $output .= ”;
    }
    $output .= ”;
    }

    if ($sub_results)
    {
    // Close off children UL
    $output .= ”;
    }

    }

    if ($results)
    {
    // Close parent UL
    $output .= ”;
    }

    echo $output;

  13. Edmend
    #19 written by Edmend  (1 year ago)

    could you tell me which file i need to change? i using 1.5.1 opencart.

    Thank

  14. Imran
    #20 written by Imran  (1 year ago)

    Thanks………Good work…….its greate.

  15. Imran
    #21 written by Imran  (1 year ago)

    could you tell me which file i need to change? i using 1.5.1 opencart.

    Thank

    where u want to use drop down if header then header.tpl if anywhere else then that file…………

    regards……..
    Imran Manzoor

  16. Martin Vondracek
    #22 written by Martin Vondracek  (1 year ago)

    Hello guy, thanks a lot for this post. It’s verz usefull to me.

    Very good work. Thanks again :)

  17. tarang
    #23 written by tarang  (1 year ago)

    Hi shaaz,
    Thank you for this code..
    I need to implement it on new version of opencart i.e 1.5.3
    Are there any modifications required or will this code work?
    I am new to PHP and opencart both..really looking forward to your help..

  18. tarang
    #24 written by tarang  (1 year ago)

    Hello Shahz,

    Waiting for your response…any help would be appreciated..

  19. Wayne
    #25 written by Wayne  (1 year ago)

    Hi Shahz, this looks very straightforward but like tarang above I am new to both PHP and OpenCart and I need some advice on how to implement this. It looks very easy but I am not sure where to start. Please could you help us out or email (provided in form). Many thanks.

  20. Shahz
    #26 written by Shahz  (1 year ago)

    Sorry guys,

    This code is pretty old now. It was implemented for OpenCart before 1.5. I’ve yet to play with the new version.

  21. Wayne
    #28 written by Wayne  (1 year ago)

    Hi Shahz, thanks for the reply. I am using OpenCart 1.5 and really want this on the website! Please could you help? I would really appreciate it.

  22. tarang
    #29 written by tarang  (1 year ago)

    Hi Shahz,
    Thanks for replying. Like Wayne above, i also want it on my website and my product upload is pending due to this change..
    I have searched opencart forums and php forums..even posted a request to Craig Murray, but m not getting any help :(
    Really looking forward for your help…
    Thanks in advance..!!

  23. avriukas
    #30 written by avriukas  (1 year ago)

    it is so actual for me too..

  24. Goke
    #31 written by Goke (3 months ago)

    hello all,
    Can someone guide me on introducing the Shahz script in to version 1.5.4.1 of the opencart?
    I have tested even the online demo, the second sub menu is not working.

    Your guide is key please.

    Goke

  25. 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>

  26. Comment Feed for this Post
Go to Top