Understanding SEF routing for Joomla Components
Developing bespoke components for Joomla can be quite daunting. There are a lot of resources, books, dev articles and the API documentation; these try to give you a basic understanding of how things should be laid out. A lot of these work on the premise of learning by doing. Many of the documented examples from the API point developers to look at the core components to see how it works.
Configuring an effective component router can be quite tricky, as it depends on how complex your component is. This article serves as a reference for how routing works in Joomla, why it's important, and how you could make better use of component routing in your projects.
Routing Modes #
There three different implementations of SEF that Joomla supports;
- Rewrites via Apache mod_rewrite or IIS URL rewriter. (e.g. http://www.example.com/component/name/view/layout.html)
- Rewrites via php implementation. (e.g. http://www.example.com/index.php/component/name/view/layout.html)
- Rewrites disabled. (e.g. http://www.example.com/index.php?option=com\_name&view=view&layout=layout)
Options 1 & 2 would use your router to build and parse the route. The third would not require parsing, as we have the request variables in a raw form anyway. As far as I am aware, your routes won't be built either when SEF URLs are disabled. Without specifying menu item ids in your routes you won't be getting menu item matching. The ".html" suffix on the end of the link in the first two is an optional setting in the Joomla configuration. Find out more about enabling these options here
Integrating with Menu Items #
For the purposes of SEF URIs, there are two levels of support which you need to be aware of:
- SEF URIs without a menu item (e.g. http://www.example.com/component/name/view/layout.html)
- SEF URIs with a menu item. (e.g. http://www.example.com/any/sub/menu/item.html)
For basic routing, such as supporting menu item links, you can use a really basic 'build route' and ignore the 'parse route' function altogether. This means that you need to write some code which checks the route query string against a list of menu items for your component. If there is a successful match, the query string will be replaced with the menu link. Your router should remove the matched query items from the request array, which is passed in by reference. Any unmatched variables should be left untouched, and will be appended to the URI.
Why is this important? #
There are several reasons why you should ensure that your component properly integrates with menu items.
- Modules are assigned directly to menu items. If your router doesn't match match up to a menu item then the end user can't assign modules to the layout.
- Menu items can be configured with access levels. If Joomla can't match a menu item, then the access restriction that was applied to the menu item won't apply.
- You can set up your router to match custom, application specific variables. This allows your component to have finer grained menu items of the same type. One example of this is the content core component, which allows you to link to specific content items.
Special Variables #
You can include any GET variables in your query, however there are some which get special treatment from Joomla:
- option points to a component, and uses the full name (such as com_name)
- view points to a view folder within the component, the default is typically default
- layout points to a layout within a view, the default is typically default
- task points to a function within a view (e.g. view.html.php), the default is typically display
- tmpl allows you to choose the display mode. You can choose tmpl=component to capture just the component output without your template.
- Itemid is the menu item id from the menu table.
The good thing about this is that it's down to you how you use variables. When you construct menu items in the Joomla, they will be created as links to view folders and layout files. Menu items will include the option name of your component, for internal routing. They will include a view, unless the link is to a view named default in which case it will be omitted. The layout name will similarly be included unless it is named default.
Outputting component routes #
As you application grows, you will inevitably want to create links (or HTML redirects) to other areas of your application. This is where we use the JRoute::_() static method. This method basically acts as a URI renderer, and it will output relative URIs according to your site configuration. Here are a few examples:
JRoute::_('index.php?view=cheese');
This would be used internally to link to the default layout of the cheese view within the component. In Joomla 1.5, you had to specify the option for every call, but from 1.6+ this can be omitted for internal component links.
JRoute::_('index.php?view=cheese&layout=stilton');
This would again internally link to the cheese view, but instead would invoke the stilton layout file.
JRoute::_('index.php?option=com_content&view=article&id=5');
This would be used to create a link to the core content component, and would link to the single article display page. It should also load and display article with id number 5 from the database. When linking to external components, that component's route functions are used to determine the correct route.
JRoute::_() includes a second parameter, which is a switch for html encoding. By default, the method will html encode it's output. This doesn't work with HTTP redirects, because any ampersands will be converted to & which breaks your variable names. So when using this function outside of output to a HTML page, this needs to be set to false.
If you would like to see some examples in action, there are some in this wiki entry on the Joomla documentation wiki. I'll be following up with a couple of practical techniques that I have put together in due course.