Code hacks

My first Joomla! CMS code hack


PHP developer

One week into it and I am already hacking the Joomla! CMS core code. I knew it would happen after a while but the reason for the needed hack came as a surprise. I was surprised because I have seen dozens of Joomla! based websites with some fantastic looking designs. I never noticed one thing though, most of those designs used text links in their menu systems. It seems that Joomla! does not support the use of images as links in its menu system.

So when I needed to use images in the main navigation menu for the website that I am building I thought that it should be a simple fix. Just go out and get a Joomla! component that does what I need to get done.
I tried five different free GPL components and came to the conclusion that if using images is possible it just is not very easy. Any component that overrides the default menu also needs help establishing a new menu via a template. None of the templates I saw allowed the simple use of an image as a link in a menu. Most where DHTML style menus that still used text links. So after a few hours of reading at the Joomla! forums and surfing the web I saw that the best and easies solution was to hack the mainmenu module.

The hack is a fairly simple one because Joomla! does provide a mechanism for using images as icons next to text links. Why they did not go the next step and add in full image usage is beyond me. It only seemed logical. But in the years that I have been using different CMS's I have found that logic is last on any feaure list. The hack was to just change the code so that the icon image becomes an actually link when an image setting is detected.

/**
* Utility function for writing a menu link
*/
function mosGetMenuLink( $mitem, $level=0, &$params, $open=null ) {
global $Itemid, $mosConfig_live_site, $mainframe;

$txt = '';
$image_link = 0;

switch ($mitem->type) {
case 'separator':
case 'component_item_link':
break;

case 'url':
if ( eregi( 'index.php\?', $mitem->link ) ) {
if ( !eregi( 'Itemid=', $mitem->link ) ) {
$mitem->link .= '&Itemid='. $mitem->id;
}
}
break;

case 'content_item_link':
case 'content_typed':
// load menu params
$menuparams = new mosParameters( $mitem->params, $mainframe->getPath( 'menu_xml', $mitem->type ), 'menu' );

$unique_itemid = $menuparams->get( 'unique_itemid', 1 );

if ( $unique_itemid ) {
$mitem->link .= '&Itemid='. $mitem->id;
} else {
$temp = split('&task=view&id=', $mitem->link);

if ( $mitem->type == 'content_typed' ) {
$mitem->link .= '&Itemid='. $mainframe->getItemid($temp[1], 1, 0);
} else {
$mitem->link .= '&Itemid='. $mainframe->getItemid($temp[1], 0, 1);
}
}
break;

default:
$mitem->link .= '&Itemid='. $mitem->id;
break;
}

// Active Menu highlighting
$current_itemid = $Itemid;
if ( !$current_itemid ) {
$id = '';
} else if ( $current_itemid == $mitem->id ) {
$id = 'id="active_menu'. $params->get( 'class_sfx' ) .'"';
} else if( $params->get( 'activate_parent' ) && isset( $open ) && in_array( $mitem->id, $open ) ) {
$id = 'id="active_menu'. $params->get( 'class_sfx' ) .'"';
} else {
$id = '';
}

if ( $params->get( 'full_active_id' ) ) {
// support for `active_menu` of 'Link - Component Item'
if ( $id == '' && $mitem->type == 'component_item_link' ) {
parse_str( $mitem->link, $url );
if ( $url['Itemid'] == $current_itemid ) {
$id = 'id="active_menu'. $params->get( 'class_sfx' ) .'"';
}
}

// support for `active_menu` of 'Link - Url' if link is relative
if ( $id == '' && $mitem->type == 'url' && strpos( 'http', $mitem->link ) === false) {
parse_str( $mitem->link, $url );
if ( isset( $url['Itemid'] ) ) {
if ( $url['Itemid'] == $current_itemid ) {
$id = 'id="active_menu'. $params->get( 'class_sfx' ) .'"';
}
}
}
}

// replace & with amp; for xhtml compliance
$mitem->link = ampReplace( $mitem->link );

// run through SEF convertor
$mitem->link = sefRelToAbs( $mitem->link );

$menuclass = 'mainlevel'. $params->get( 'class_sfx' );
if ($level > 0) {
$menuclass = 'sublevel'. $params->get( 'class_sfx');
}

// replace & with amp; for xhtml compliance
// remove slashes from excaped characters
$mitem->name = stripslashes( ampReplace($mitem->name) );

switch ($mitem->browserNav) {
// cases are slightly different
case 1:
// open in a new window
$txt = ''. $mitem->name .'';
break;

case 2:
// open in a popup window
$txt = "link ."', '', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=550'); return false\" class=\"$menuclass\" ". $id .">". $mitem->name ."\n";
break;

case 3:
// don't link it
$txt = ''. $mitem->name .'';
break;

default:
// open in parent window
if ( $params->get( 'menu_images' ) ) {
$menu_params = new stdClass();
$menu_params = new mosParameters( $mitem->params );
$menu_image = $menu_params->def( 'menu_image', -1 );
$txt = ''.''. $mitem->name .''.''."\n";
$image_link = 1;

}
else{
$txt = ''. $mitem->name .''."\n";
}
break;
}

if ( $params->get( 'menu_images' ) ) {
$menu_params = new stdClass();
$menu_params = new mosParameters( $mitem->params );
$menu_image = $menu_params->def( 'menu_image', -1 );
if ( ( $menu_image != '-1' ) && $menu_image && !$image_link) {
$image = ''. $mitem->name .'';
if ( $params->get( 'menu_images_align' ) ) {
$txt = $txt .' '. $image;
} else {
$txt = $image .' '. $txt;
}
}
}

return $txt;
}
?>

Happy Publishing!

Discussion

7 comments for “My first Joomla! CMS code hack”

  1. Oh wow.. I never throught of that. thanks for the code.

    Posted by Anonymous | November 16, 2006, 02:25
  2. This very useful!
    Would it be possible to make another version of this function which includes both the image and the menu text in the link?

    Posted by Anonymous | October 2, 2007, 12:59
  3. Preferably where the text aligns with the middle of the image.

    Posted by Anonymous | October 2, 2007, 17:26
  4. where do i put this code

    Posted by Anonymous | April 4, 2008, 02:39
  5. Hi,

    Let us know what version of Joomla! you are using so we can test and see if the code still works. I have to do a search and update the article because to be honest I have forgotten where the code goes.

    I should have an answer for you by tomorrow.

    Posted by Anonymous | April 4, 2008, 18:50
  6. Can you please tell me where to put this code?

    Posted by Anonymous | May 11, 2008, 13:17
  7. You did not say which version of Joomla! you use. In Joomla 1.5 the code changes are in legacy.php. In Joomla ! 1.0 go to modules/mod_mainmenu.php.

    Posted by Hiveminds | May 11, 2008, 13:36

Post a comment

© 2003-2009 Hiveminds Magazine. Entries (RSS)
Powered by WordPress Theme by The Masterplan