The built-in Autonav block is one of the most essential blocks in a Concrete5 site (right up there with Content and Page List). But if you’ve already designed a menu with a certain HTML and CSS structure, it can be very difficult to modify the autonav template to suit your needs because its default template is rather messy.
For example, what if you want to change the name of the class that indicates the current page from the default “nav-selected” to the more succinct “active”, or “current” (something that is used frequently in other systems’ dropdown menus)? Or what if you want to add a new class denoting the first or last item in the list? Or what if you want to do something more drastic like change the unordered list structure to a series of divs and spans? I consider myself a decent programmer and even I would be afraid of messing with that code!
But after a year of struggling with the autonav template on dozens of sites, and a healthy dose of assistance from other members of the C5 community, I’ve finally gotten it all figured out and have re-constructed the template so it is cleaner and easier to customize. Behold!
Not only is the markup nice and clean, but this template includes a ton of additional features beyond what the built-in autonav template provides (although it doesn’t break backwards compatibility in any way – you can use this new template unmodified and your site’s markup will not be any different than it was before). Some of the additional features available to you are:
- Ability to easily set and change class names for a variety of different circumstances (e.g. first and last items, item contains dropdown, unique class for every single item, etc.)
- Fixes a Concrete5 bug that resulted in all child pages of an excluded page to be included in the menu (the same functionality included in the Autonav Exclude Subpages addon)
- Recognizes a new custom attribute (
exclude_subpages_from_nav) you can add to your site that lets you exclude all of a page’s children without excluding that page itself
- Lets you set up a custom attribute (
nav_item_class) for a custom class name – whatever text is entered into that attribute for a certain page will get outputted into the menu item’s list of classes
To use this custom template in your own site, grab the latest file here: https://raw.github.com/jordanlev/c5_clean_block_templates/master/autonav/view.php. Save that page to
siteroot/blocks/autonav/view.php (you’ll need to create the
autonav directory inside
blocks if it doesn’t already exist). As always, make sure you’re not in
Out of the box, nothing will change on the front-end of your site. But you now have a nice and neat default template for the autonav block that you can easily customize. If you look at the code, you’ll see some comments at the top telling you about custom attributes that will be recognized by the template, which should be fairly self-explanatory. After that is a bunch of code that handles functionality (you don’t need to worry about that). Down towards the bottom, we get to the important part of the template. There are actually two distinct areas: one for setting up the css classes, and another for the actual html markup.
Customizing The CSS Classes
The portion of the code where you customize CSS classes looks something like this:
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 49 50 51 52 53 54 55 56 57 58
Most of the functionality is commented out, with the exception of the two “current page” classes (because those are part of the default functionality). If you want to change the name of the “current page” or “current section” class, you can do so here. For example, let’s say you want the menu item for the currently-viewed page to just be the word “current” – change this:
1 2 3 4
1 2 3 4
Similarly, if you want to change the name of the class for menu items that are “parent pages” of the page currently being viewed, change this:
1 2 3 4
1 2 3 4
Easy enough, right? Now let’s say your main navigation menu is a drop-down and calls for a small “down arrow” icon to appear next to items that contain a drop-down – you can change this:
1 2 3 4 5 6
1 2 3 4
(note that all we’ve done is remove the surrounding
*/ comment markers so that this portion of code will get run).
Now your drop-down menu CSS could contain something like this:
1 2 3 4
Which might give us something like this:
Customizing The Markup
With the flexibility to change and add new class names to each item, you very likely don’t need to modify the HTML markup at all. But every now and then you have some particularly nasty HTML that you’d rather not change. No problem! If you scroll down to the bottom of the template file, you’ll see code that looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
(note that you won’t see the opening and closing “php” tags in the real code – I unfortunately need to include those in order for the syntax highlighting on this blog to work – but if you actually add them to your code it will break!)
Okay, let’s start with an easy one. What if you want the nav menu to use an “id” instead of a “class”? Just change this line:
What if the html for your menu has spans surrounding each link? Just add the necessary tags around the “a” links, by changing this:
(be careful to make sure you keep everything inside the single-quotes, otherwise the php code will get messed up)
Here’s a really tough one I’ve had to deal with before – a particularly gnarly dropdown menu that had rounded corners at the bottom, but needed to maintain IE6 compatibility(!). I wish I had this template back then, and if I did, I would have changed the line that closes out every dropdown sub-menu from this:
(the reason that code is inside the “str_repeat” function is so all levels of a multi-level dropdown menu are closed in case you’re at the last item in one level whose parent item is also the last of its level)