JRoute and module visibility

12 September 2009 - 19:04

Correct SEF routing in Joomla is pretty easy thanks to the class JRoute. If you want to redirect to a clean url just use the basic method _(); like so:

JRoute::_('index.php?option=com_example&task=view');

Unfortunately, this method isn't aware of url aliases created in menu items. JRoute just alters a dirty url like /index.php?option=com_example&task=view in a clean url like /components/example/view. Let's say you've created menu item to this components task with the alias: /view-example. JRoute doesn't redirect to the alias, just to the cleaned up system url. This is a problem because menu items are essential if you want to define page parameters or module visibility. These parameters are only visible if the url matches exactly. If you want to create redirects to url aliases in your Joomla modules or components you can try the following snippet.

$menu =& JSite::getMenu();
$menu_items = $menu->_items;
foreach($menu_items as $item) {
    $match = 0;
    if($item->query['option'] == 'com_example')    $match = $match+1;
    if($item->query['task'] == 'view') $match = $match+1;
 
    $matches[$match] = $item->route;
}
if(key_exists(1, $matches)) {
    array_shift($matches);
    array_reverse($matches, false);
 
    $action_url = JRoute::_(JUri::base(true).'/'.$matches[0]);
}

This will create a path to a single alias created in a menu item if a matching menu item exists. You can also do this for other components by specifying the match criteria. For example:

$menu =& JSite::getMenu();
$menu_items = $menu->_items;
foreach($menu_items as $item) {
    $match = 0;
    if($item->query['option'] == 'com_content')    $match = $match+1;
    if($item->query['view'] == 'category') $match = $match+1;
    if($item->query['layout'] == 'blog') $match = $match+1;
    if($item->query['id'] == '63') $match = $match+1;
 
    $matches[$match] = $item->route;
}
if(key_exists(1, $matches)) {
    array_shift($matches);
    array_reverse($matches, false);
 
    $action_url = JRoute::_(JUri::base(true).'/'.$matches[0]);
}

These snippets just ensure that at least some page parameters as defined in a menu item are used on the redirected page. If it finds a matching url it uses the best match. If it doesn't find anything, well... bad luck.

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <drupal6>, <javascript>, <php>. The supported tag styles are: <foo>, [foo].

More information about formatting options