First:
You will have to change router.php in your component's root.
You can not fork it.
Second:
You need to change YourcomponentBuildRoute and YourcomponentParseRoute
Let's start with YourcomponentBuildRoute.
Is starts with setting $segments = array();
That will be your array of segments (duh).
Check the function and it will be quite clear:
This code
if(isset($query['view']))
{
$view = $query['view'];
$segments[] = $view;
unset( $query['view'] );
}
check for the query view (you will see this when you have SEF turned off.
Your url will be something like:
http://(domain/)index.php?option=com_yourcomponent&view=deals&Itemid=117
==> Itemdid is the id of the active menu, the view is in this case "deals"
segments[] will only return "deals".
No, when selecting an item, your url will probably be someting like:
http://(domain/)index.php?option=com_yourcomponent&view=deal&layout=deal&cid[0]=1&Itemid=117
Rewriting this will become:
http://(domain)/deals/deal/deal?cid[0]=1 The first "deals" in the URL you pasted is because your menuitem is called "deals".
Breaking down you have for the menuitem http://(domain)/deals/
Then the view = deal, and after that layout = deal
So, there is only cid[0]=1 left to route.
If your deal has a name, you can do this by checking $query after the check for view and layout
if (isset($query['cid'])) {
$db = JFactory::getDbo();
$dbQuery = $db->getQuery(true)
->select('name')
->from('#__yourcomponent_deals')
->where('id=' . (int) $query['cid'][0]);
$db->setQuery($dbQuery);
$name = $db->loadResult();
//some url thingy, you can change it or make it safer/better
$segments[] = urlencode($name);
unset( $query['cid'] );
}
The, your url will be on the list:
http://(domain)/deals/deal/deal/free-beer-2015
Without the YourcomponentParseRoute, this will not work because YourcomponentParseRoute has no way of knowing what "free-beer-2015" has for id to look for in the database. Cook needs cid[].
Let's make it understand:
Go to the url http://(domain)/deals/deal/deal/free-beer-2015, it will probably give a nice page without your item
Lookup to the YourcomponentParseRoute function and do a var_dump of the segments:
Then refresh and on top of the page you'll see: array(3) { [0]=> string(6) "deal" [1]=> string(10) "deal" [2]=> string(7) "free-beer-2015" }
The first entry is your view, the second the layout, the router.php has code for that in the YourcomponentParseRoute function
The third part is the one we need, is it the name of our item.
So, after the first to segment-checks do a check on the 3rd:
if (isset($segments[$nextPos])) {
$db = JFactory::getDbo();
//get the id from name
$dbQuery = $db->getQuery(true)
->select('id')
->from('#__yourcomponent_deals')
->where("name='" . $segments[$nextPos]."'");
$db->setQuery($dbQuery);
$id = $db->loadResult();
//set the var needed by Cook
$vars['cid'][0] = $id;
//move to next segment
$nextPos++;
}
That is basically it.
You will probably need to do some rework so that the name will always get the correct id, maybe work add an alias wizard to your table and work with that.
That is safer. For items with the same name you will have no problem then.
You can also use the id as an extra segment:
http://(domain)/deals/deal/deal/1/free-beer-2015
Good luck!