concrete5: Mastering Auto-Nav for Advanced Navigation

Exclusive offer: get 50% off this eBook here
concrete5 Beginner's Guide

concrete5 Beginner's Guide — Save 50%

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

£16.99    £8.50
by Remo Laubacher | April 2011 | Beginner's Guides Open Source Web Development

Creating a navigation isn't complicated but there are a few things you have to know if you want to customize the navigation. In this article by Remo Laubacher, author of concrete5 Beginner's Guide, we'll have a deeper look at the autonav block you use to create dynamic navigation. It basically pulls a selection of pages from the sitemap and prints a hierarchical HTML structure which represents the navigation.

We're going to start with information about the use of the block. Afterwards we're going to create a series of templates for the block in order to change the look and the behavior of the navigation to explain the process of building a custom navigation in concrete5.

 

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.

Preparation

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">
    <?php
    $a = new Area('Header Nav');
    $a->display($c);
    ?>
    </div>
    <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:

<?php
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) {
echo("<ul>");
}

// 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) {
echo("</li></ul>");
} else {
echo("</li></ul></li>");
}
}
}

// 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) {
echo("</li>");
}

// 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;
$i++;
}
// 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++) {
echo("</li></ul>");
}
?>

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

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.
concrete5 Beginner's Guide Create and customize your own website with the Concrete5 Beginner's Guide
Published: March 2011
eBook Price: £16.99
Book Price: £27.99
See more
Select your format and quantity:
        Read more about this book      

(For more resources on concrete5, see here.)

Images in the navigation

If you add a new autonav block, it will always print text links, no matter which template you use or which option you select.

We're going to assign the navigation pictures as we did with the pictures attribute used in the page list template where we've added a thumbnail. For this we have to create two new attributes, one for the picture in the normal state and one displayed when the page is active.

Time for action – creating page attributes for navigation pictures

  1. In the dashboard, go to Pages and Themes - Attributes.
  2. At the bottom, select Image/File and click on Go.
  3. Enter navigation_pic_off for handle and Navigation Picture Off for name.
  4. Create another attribute with navigation_pic_on for handle and Navigation Picture On for the name.
  5. If you intend to use this for all navigation items, you might want to assign the new attributes to the page types by default. Go to Page Types and click on Edit for each page type. Select the two new attributes and click on Update Page Type.

What just happened?

By following the steps in the time for action, you created two attributes which allowed you to assign two pictures to every page. Attributes in concrete5 are very flexible—you can create and connect them to pages, users, and files in case you have to manage object-specific data.

Attributes can be helpful with a variety of different problems; make sure you know how to use them.

Time for action – creating block picture navigation template

  1. Copy the default autonav template concrete/blocks/autonav/view.php to blocks/autonav/templates/picture_nav.php.
  2. We have to modify a few lines in the new template, and the following snippet shows you the lines you have to modify:

    if (!$pageLink) {
    $pageLink = $ni->getURL();
    }

    $navigationLinkOn = $navigationLinkOff = $ni->getName();
    $navigationPicOff = $_c->getAttribute('navigation_pic_off');
    $navigationPicOn = $_c->getAttribute('navigation_pic_on');
    if ($navigationPicOn) {
    $navigationLinkOn = '<img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="' . $navigationPicOn->getURL() .
    '" alt="' . $navigationLinkOn . '"/>';
    }

    if ($navigationPicOff) {
    $navigationLinkOff = '<img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="' . $navigationPicOff->getURL() .
    '" alt="' . $navigationLinkOn . '"/>';
    }

    if ($c->getCollectionID() == $_c->getCollectionID()) {
    echo('<li class="nav-selected nav-path-selected"><a class=
    "nav-selected nav-path-selected" href="' . $pageLink . '">' .
    $navigationLinkOn . '</a>');
    } elseif ( in_array($_c->getCollectionID(),
    $selectedPathCIDs) ) {
    echo('<li class="nav-path-selected"><a class=
    "nav-path-selected" href="' . $pageLink . '">' .
    $navigationLinkOn . '</a>');
    } else {
    echo('<li><a href="' . $pageLink . '">' . $navigationLinkOff .
    '</a>');
    }

What just happened?

Using the two new attributes, we created another block template. We had to insert a bunch of lines compared to the original template, but the logic behind it is rather simple.

First, we try to get all the information from the page we need—the name and the two pictures. We then build the HTML code to print the clickable part of our link. If there's a picture, we'll use it; if there isn't, we'll print the text as if nothing has changed.

In the preceding code you can see a comparison $c->getCollectionID() == $_c->getCollectionID(). This is what checks if we're currently processing the current page. If we are on the current page, we have to print the first navigation picture; otherwise we use the second attribute.

CSS3 hover effect

While CSS3 isn't well supported yet, it allows us to do things for which we previously needed JavaScript. The use of JavaScript would have been possible for most effects as well, but we're going to look at a CSS3-only effect to get a quick impression to see how easy it is to integrate upcoming web technologies. Make sure you're using an up-to-date browser like Chrome 6 to see the effect.

The effect we're going to use is just a bit more than a classic CSS hover effect which you've probably used before. It starts with something like this:

a {
color: silver;
}
a:hover {
color: black;
}

Such a CSS file would display all the links in silver and, when you hover over them, in black. With CSS3, things get a bit fancier, but let's create the new template; we'll see how it looks very quickly.

Time for action – creating a CSS3 transition autonav template

  1. Create the directory structure for our new template autonav/templates/css3_hover.
  2. Our template works a lot like the existing header menu: copy concrete/blocks/autonav/templates/header_menu.php to blocks/autonav/templates/css3_hover/view.php.
  3. Since we don't want to interfere with an existing autonav template, we rename the main ul element. In the fifth line, make sure there's a class called nav-css3-hover:

    <?php
    defined('C5_EXECUTE') or die(_("Access Denied."));
    $aBlocks = $controller->generateNav();
    $c = Page::getCurrentPage();
    echo("<ul class=\"nav-css3-hover\">");

    $nh = Loader::helper('navigation');

  4. In our template directory, create another file called view.css:

    .nav-css3-hover li {
    list-style-type: none;
    float: left;
    }
    .nav-css3-hover a {
    display: inline-block;
    padding: 4px;
    border: 2px solid transparent;
    -moz-transition: 0.25s -moz-transform;
    transition: 0.25s transform;
    -webkit-transition: 0.25s -webkit-transform;
    -webkit-transform: scale(1) rotate(0);
    -moz-transform: scale(1) rotate(0);
    transform: scale(1) rotate(0);
    }
    .nav-css3-hover a:hover {
    background: #e64116;
    text-decoration: none;
    color: #ffffff;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
    border: 2px solid white;
    -webkit-transform: scale(1.2) rotate(-3deg);
    -moz-transform: scale(1.2) rotate(-3deg);
    transform: scale(1.2) rotate(-3deg);
    }
    .nav-css3-hover li:nth-child(2n) a:hover {
    -webkit-transform: scale(1.2) rotate(3deg);
    -moz-transform: scale(1.2) rotate(3deg);
    transform: scale(1.2) rotate(3deg);
    }

  5. Save the files and go back to your page, edit it, and click on the navigation block in the previously modified area. Select Custom Template, select Css3 Hover, and Update the block.

What just happened?

Another quite simple template, which looks as follows:

concrete5: Mastering Auto-Nav for Advanced Navigation

The modification to view.php wouldn't have been necessary if we didn't care about interfering with other navigations on the same page, which would only happen if there were two navigation blocks anyway.

At the end of the day it's only about the CSS file we've created. We will have a quick look at the CSS rules used in the preceding example without going too much into the details of CSS3. We had to use some browser-specific extensions because it's a rather new feature. If you remove those, things are easier to read, for example:

.nav-css3-hover a {
display: inline-block;
padding: 4px;
border: 2px solid transparent;
transition: 0.25s transform;
transform: scale(1) rotate(0);
}

The transition property sets the duration for the effect and specifies the element we want to use for the effect. In the case of the transform property, the simplified rule relevant when the link is hovered over would look as follows:

.nav-css3-hover a:hover {
transform: scale(1.2) rotate(-3deg);
}

Here we can see that the transform property has a different value than the one in the first example. It's scaled and rotated a little bit which will cause the effect.

In short, transition sets the attribute to use, and will then transform into the value specified in :hover. You can also use transition: 0.25s all, which would use all properties.

Have a go hero – create more transitions

Instead of the transform property, you can access all kinds of CSS properties to create a smooth transition effect.

transition: 0.25s color would gradually fade the color of the link to the color you have specified in :hover. It works with the location, dimension, color, background, and a lot more; there are lots of possibilities and it takes only a few lines of code.

Drop-down navigation

Drop-down navigations have been around for quite some time. When graphical user interfaces got popular, they were everywhere. With more advanced web technologies available, they also found a way onto the Internet.

We therefore have to create one in concrete5 as well using the jQuery library. There are lots of scripts available and most of them can be used, but we're going to use SooperFish by Jurriaan Roelofs from http://www.sooperthemes.com. It's a great little plugin—easy to work with and easy to integrate in concrete5.

Time for action – creating SooperFish template

  1. Go to http://www.sooperthemes.com/open-source/jquery/jquery-sooperfish-dropdown-menus and download the latest version available.
  2. Create a new directory structure for our template blocks/autonav/templates/sooperfish/js. From the downloaded ZIP file, extract jquery.sooperfish.min.js in the js directory.
  3. In the directory just mentioned, create a new file called view.php. We could copy it from the original template and rename the main ul element in case there's a second navigation on the page. Feel free to do that, but please take care that you rename all the CSS rules as well. However, in this case we're simply going to include the original template as we already have several CSS rules in the theme which are useful for our drop-down menu:

    <?php
    $bvt = new BlockViewTemplate($b);
    $bvt->setBlockCustomTemplate(false);

    include($bvt->getTemplate());
    ?>

  4. Create another file called view.js where we initialize the SooperFish menu:

    $(document).ready(function() {
    $('#header > ul').sooperfish();
    });

  5. If you create a drop-down menu, your HTML code must contain the child pages, even if you only see them when hovering over the parent element. Since JavaScript is responsible for showing and hiding the child elements, we have to make sure the child elements are printed by autonav. Edit the page where you want to use the drop-down menu, click on the autonav block, and apply these values:

    concrete5: Mastering Auto-Nav for Advanced Navigation

  6. Update and publish the page.

What just happened?

A new template based on SooperFish is created. Since most of the CSS rules we created earlier work with SooperFish, we do not even have to make any CSS modifications. The only thing that is needed is the SooperFish JavaScript, another super small JavaScript to load the script and the standard template. Depending on the CSS file from your theme, you might have to include a modified version of some CSS rules you can find in the SooperFish ZIP file. The menu does require a few CSS instructions in order to work properly.

When we created the view.js file, we did not pass any parameters to SooperFish, but there are plenty of things you can configure with this plugin. If we have a look at the example from the author's website, we'll find the following example:

$(document).ready(function() {
$('#header >ul').sooperfish({
hoverClass: 'over',
delay: '400ms',
dualColumn: 7,
tripleColumn: 14,
animationShow: {height:'show',opacity:'show'},
speedShow: '800ms',
easingShow: 'easeOutTurbo2',
animationHide: {width:'hide',opacity:'hide'},
speedHide: '400ms',
easingHide: 'easeOutTurbo',
autoArrows: false
});
});

An interesting feature other drop-down plugins don't offer can be configured by dualColumn and tripleColumn. In the example above, any submenu with more than seven elements will be divided into two columns.

All the other properties should be fairly easy to understand—they let you specify a custom animation, duration, and some interface-related features such as arrows to indicate the availability of child pages. There's a nice page where you can play with all these properties at http://www.sooperthemes.com/sites/default/files/SooperFish/example.html.

concrete5 Beginner's Guide Create and customize your own website with the Concrete5 Beginner's Guide
Published: March 2011
eBook Price: £16.99
Book Price: £27.99
See more
Select your format and quantity:
        Read more about this book      

(For more resources on concrete5, see here.)

Hierarchical tree navigation

Another variant of drop-down navigation is a tree which works a bit like a file explorer. There are plenty of jQuery plugins for this job around as well, but this time we're going to create everything from scratch. Thanks to jQuery, this is going to take neither a lot of time nor a lot of lines of code.

To keep the example as simple as possible, we're not using any pictures at all. You can surely find a way to improve the layout once you've had a closer look at the jQuery code.

Time for action – building a file explorer-like navigation

  1. Create another directory structure for our template blocks/autonav/templates/tree.
  2. Within that directory create view.php, but this time we'll use a different approach. We only want to change the class name to keep the functionality separated from other autonav blocks on the same page. We also don't want to copy the default autonav block template to avoid redundant code. We're going to replace the ul class name on-the-fly:

    <?php
    $bvt = new BlockViewTemplate($b);
    $bvt->setBlockCustomTemplate(false);

    function nav_tree_callback($buffer) {
    return str_replace('<ul class="nav">',
    '<ul class="nav-tree">',$buffer);
    }

    ob_start("nav_tree_callback");
    include($bvt->getTemplate());
    ob_end_flush();
    ?>

  3. In another file called view.css, you have to place some layout instructions for our tree. The script works without this, but the tree would look a bit misaligned:

    .nav-tree li { list-style-type: none; }
    .nav-tree { margin: 0px; padding: 0px; }
    .nav-tree ul { margin: 0px; padding: 0px 0px 0px 20px; }
    .nav-tree .tree-item-folder { cursor:pointer; }
    .nav-tree .tree-item-type {display:inline-block; width: 10px;}

  4. And finally some jQuery magic in view.js:

    $(document).ready(function() {
    // prepend a span element in front of each link
    $(".nav-tree a").parent().prepend("<span class=
    \"tree-item-type\"></span> ");

    // those span element being part of a parent element get a "+"
    $(".nav-tree ul:has(*)").parent().find("> .tree-item-type")
    .text("+").toggleClass("tree-item-folder");

    // hide all submenus
    $(".nav-tree ul").hide();

    $(".tree-item-folder").click(function() {
    $(this).next().next().slideToggle("fast");
    })
    });

What just happened?

After you've created the template and assigned it to your autonav block you'll have a tree-like navigation which looks as follows:

concrete5: Mastering Auto-Nav for Advanced Navigation

This is another template which doesn't use any external jQuery libraries at all. Thanks to jQuery, we only needed a few magic lines of code to add a small "plus" sign in front of all pages with subpages. It uses three lines of code to hide the subpages when the user clicks on the "plus" sign, and a small PHP template which includes the default template but replaces the ID to avoid any complications with other navigation blocks on the same page.

Dynamically loading content

During the last few years, AJAX has become very popular. It wasn't really new at that time but people started using it more and more and of course, you can use it in concrete5. Sometimes, AJAX is a bit too razzle-dazzle and so is the following autonav template we're going to look at.

This demonstration is more about giving you ideas about what you can do rather than a recommendation to use it on your website.

Time for action – dynamically loading concret5 content using jQuery

  1. As always, we need a new structure for our template. Make sure all these directories exist within each other: blocks, autonav, templatesanddynamic_loadbuilding this path blocks\autonav\templates\dynamic_load.
  2. Create a new file view.php with the well-known content:

    <?php
    $bvt = new BlockViewTemplate($b);
    $bvt->setBlockCustomTemplate(false);

    include($bvt->getTemplate());
    ?>

  3. All the magic happens in our JavaScript file view.js:

    $(document).ready(function() {
    $(".nav a").click(function() {
    var pageUrl = $(this).attr("href") + " #content > *";

    $("#content").slideUp("normal",function() {
    $("#content").load(pageUrl,"", function() {
    $("#content").slideDown("normal");
    });
    });
    return false;
    });
    });

  4. After you've created all the files, go back to your page and change the Custom Template of the autonav block where you want to try the dynamic page loading.

What just happened?

After you activate the template you can click on a link in the navigation. The browser won't load a new page; instead our little jQuery script slides up the current content, dynamically loads the new page, and slides the new content down.

This works by redirecting all clicks on links within the nav element using this selector: $(".nav a"). We then build the URL we want to load. Please note that we append #content > * at the end of the variable; the jQuery method load parses this expression, and only returns the content of the new page which matches the selector. In this case all HTML elements are under #content. Before we load the new content, we hide the existing using slideUp and once the new content is loaded, we use slideDown to show it.

However, as mentioned at the beginning, using this technique has lots of disadvantages:

  • We only load the content of the new page and skip the header. If the new pages depend on JavaScript, we don't include the first page as it will fail.
  • Depending on the complexity of the content you load, the effect might be a bit bumpy; use it for a personal portfolio page with little content to get a smooth effect, and not your huge company website.
  • If you're in the edit mode looking at a dynamically loaded page and start the in-site edit mode, you'll still edit the first page because concrete5 doesn't know anything about that dynamic script which changed the content on-the-fly.
  • The preceding script makes it possible to directly link to your pages, but the page address won't change when you load a new page. This however, can be avoided by using a little more advanced script.

Allowing direct links in dynamically loaded pages

In order to make direct links possible, we're using a part of the URL called hash, which we can set using JavaScript. The URL is going to look like this: http://localhost/#about. While this still links to the first page, we can use a JavaScript method to check for the existence of the hash and dynamically load the subpage, even if we're on the first page.

Time for action – direct link with dynamic content

  1. Open view.js from the previous template again.
  2. Replace everything with this content:

    function getLinkHash(linkHref) {
    linkHref = linkHref.replace(CCM_DISPATCHER_FILENAME,"");
    return linkHref.replace(new RegExp("[^a-zA-Z0-9_]","g"), "");
    }

    $(document).ready(function() {

    // check if there's a hash in the url and
    // dynamically load the page
    if (window.location.hash) {
    $(".nav a").each(function(index, value) {
    if ("#" + getLinkHash($(this).attr("href")) ==
    window.location.hash) {
    $("#content").load($(this).attr("href") + " #content > *");
    }
    })
    }

    $(".nav a").click(function() {
    var linkHref = $(this).attr("href");
    var pageUrl = linkHref + " #content > *";

    window.location.hash = getLinkHash(linkHref);

    $("#content").slideUp("normal",function() {
    $("#content").load(pageUrl,"", function() {
    $("#content").slideDown("normal");
    });
    });
    return false;
    });
    });

What just happened?

The preceding script is an extension to the previously created template. There are two main additions:

  • When you click on a link, the name of the page will be sanitized and appended to the URL by using window.location.hash.
  • When a page is loaded, there's a little code which checks if the current hash at the end of the URL matches a link in the navigation. If it does, that page will be loaded immediately.

When you directly open a page with a hash at the end, you'll still see the first page for a very short time. This is because we have to wait until the first page is loaded before we load the next page. Again, think about it before you really use this; with this addition it works a bit better but still shouldn't be used in pages with a complicated structure and dynamic elements in it.

Summary

We took a closer look at the autonav block, an element you'll often need when you work with concrete5. While a lot about the autonav block is down to experience, you should already have gotten an impression about some of the possibilities.

The templates we created are fairly easy to modify or extend with some basic knowledge about the used web technologies. The layout is mostly amendable by adding some CSS rules and some templates we've created use JavaScript libraries, where you can modify some parameters such as colors and the number of columns very easily by changing some easy-to-understand variables.

Try to use the template we've created as a base for your own, custom navigation. You've got examples which show you how to include JavaScript, CSS, and PHP to get the most out of the autonav block to create almost any kind of navigation you want.


Further resources on this subject:


About the Author :


Remo Laubacher

Remo Laubacher grew up in Central Switzerland in a small village surrounded by mountains and natural beauty. He started working with computers a long time ago and then, after various computer-related projects, focused on ERP and Oracle development. After completing his BSc in Business Administration, Remo became a partner at Ortic, his ERP and Oracle business, as well as a partner at Mesch web consulting and design GmbH. At Mesch—where he's responsible for all development-related topics—he discovered concrete5 as the perfect tool for their web-related projects and has since become a key member of the concrete5 community. You can find his latest publications on http://www.codeblog.ch/.

He has also authored concrete5 Beginner's Guide and Creating concrete5 Themes.

Books From Packt


jQuery 1.4 Reference Guide
jQuery 1.4 Reference Guide

Learning Ext JS 3.2
Learning Ext JS 3.2

Drupal 7
Drupal 7

Inkscape 0.48 Essentials for Web Designers
Inkscape 0.48 Essentials for Web Designers

MODx Web Development - Second Edition
MODx Web Development - Second Edition

Magento 1.4 Development Cookbook
Magento 1.4 Development Cookbook

Mastering phpMyAdmin 3.3.x for Effective MySQL Management
Mastering phpMyAdmin 3.3.x for Effective MySQL Management

ADempiere 3.6 Cookbook
ADempiere 3.6 Cookbook


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software