Top

The Blog


  1. 3
    Mar
    2010

    Advanced Techniques: The Joomla Parent Menu ItemID

    Joomla’s ItemID system offers a great way of customizing sites by giving the opportunity to style major parts of a template or page based on the menu links ItemID. Every menu link in a Joomla website has one; and they are unique to each and every link on your site.

    But what if you need to style entire sections of a site based on a handful of top-level (parent) menu items?

    This article explores the methodology of styling sub-level pages respective of their common parent menu links.

    menusystem

    Method 1: Modifying the mod_breadcrumb Module Code

    The mod_breadcrumb module is native to Joomla, and by it’s core function maintains a trail of menu link hierarchy leading to the current page. This code can be utilized in order to obtain the top-level menu’s textual name (rather than an itemID number). This method expands the code further to reformat this text into a usable, readable format which can be used to style a page in an understandable way. It’s more code-heavy than method 2, but provides an easier-to-understand output that works in exactly the same way.

    Let’s first examine the original code:

    defined('_JEXEC') or die('Restricted access');
    
    class modBreadCrumbsHelper
    {
    	function getList(&$params)
    	{
    		global $mainframe;
    
    		// Get the PathWay object from the application
    		$pathway =& $mainframe->getPathway();
    		$items   = $pathway->getPathWay();
    
    		$count = count($items);
    		for ($i = 0; $i < $count; $i ++)
    		{
    			$items[$i]->name = stripslashes(htmlspecialchars($items[$i]->name));
    			$items[$i]->link = JRoute::_($items[$i]->link);
    		}
    
    		if ($params->get('showHome', 1))
    		{
    			$item = new stdClass();
    			$item->name = $params->get('homeText', JText::_('Home'));
    			$item->link = JURI::base();
    			array_unshift($items, $item);
    		}
    
    		return $items;
    	}
    	
    	function setSeparator($custom = null)
    	{
    		global $mainframe;
    
    		$lang =& JFactory::getLanguage();
    
    		if ($custom == null) {
    			if($lang->isRTL()){
    				$_separator = JHTML::_('image.site', 'arrow_rtl.png');
    			}
    			else{
    				$_separator = JHTML::_('image.site', 'arrow.png');
    			}
    		} else {
    			$_separator = $custom;
    		}
    		return $_separator;
    	}
    }
    

    We can immediately remove the second part of the code that sets the separator, since we don’t need that. Also, since we only need to return the parent item’s text, we don’t need the loop in place. We shall also use the Application Object since
    $global mainframe
    will be removed in Joomla 1.6, so:

    $global mainframe; 
    

    Becomes:

    $app = &JFactory::getApplication();
    

    Which gives us the completed code below:

    class getParentMenuTitle {
    	function getList() {
    		$getParent = &JFactory::getApplication();
    		// Get the PathWay object
    		$pathway =& $getParent->getPathway();
    		$items = $pathway->getPathWay();
    	return $items;
    	}
    }
    $list = getParentMenuTitle::getList();
    $count = count($list);
    if ($count !== 0) :
    	$parentmenu = $list[0]->name;
    	$parentmenu = ereg_replace(" ", "-", $parentmenu); // replace spaces with a dash
    	$parentmenu = ereg_replace("[^+A-Za-z0-9-]", "", $parentmenu); // strip special characters
    	$parentmenu = strtolower($parentmenu); //set name to lowercase
    else :
    	$parentmenu = "home"; // Set parentmenu to "home" if there are no items
    endif;
    

    How To Use The Code

    This block of code can be inserted directly into your active template’s index.php file before the HTML is started. Remember to enclose the code block in PHP tags. Alternatively you can include it from an external file.

    Once working in the template, you can apply the variable $parentmenu to a top-level container to initiate a CSS hook. Where you add this will depend on what you need to influence in the design, but the further up the hierarchy the more things you will be able to affect in the design – for example:

    <body id="<?php echo $parentmenu; ?>">
    

    …will allow you to influence the design across the whole template, such as:

    body#menu-link-name a {color:red;}
    

    …which will change all links on the page to red for that particular top-level menu link.

    Method 2: Using the Jsite Object

    This method is by far the simplist of the two methods, and unless you need a more human-readable format for the menu class/ids then it’s by far the recommended method of the two. It uses the Jsite object to obtain the parent menu’s ItemID and stores it in a variable which can then be applied to any class/id in the template:

    $parentmenu = JSite::getMenu()->getActive()->tree[0];
    

    You can obtain the ItemID of any menu links in the pathway by altering the value of tree[0].

    How To Use The Code

    Again, this code needs to be inserted into the template. The ItemID is stored in the $parentmenu variable, just as it was before, so you can use a similar method to above – but prefix the class/id with something or else you may have problems, for example:

    <body id="menuID-<?php echo $parentmenu; ?>">
    

    Why Would You Need To Use Method 1?

    The first method could be useful in instances where you (as the developer) might want to pass more control onto someone who is less technically-minded – the class/id names which are generated using this method are very easy to predict, whereas method 2 requires the administrator to lookup the itemID for each menu item that requires styling.

    Something to Share?

    Have an alternative technique, or have you used this (or something similar) on a site before? Please do share it in the comments.

    Many thanks to Gergő Erdősi and Amy Stephen for the code presented in method 2 above.

  2. 5
    Comments

    Something to say? Leave a reply!

    1. Comment by Tambra Goldhirsh — April 3, 2010 @ 1:54 am [Link]

      Thanks dude, that is really helpful information, thanks.

    2. Comment by Webster — April 6, 2010 @ 12:28 am [Link]

      Thank You

    3. Comment by Josh — April 13, 2010 @ 9:34 am [Link]

      Could you expand on how to use this technique with children menu items as well?

    4. Comment by Dan Luton — April 13, 2010 @ 9:45 am [Link]

      Hi Josh,

      Depends what you mean.

      If you want to get the current Menu Itemid, you can use:

      $item_id = JRequest::getVar(’Itemid’);

      Alternatively, you can use the above technique to obtain the parent menu Itemid for a different level:

      $parentmenu = JSite::getMenu()->getActive()->tree[1];

      …which should work. All depends really what it is you’re trying to achieve – this article really focuses on the absolute top-level ID.

      Hope that helps.

    5. Comment by Josh — April 13, 2010 @ 3:56 pm [Link]

      That was exactly what I have been trying to do all morning. Thanks!

    [TrackBack URL]

    Leave a comment