The built-in menu module in Joomla 2.5 does not offer a way to indicate that a menu item has undisplayed sub-menus but with a little bit of PHP coding we can make it happen.

The context of this problem is a menu displayed at the left of the main content which only displays submenus for the active item.

In summary, the method is:

  • Override the menu module output to add class specifiers to those menu items that have sub-items.
  • Identify the menus that should use this behaviour.
  • Adjust the template style sheet to include a visual indication of the existence of sub-items.

The Details

Module override

Copy the main php file that generates menu items from the core directory to the override directory for your template.

eg copy from {website}/modules/mod_menu/tmpl/default.php
to {website}/templates/{templatename}/html/mod_menu

If your template already has this output override file, then don't copy the core file (but do make a backup of the override file before editing it).

Now we edit this file. Near the top, before the 'foreach' loop, we get a reference to the current menu object.

<?php
$curMenu = JSite::getMenu();
foreach ($list as $i => &$item) :

In the body of the loop, where the code builds the class string depending on various rules, we add one to detect submenu items:

$subitems = $curMenu->getItems(array("parent_id"), array($item->id));
if (count($subitems) > 0) {
$class .= 'hassubmenu ';
}

Here I'm using the class 'hassubmenu', which doesn't conflict with any of the other classes in this template.

There should be a series of statements similar to this:

if ($item->parent) {
$class .= ' parent';
}

We add our new test just after these, but before the 'class=' prefix gets added (if (!empty($class)) {$class = ' class=".trim($class) ."'; })

That's all for the module override. Save this file and check that your site still works. If you look at the generated HTML code you should see some menu items include the 'hassubmenu' class either on its own or in combination with other classes (<li class="hassubmenu">) or in combination with other classes (<li class="current active parent first hassubmenu">)

Tell the menu

If you only use one menu on your site, you can skip this next bit, but I think it's a good idea. in any case.

In those menu modules that you want to exhibit this new behaviour, add a moduleclass suffix (such as 'showsub'). This lets you have some normal menus and some that use this extra style.

Add some styles

Now that we can identify these menu items, we can adjust the template style sheet to include a visual indicator. Here I'm using a small image at the right of the list item.

In a template css file (probably called 'template.css', but it depends on your template), add this declaration at the end of the file.

div.jsn-modulecontainer.showsub li.hassubmenu {
background: url(../images/arrow.png) no-repeat top right;
}

Here my menus are generated within a div with class jsn-modulecontainer, I'm only applying this style if the menu has the 'showsub' class suffix (if you didn't do that bit, your selector will have to change). The style applies to list items within this div that have the 'hassubmenu' class and sets the background image to a small right-pointing arrow positioned at the top right of the list item - this worked for me but you might like something else.

Depending on your template and other CSS markup, you may need to use different style specifier.

If you don't want to see the indicator on the active menu (which lists the sub-items anyway), use the 'parent' class to remove the image we just added.

div.jsn-modulecontainer.showsub li.hassubmenu.parent {
background: url();
}

This goes after the previous one.

Alternatives

Using the standard menu module, we could show the whole menu tree all the time. Except there are lots of items, so the pages get really long.

There are a number of different menu extensions available which offer the same or similar features (as far as I can tell).Except that wouldn't be as much fun.

References

Joomla documentation - how to override the output from the Joomla! core

Joomla API documentation - the version used by Joomla 2.5