I wanted to share a little Joomla! hacking I did the other day for two reasons:
- Because I think what I managed to do was pretty damn cool (someone else might think otherwise of course),
- Because I think there must be a better, less intrusive, way to do what I wanted. So I am hoping for some comments from hardcore Joomla! guys.
So, the scenario is this: A good customer of ours, ion design it a web design firm, asked me to build them a template, from scratch, for a particular client of theirs. This is something I’ve done before and will probably do again (basically, in this role, I help the artists with a fantastic eye for design make their artwork work in Joomla!). Clive, my customer, does come up with some cracking designs… Follow some of the links from his home page if you’re interested.
After being given the job, I started looking through the 5 page PDF which he submitted with the design. One page had a rather troubling menu layout…
After quite a bit of head scratching, this is actually what I have managed to achieve. The image is taken straight from Firefox 3 running on Ubuntu 8.10. That is Joomla! 1.5.9, the blue boxes arranged in an elipse are actually real Joomla! menu items! At this stage, the template is still being developed and doesn’t have the proper graphics but the basic physical layout and structure is there.
Each dark blue box in-the-round is a regular menu item in Joomla! that is a sub-menu of the menu shown along the top. Using the new split-menu technique in Joomla! 1.5 I am able to use seperate menu modules to display different layers of a single menu heirarchy, so that I can retain the “active” highlighting in the main menu for example.
Making the menu items appear in this ring arrangement isn’t really too hard; I just used absolute positioning of the
<li> elements. Each menu item has a unique class such as
<li class="item62">. It even mostly works in IE6!
However, there is a much bigger issue… On other pages of the site, the same sub-menu content needs to be displayed but with a different, more traditional, layout; as here:
To achive this I realised there were several problems to overcome:
- The titles in the sub-menu needed to break across several lines so they wrapped consistently,
- the menu module responsible for displaying the menu had to be the same for both layouts or I would lose the active highlighting of the top menu,
- I wanted to have a single menu so it was easy for my customer or their end-user to modify and update the site,
- the ring menu really needed to be text based so it was properly indexable and accessible,
- Joomla! only allows custom CSS class or id tags to be added at the module level and not at the article level.
To fix the first problem, having line breaks (or
<br /> elements) in menu items, I used an excellent plugin called yvBBCode. It enables you to insert BB Codes, such as
[br] for example, anywhere in Joomla! Including in menu titles. The plugin then converts these BB codes to XHTML codes on the fly.
In the end, the solution for the menu layout itself was fairly straightforward, but required a minor hack to the Joomla! core (you can’t use the override facility here) and a small eval script on the template’s
I added a custom
radio list parameter (
ring_menu) to the article.xml file in
<!-- Added by Alan Lord. 22/01/09 -->
<param name="ring_menu" type="list" default="vertical" label="Menu Style" description="Chose a normal or ring style menu layout">
<option value="ring_menu">Ring Menu</option>
<!-- End modification -->
On the particular article where I wanted the menu displayed “in-the-round” I set this
radio list param to “Ring Menu”. The option is shown in the Article Advanced Parameters accordion (the default setting is “vertical” BTW). You can see how the custom parameter is displayed here. Note the first item in the Parameters (Advanced) menu on this screenshot.
Now we have a parameter to play with, in the template’s
index.php file in the
<head> area, I can read this value into a php variable (
// This loads a custom article parameter "Ring Menu". The custom parameter is defined in
// administrator/components/com_content/models/article.xml. It defaults to Vertical, the other
// option currently is "Ring Menu".
// We can read this parameter and apply a different style to a module based on the page
$params = &JComponentHelper::getParams( 'com_content' );
$class = $params->get('ring_menu');
Further down the script, where the menu module itself is loaded, the
$class variable is echoed into the surrounding div. Thus, when the particular article in question is loaded, the container div for the menu changes from
<div id="sub-menu" class="vertical"> to
<div id="sub-menu" class="ring-menu">. So my stylesheet can now do its magic and render the sub-menu, or any module for that matter, in the manner which I choose.
I hope this is useful to some and I would really love to know if there is a way to achieve the same result (i.e. adding a style class based on the article being viewed) without needing to hack the Joomla! core. I’m sure there probably is…