concrete5: Mastering Auto-Nav for Advanced Navigation

9 min read


concrete5 Beginner’s Guide

concrete5 Beginner's Guide

Create and customize your own website with the Concrete5 Beginner’s Guide

        Read more about this book      

(For more resources on concrete5, see here.)

Autonav introduction

Before we start customizing the autonav block, we’re going to have a quick look at the different options and the output. It’s very helpful to be familiar with all the block options as well as knowing the HTML output the block generates before you start extending the block.


You may have the autonav block included in your theme, more precisely in header.php of your theme. Since we’re going to play with navigation, we should undo this modification; changing the options in header.php would be a bit annoying otherwise. If you’re done with this article, you might want to put the code back in place; it’s mostly to make it easier to work with the custom templates we’re going to build.

Time for action – undoing autonav block integration

  1. Open header.php from your theme; it’s located in the themes/c5book/elements directory (Code Download-ch:7).
  2. Since the following code snippet doesn’t show the complete file, make sure you replace the correct lines. Everything is underneath the HTML tag with the ID header:

    <div id="wrapper">
    <div id="page">
    <div id="header_line_top"></div>
    <div id="header">
    $a = new Area('Header Nav');
    <div id="header_line_bottom"></div>

  3. Save header.php and go back to your page. Make sure the navigation is still there, if it isn’t go back to edit the page and add a new autonav block in Header Nav. After you’ve added it, change the custom template to Header Menu.

What just happened?

We had to undo a modification done before this article. The code which printed the autonav block directly from the template would be fine if your navigation didn’t change. However, since we’re working on the autonav block for a whole article, we had to remove this code and replace it with the default code for an editable area.

Autonav options

The autonav block comes with a bunch of options you can use to create the correct hierarchical output of pages in your navigation.

While you probably have to play around with it for a bit to get used to all the options, we’re still going to look at a few possible configurations which we’ll need later in this article.

Autonav page structure

The example configurations we’re going to look at use the structure shown in the following screenshot. We won’t need to tick the checkbox for system pages, which would show the dashboard and some built-in pages. We don’t want to include them in our navigation anyway.

It doesn’t matter if your structure looks different at this point; the examples are easy to understand even if your result looks a bit different.

concrete5: Mastering Auto-Nav for Advanced Navigation

Page order

By default, the autonav block uses the sort order which you can see in the sitemap as well. This usually makes sense because it offers the biggest flexibility. Remember, you can arrange pages by dragging their icon to the place where you want the page to be.

In all our examples you can choose whatever order you like; it doesn’t have an effect on our templates.

concrete5: Mastering Auto-Nav for Advanced Navigation

Example 1 – showing all pages

The most basic configuration shows all pages, no matter where we are and no matter how many pages there are. This configuration is useful when you create a JavaScript-based navigation which displays subpages dynamically without reloading the page.

The settings should be obvious and the result as well; it will show all pages shown in the preceding structure.

concrete5: Mastering Auto-Nav for Advanced Navigation

When you create JavaScript drop-down navigation, you have to generate HTML code for all elements you want to show, but that doesn’t necessarily mean that you want to print all elements. Assuming you’ve got hundreds of pages, would you like to see all of them in the drop-down menu? Probably not, and this is why you can manually specify the number of page levels you’d like to print. Use this for the drop-down navigation we’re going to create later in this article.

concrete5: Mastering Auto-Nav for Advanced Navigation

Example 2 – showing relevant subpages

In the structure just shown, assume you’re on About, which has two direct child pages. If we wanted to display the two subpages in the left sidebar of our page, we could use the following settings:

concrete5: Mastering Auto-Nav for Advanced Navigation

Example 3 – showing relevant subpages starting from the top

For a site where you only have a single navigation, probably on the left-hand side, you have to start at the top and include all the relevant subpages. The settings are similar, but this time we start at the top and include the level below the current subpage as well by using these settings:

concrete5: Mastering Auto-Nav for Advanced Navigation

If you’re on the About page again, you’d see all pages on the top, along with the About page and the two subpages of it.

Autonav output

The autonav controller produces an HTML output which is compatible with most jQuery libraries you can find. It uses an UL/LI structure to create a proper hierarchical representation of the pages we show in our navigation.

Before we look at the actual output, here are some words about the process which generates the output. The autonav block controller uses all the settings you make when you add the block. It then creates an array of pages which doesn’t have any children—it’s a flat array. Unlike what some of you would expect, there’s no real recursion in the structure which you have to process in the block template.

How’s an autonav block template supposed to print a hierarchical structure? That’s not too difficult; there’s a property called level for each element in the array. You simply have to check what happens to that level. Is the level of the current page element bigger than the one from the previous element? If yes, create a new child to the current page. Does it decrease? If yes, close the HTML tags for the child elements you created when the level increased. Does this sound a bit abstract? Let’s look at a simplified, not working, but commented autonav template:

defined('C5_EXECUTE') or die(_("Access Denied."));
// get the list of all pages matching the selection
$aBlocks = $controller->generateNav();

$nh = Loader::helper('navigation');
echo("<ul class="nav">");

// loop through all the pages
foreach($aBlocks as $ni) {
$_c = $ni->getCollectionObject();
// get the level of the current element.
// This is necessary to create the proper indentation.
$thisLevel = $ni->getLevel();

// the current page has a higher level than the previous
// page which means that we have to print another UL
// element to indent the next pages
if ($thisLevel > $lastLevel) {

// the current page has a lower level compared to
// the previous page. We have to close all the open
// LI and UL elements we've previously opened
else if ($thisLevel < $lastLevel) {
for ($j = $thisLevel; $j < $lastLevel; $j++) {
if ($lastLevel - $j > 1) {
} else {

// when adding a page, see "echo('<li>..." below
// the tag isn't closed as nested UL elements
// have to be within the LI element. We always close
// them in an iteration later
else if ($i > 0) {

// output the page information, name and link
echo('<li><a href="' . $ni->getURL() . '">' .
$ni->getName() . '</a>');

// We have to compare the current page level
// to the level of the previous page, safe
// it in $lastLevel
$lastLevel = $thisLevel;
// When the last page has been printed, it
// can happen that we're not in the top level
// and therefore have to close all the child
// level we haven't closed yet
$thisLevel = 0;
for ($i = $thisLevel; $i <= $lastLevel; $i++) {

The templates we’re going to create don’t change a lot from the default PHP template. We mostly use the HTML structure the default template generates and only add some CSS and JavaScript. Understanding every detail of the default autonav template isn’t necessary, but still helps you to get the most out of the autonav block.

What we must understand is the HTML structure shown as follows—it’s what you’ll have to work with when you create a custom navigation or layout:

<ul class="nav">
<li class="nav-path-selected">
<a class="nav-path-selected" href="/">Home</a>
<li class="nav-selected nav-path-selected">
<a class="nav-selected nav-path-selected"
<a href="/index.php/about/press-room/">Press Room</a>
<a href="/index.php/about/guestbook/">Guestbook</a>
<a href="/index.php/search/">Search</a>
<a href="/index.php/news/">News</a>

Since you’re supposed to have some HTML knowledge to read this book, it should be fairly easy to understand the preceding structure. Each new level added a new ul element which contains an li element for each page along with an a element to make it clickable. Child pages within a ul element belong to their parent, meaning that the li element of the parent is closed when all the children have been printed.

The output uses the default template which adds some classes you can use to style the navigation:

  • nav: The main ul tag contains this class. Use it to access all elements of the navigation.
  • nav-selected: This class is assigned to the elements if they belong to the current page.
  • nav-path-selected: This class can be found on pages which are above the current page. They belong to the path of the current page, and are thus called path-selected.


Please enter your comment!
Please enter your name here