Sander,
vancanneyt wrote:
Johan, Just a small question about developing content URL's and category section links in a component, is it something like this?
index.php?view=article&id=". $rows->id ."&Itemid=43
but here it just adds the id number and not the new way of number and title, so how do we create the correct links like the examples you gave?
When i look to your example it should look like this:
index.php?view=article&id=". $rows->id .":".$rows->title_alias."&Itemid=43
Is this correct or can we do it in an other way?
You, as a component developer are responsible to decide how your links will look like. com_weblinks and com_newsfeeds use, a link format that is hierarchical and unique, it does that by adding the so called slug to the link. You are correct in saying that the id is generated like
Code:
id=$row->id.':'.$row->title_alias.
This is one way to do it and the way the core will be doing it. Does that mean this is the only way ? Definitly not. Let's have a look at one of the newsfeed links to get a better idea of how this works. In com_newsfeeds for the actual newsfeed item link we do the following (com_newsfeeds/views/category/view.html.php line 82)
Code:
$item->link = sefRelToAbs('index.php?view=newsfeed&catid='.$category->slug.'&id='. $item->slug );
This code is reponsible for creating the route (URL) for a newsfeed item. As you can see I'm passing in two things :
- catid : the newsfeed category identifier slug
- id : the newsfeed item identifier slug
The slug is this case is created by the categories model on line 113 for the id (item) slug and on line 195 for the catid (category) slug. The slug is a combination of the id and the alias.
The newsfeeds components is adding both the category and item slug to the URL to be able to create hierarchical URL's. Not all components need to or will be doing it like this but it's best to create hierarchical URL's for content driven components. In the core this means com_newsfeeds, com_weblinks, com_contact, com_content, com_banners. Other component can use a different formatting.
Building the URLNow, when sefRelToAbs is called it will fire up JRouter and ask him to build the route. The buidling process is divided into two steps :
1. Create the application (menu) route, based on the Itemid
2. Create the component route, based on the extra information you passed into sefRelToAbs
This will result in a URL like /index.php/applicationroute/componentroute?query....
Step 1 you don't need to worry about, JRouter is a big boy and he handles that one for you. Step 2 is the one you are in charge of by adding the router.php file to your component. Let's see what com_newsfeed does here :
Code:
function NewsfeedsBuildRoute(&$query)
{
$parts = array();
if(isset($query['catid']))
{
$parts[] = $query['catid'];
unset($query['catid']);
};
if(isset($query['id']))
{
$parts[] = $query['id'];
unset($query['id']);
};
unset($query['view']);
return $parts;
}
As you can see, it's pretty simple. The NewsfeedsBuildRoute function receives a $query array examines it and adds the relevant parts in the right order to the $parts array and returns this one.
In case of the example link it means that JRouter will add the $category->slug and the $item->slug to the route, which gives the following result :
index.php/applicationroute/$category->slug/$item->slug
You will notice that the function also unsets the information from the query array. You need to do this, otherwise JRouter will add this info to the URL in the form of a query string.
Parsing the URLThe parsing of the route is also a two step process, in the first step JRouter tries to find the correct Itemid based on the application route. In the second part the component router is called to handle the remaining parts of the route that are left unhandled by JRouter.
As I already explained parsing the URL is the opposite process of building it. The trick is to understand the structure of the URL filter the needed information and push this into JRequest.
In com_newsfeeds we do the following :
Code:
function NewsfeedsParseRoute($parts)
{
$menu =& JMenu::getInstance();
$item =& $menu->getActive();
// Count route parts
$nArray = count($parts);
//Handle View and Identifier
switch($item->query['view'])
{
case 'categories' :
{
if($nArray == 1) {
$view = 'category';
}
if($nArray == 2) {
$view = 'newsfeed';
}
$id = $parts[$nArray-1];
} break;
case 'category' :
{
$id = $parts[$nArray-1];
$view = 'newsfeed';
} break;
}
JRequest::setVar('view', $view, 'get');
JRequest::setVar('id', (int)$id, 'get');
}
The magic here is that we need to know in what level of the hierarchy we are by examining the root element. We do this by looking at the parent view name of the active menu item and we also look at the size of the parts array :
Here we request the menu item view :
Code:
$item-query['view']
Here we calculate the number of items in the parts array :
Code:
$nArray = count($parts);
These two pieces of info allow us to correct filter the info passed through in the parts array. As you can see in the code we are handling 3 different cases :
1. The menu item is a link to the newsfeed catagories view and the parts have two items, in this case we know we have a link to a newsfeed item
2. The menu item is a link to the newsfeed categories view and the parts have one item, in this case we know we have a link to a newsfeed category
3. The mnu item is a link to a newsfeed category, in this case we know the that we extra information in the URL is the identifier of the newsfeed item.
At the end of the function we are setting both the right view and the right identifier, after which JApplication dispatch can take over.
And voila all done !
