Ahhh the joys of the current routing system in Joomla. (I thought I heard that someone was doing a Google Summer of Code project to update the routing system, but haven't seen anything else on that.)
So my understanding of the routing is that Joomla will try to parse as much of the request uri (ie. foo/2
) to a menu item as possible. In your case, this would match on just foo
.
Next, the rest of the pieces are passed to the router.php
file for the component that matches that menu item. In your case, I'm guessing that this is the com_content router at components/com_content/router.php
.
This will call the parse
function in this class and pass in the segments (which in this case will just be 2
.
The router has code (which you can look through if you would like) to try to parse the segments in the uri into article ids and such. The core piece that affects you is what happens if there is only one segment piece:
/*
* If there is only one segment, then it points to either an article or a category.
* We test it first to see if it is a category. If the id and alias match a category,
* then we assume it is a category. If they don't we assume it is an article
*/
if ($count == 1)
{
// We check to see if an alias is given. If not, we assume it is an article
if (strpos($segments[0], ':') === false)
{
$vars['view'] = 'article';
$vars['id'] = (int) $segments[0];
return $vars;
}
list($id, $alias) = explode(':', $segments[0], 2);
// First we check if it is a category
$category = JCategories::getInstance('Content')->get($id);
if ($category && $category->alias == $alias)
{
$vars['view'] = 'category';
$vars['id'] = $id;
return $vars;
}
else
{
$query = $db->getQuery(true)
->select($db->quoteName(array('alias', 'catid')))
->from($db->quoteName('#__content'))
->where($db->quoteName('id') . ' = ' . (int) $id);
$db->setQuery($query);
$article = $db->loadObject();
if ($article)
{
if ($article->alias == $alias)
{
$vars['view'] = 'article';
$vars['catid'] = (int) $article->catid;
$vars['id'] = (int) $id;
return $vars;
}
}
}
}
Basically, it checks to see if it is a category id or an article id. Since you have an article with the id 2, it passes and thus we now move forward with that as the id instead of whatever you sent in the menu id.
This is exactly what com_content was coded to do, for better or worse... :/