<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Iv660</id>
	<title>Joomla! Documentation - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Iv660"/>
	<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/Special:Contributions/Iv660"/>
	<updated>2026-08-10T05:03:49Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Development_Working_Group&amp;diff=62172</id>
		<title>Development Working Group</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Development_Working_Group&amp;diff=62172"/>
		<updated>2011-09-23T00:03:03Z</updated>

		<summary type="html">&lt;p&gt;Iv660: /* Introduction */ letter case&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{incomplete}}[[Image:workgroups_development.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;&#039;&#039;&amp;quot;..To develop a cutting edge, state of the art Web Content Management application framework...&amp;quot;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The main responsibility of the [[Development Working Group]] is taking care of the development of the Joomla! application framework and the Joomla! Content Management System (CMS). Besides the development of the Joomla! codebase the development working group defines the Joomla! roadmap strategy, creating (architectural) designs for major and minor versions and of course take care of bug and security fixes in maintenance versions.&lt;br /&gt;
&lt;br /&gt;
The development working group holds two teams: the [[Development Team]] and the so called [[Bug Squad]]. Both teams have a separate responsibility but together they form the development force for the Joomla! project.&lt;br /&gt;
&lt;br /&gt;
Joomla! is as every other open-source project based upon the fundaments of collaborative and is a community-driven project. This means that the software, the documentation, the ever growing number of available the extensions, support (forum, mailing, lists newsletters, user groups are collaboratively produced by users and developers all over the world.&lt;br /&gt;
&lt;br /&gt;
In this section of the documentation wiki we have tried to describe all relevant aspects to Joomla! development. Our effort strives to be as complete as we can be, but we don&#039;t rule out that information you are looking for is not (yet) documented. We encourage everyone to help completing the documentation effort and maximize the community effect within the Joomla! project.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
&lt;br /&gt;
The amount of information that is available from this page is like a small (e-)book. We tried to organize the information in a logical order, and also structure the information in the most efficient way. To prevent you from reading for some hours, we use a simple documentation method. Per topic we draft a short description on the information that can be found, and in the linked pages we will provide as much as possible detail. Keep in mind that you can use the free-text search or the generated table of contents for this documentation category to find your information. If there is information missing, feel free to add this within this wiki.&lt;br /&gt;
&lt;br /&gt;
* [[First look around]]&lt;br /&gt;
* [[Guide to the Development Documentation wiki section]]&lt;br /&gt;
&lt;br /&gt;
== Technical infrastructure == &lt;br /&gt;
&lt;br /&gt;
For collaboration we have set up an infrastructure like version control, the bug tracker and of course this wiki for documentation. These assets are essential for Joomla! development. Below you will find links to the infrastructure that is used within the Joomla! project.&lt;br /&gt;
&lt;br /&gt;
* [[Mailing lists]]&lt;br /&gt;
* [[Version control]]&lt;br /&gt;
* [[Bug tracker]]&lt;br /&gt;
* [[IRC/Real-Time Chat]]&lt;br /&gt;
* [[Wikis]]&lt;br /&gt;
* [[Web sites]]&lt;br /&gt;
* [[Joomlacode]]&lt;br /&gt;
&lt;br /&gt;
== Social and Political Infrastructure ==&lt;br /&gt;
&lt;br /&gt;
Ready for something more heavy at tea? Then you&#039;re in the right place here ;-) In this section we describe the basic organizational structures we have put in place, but probably at least important we describe the code of conduct we follow. For open source projects this is especially important because we have no hierarchical relation with our volunteers, the Joomla! project follows the [[http://producingoss.com/en/consensus-democracy.html Consensus Based Democracy]] model.&lt;br /&gt;
&lt;br /&gt;
* [[Organizational structure]]&lt;br /&gt;
* [[Code of conduct]]&lt;br /&gt;
&lt;br /&gt;
== Communications ==&lt;br /&gt;
&lt;br /&gt;
There are several ways to get in touch, or communicate with the development community of Joomla! Within the working groups we try to share as much as possible information, using different media. It is a mix of tools and events we organized, details can be found in the links below.&lt;br /&gt;
&lt;br /&gt;
* [http://developer.joomla.org/section-blog.html Development blog]&lt;br /&gt;
* [http://developer.joomla.org/gsoc2008.html Summer of Code blog]&lt;br /&gt;
* [http://developer.joomla.org/bug-squad-blog.html Bug Squad blog]&lt;br /&gt;
* [http://forum.joomla.org/viewforum.php?f=509&amp;amp;sid=fb99f7b1a81437ff25e8dd707343bae0 Development forum]&lt;br /&gt;
* [[Development meetings]]&lt;br /&gt;
* [http://www.google.com/calendar/embed?src=calendar@joomla.org Joomla! events]&lt;br /&gt;
* [http://community.joomla.org/joomla-user-groups.html Local user groups]&lt;br /&gt;
* [http://docs.joomla.org/Pizza_Bugs_and_Fun_2 Pizza Bugs and Fun]&lt;br /&gt;
&lt;br /&gt;
== Packaging, releasing and daily development ==&lt;br /&gt;
&lt;br /&gt;
* Release numbering&lt;br /&gt;
* Release branches&lt;br /&gt;
* Sandboxes&lt;br /&gt;
* Stabilizing a release&lt;br /&gt;
* Packaging&lt;br /&gt;
* Testing and releasing&lt;br /&gt;
* Maintaining multiple release lines (general description, and our current release lines)&lt;br /&gt;
* Releases and daily development&lt;br /&gt;
&lt;br /&gt;
== Development community ==&lt;br /&gt;
&lt;br /&gt;
* How to get involved?&lt;br /&gt;
* 3rd party development&lt;br /&gt;
* Interesting topics to study&lt;br /&gt;
* Recommended readings and books&lt;br /&gt;
&lt;br /&gt;
== Licensing and copyrights == &lt;br /&gt;
&lt;br /&gt;
* General Public License&lt;br /&gt;
&lt;br /&gt;
== How to contribute to Joomla! development ==&lt;br /&gt;
&lt;br /&gt;
== Coding standards ==&lt;br /&gt;
A list of Joomla! coding standards as of 13 February 2010 can be found here: [[Coding style and standards]]. There is also a list of [[Core Development Best Practices]].&lt;br /&gt;
&lt;br /&gt;
== Writing secure Joomla! code ==&lt;br /&gt;
&lt;br /&gt;
* [http://developer.joomla.org/tutorials/181-preventing-sql-injections.html Preventing SQL injections]&lt;br /&gt;
* [[Secure coding guidelines]]&lt;br /&gt;
&lt;br /&gt;
== Unit testing within Joomla! ==&lt;br /&gt;
&lt;br /&gt;
The goal of unit testing is to isolate each part of the program and show that the individual parts are correct. A unit test provides a strict, written contract that the piece of code must satisfy. As a result, it affords several benefits. Unit tests find problems early in the development cycle.&lt;br /&gt;
&lt;br /&gt;
In computer programming, unit testing is a method of testing that verifies the individual units of source code are working properly. A unit is the smallest testable part of an application. In procedural programming a unit may be an individual program, function, procedure, etc., while in object-oriented programming, the smallest unit is a method, which may belong to a base/super class, abstract class or derived/child class.&lt;br /&gt;
&lt;br /&gt;
Ideally, each test case is independent from the others; Double objects like stubs, mock or fake objects as well as test harnesses can be used to assist testing a module in isolation. Unit testing is typically done by software developers to ensure that the code they have written meets software requirements and behaves as the developer intended.&lt;br /&gt;
&lt;br /&gt;
Ground work on the implementation of unit testing has been done by Enno Klasing during the Summer of Code 2007 project and has been perfected by Alan Langford from the Joomla! [[Development Team]]. The way [[Unit Testing]] is implemented within the Joomla! project has been documented in the [[Unit Testing]] chapter.&lt;br /&gt;
&lt;br /&gt;
* [[Unit Testing]]&lt;br /&gt;
&lt;br /&gt;
== What does a Joomla! development environment look like ==&lt;br /&gt;
&lt;br /&gt;
== Debugging your Joomla! code ==&lt;br /&gt;
One way to debug Joomla! code is using the open-source programs Eclipse and XDebug. Instructions for setting up these programs is available in [[Setting up your workstation for Joomla! development]].&lt;br /&gt;
&lt;br /&gt;
== Joomla! organization ==&lt;br /&gt;
&lt;br /&gt;
* An explanation on how the [[Development Team]] is organized.&lt;br /&gt;
* An explanation on how the [[Bug Squad]] is organized.&lt;br /&gt;
&lt;br /&gt;
== Joomla! planning process and procedures ==&lt;br /&gt;
* Description on the [[Development Strategy of Joomla!]]&lt;br /&gt;
* A description of how the [[Joomla! Maintenance Procedures]] are organized&lt;br /&gt;
* [[Release procedure and checklist]]&lt;br /&gt;
* [[Team member administration]]&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
&lt;br /&gt;
This is &amp;quot;old&amp;quot; content and needs to be moved to the final location in this wiki, work in progress...&lt;br /&gt;
&lt;br /&gt;
* [[Unit Testing]] within the Joomla! project&lt;br /&gt;
* [[The use of Subversion]]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Development Working Group]]&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Working Groups]]&lt;/div&gt;</summary>
		<author><name>Iv660</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Talk:How_to_determine_if_the_user_is_viewing_the_front_page&amp;diff=61308</id>
		<title>Talk:How to determine if the user is viewing the front page</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Talk:How_to_determine_if_the_user_is_viewing_the_front_page&amp;diff=61308"/>
		<updated>2011-08-13T00:30:31Z</updated>

		<summary type="html">&lt;p&gt;Iv660: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;would then function as in the case of a 404 SEF to show that a module appears as a 404?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Joomla! 1.5 example fails===&lt;br /&gt;
&lt;br /&gt;
Joomla! 1.5 example fails unless the Itemid is added explicitly to URL.&lt;br /&gt;
[[User:Iv660|Iv660]] 19:29, 12 August 2011 (CDT)&lt;/div&gt;</summary>
		<author><name>Iv660</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Talk:How_to_determine_if_the_user_is_viewing_the_front_page&amp;diff=61307</id>
		<title>Talk:How to determine if the user is viewing the front page</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Talk:How_to_determine_if_the_user_is_viewing_the_front_page&amp;diff=61307"/>
		<updated>2011-08-13T00:29:03Z</updated>

		<summary type="html">&lt;p&gt;Iv660: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;would then function as in the case of a 404 SEF to show that a module appears as a 404?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Joomla! 1.5 example fails unless the Itemid is added explicitly to URL.&lt;br /&gt;
[[User:Iv660|Iv660]] 19:29, 12 August 2011 (CDT)&lt;/div&gt;</summary>
		<author><name>Iv660</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J2.5:Supporting_SEF_URLs_in_your_component&amp;diff=61306</id>
		<title>J2.5:Supporting SEF URLs in your component</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J2.5:Supporting_SEF_URLs_in_your_component&amp;diff=61306"/>
		<updated>2011-08-12T23:45:35Z</updated>

		<summary type="html">&lt;p&gt;Iv660: /* The Slug */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{:Search Engine Friendly URLs}}&lt;br /&gt;
Joomla can, initially, only create human readable URLs for built-in components. As a [[Developers|developer]], you have to create a &#039;&#039;&#039;router&#039;&#039;&#039; to allow your [[component]] to create human readable URLs.&lt;br /&gt;
&lt;br /&gt;
== Preparing Your Data for Routing ==&lt;br /&gt;
&lt;br /&gt;
=== The Alias ===&lt;br /&gt;
&lt;br /&gt;
The first step is the generation of the so called alias. The alias is used in the URL instead of the title (the alias is the text you want to have in the URL). The alias has to be URI safe, which means accented UTF­8 characters are replaced by their ASCII­7 equivalents, white spaces by hyphens, etc.&lt;br /&gt;
&lt;br /&gt;
The alias can be defined by the user, but you should ensure that the above requirements for a URL safe alias are met. A good way to do so is to use the JTable::check() method during the save process. Have a look at this example code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function check()&lt;br /&gt;
{&lt;br /&gt;
    jimport( &#039;joomla.filter.output&#039; );&lt;br /&gt;
    if(empty($this-&amp;gt;alias)) {&lt;br /&gt;
	    $this-&amp;gt;alias = $this-&amp;gt;title;&lt;br /&gt;
    }&lt;br /&gt;
    $this-&amp;gt;alias = JFilterOutput::stringURLSafe($this-&amp;gt;alias);&lt;br /&gt;
&lt;br /&gt;
    /* All your other checks */&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the alias field is empty the title will be used as alias. Then the alias will be made URLSafe using the JFilterOutput::stringURLSafe() method.&lt;br /&gt;
&lt;br /&gt;
=== The Slug ===&lt;br /&gt;
&lt;br /&gt;
Continuing with the same example, the &amp;quot;slug&amp;quot; - &amp;quot;1­:welcome­-to­-joomla&amp;quot; has two parts. The first part is the article identifier (id) and the second is the alias. They are separated by a colon. These two elements were combined during the database query in the model:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$query = &#039;SELECT a.*, &#039;.&lt;br /&gt;
         &#039;CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(&amp;quot;:&amp;quot;, a.id, a.alias) ELSE a.id END as slug,&#039;&lt;br /&gt;
         /*...*/;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this step the slug is used instead of the id.&lt;br /&gt;
&lt;br /&gt;
== Routing URL&#039;s ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;JRoute::_&amp;lt;/code&amp;gt; method translates the internal Joomla! URL to a custom URL. &amp;lt;code&amp;gt;JRoute&amp;lt;/code&amp;gt; has three parameters and its prototype is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;JRoute::_( $url, $xhtml = true, $ssl=null );&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;$url&amp;lt;/code&amp;gt; is a string containing the absolute or relative internal Joomla! URL.&lt;br /&gt;
* &amp;lt;code&amp;gt;$xhtml&amp;lt;/code&amp;gt; is a boolean value that specifies whether or not the output should be in XHTML. This parameter is optional and if omitted defaults to true.&lt;br /&gt;
* &amp;lt;code&amp;gt;$ssl&amp;lt;/code&amp;gt; is an integer value that specifies whether the URI should be secure. It should be set to 1 to force the URI to be secure using the global secure site URI, 0 to leave it in the same state as when it was passed, and -1 to force the URI to be unsecure using the global unsecure site URI.&lt;br /&gt;
&lt;br /&gt;
The most important parameter is &amp;lt;code&amp;gt;$url&amp;lt;/code&amp;gt;. A call to this method might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;JRoute::_( &#039;index.php?view=article&amp;amp;id=&#039;.$row-&amp;gt;slug );&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$row-­&amp;gt;slug&amp;lt;/code&amp;gt; is the value that was generated in step 2 from a combination of id and title alias.&lt;br /&gt;
&lt;br /&gt;
Another advantage of using JRoute is that the router now handles $option (the component name) and the $Itemid (the menu item ID). The component itself doesn’t have to know its name ($option) or the active menu item ($Itemid) like it did in previous version of Joomla!.&lt;br /&gt;
&lt;br /&gt;
It is important that you think about the sequence of the URL parameter in this stage. This will be more clear when we have a deeper look at the router.php in the next section.&lt;br /&gt;
&lt;br /&gt;
The building process of JRouter is divided into two steps:&lt;br /&gt;
&lt;br /&gt;
* Create the application route. The application route is fully handled by JRouter and the component developer doesn’t have to do anything to make it work.&lt;br /&gt;
* Create the component route. To create the component route, JRouter looks for the router.php in the component directory which is responsible for building the route for the component.&lt;br /&gt;
&lt;br /&gt;
== The Component Router ==&lt;br /&gt;
&lt;br /&gt;
We will have two functions in the router.php. One is responsible for building the URL and the other is responsible for parsing it. In the next examples, a very basic and a more advanced one, we assume that we have three views that links can point to. The first is a categories overview (view=categories), the second is a single category (view=category) and the third is a single article (view=article).&lt;br /&gt;
&lt;br /&gt;
The file router.php should be in the site area of your component. It is not used on admin/backend pages. Don&#039;t forget to add it to your installation XML in the site folder.&lt;br /&gt;
&lt;br /&gt;
=== A Simple Example ===&lt;br /&gt;
&lt;br /&gt;
This simple example will illustrate the basics of implementing a router for your component.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function [componentname]BuildRoute( &amp;amp;$query )&lt;br /&gt;
{&lt;br /&gt;
       $segments = array();&lt;br /&gt;
       if(isset($query[&#039;view&#039;]))&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;view&#039;];&lt;br /&gt;
                unset( $query[&#039;view&#039;] );&lt;br /&gt;
       }&lt;br /&gt;
       if(isset($query[&#039;id&#039;]))&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;id&#039;];&lt;br /&gt;
                unset( $query[&#039;id&#039;] );&lt;br /&gt;
       };&lt;br /&gt;
       return $segments;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt; passes a $query array to the &amp;lt;code&amp;gt;[&#039;&#039;componentname&#039;&#039;]BuildRoute&amp;lt;/code&amp;gt; function. This function will add the relevant parts of the array to the $segments array in the right order and will return the properly ordered array. The content of the &amp;lt;code&amp;gt;$query&amp;lt;/code&amp;gt; array needs to be unset, otherwise &amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt; will add it to the URL in the form of a query string (i.e. any variables that are not handled by the router will be passed in the query string).&lt;br /&gt;
&lt;br /&gt;
The prefix &#039;&#039;componentname&#039;&#039; is the name for your component, as found in the directory holding the component&#039;s files. For instance, a component &amp;quot;Magic&amp;quot; in directory &amp;lt;code&amp;gt;/components/com_magic/...&amp;lt;/code&amp;gt; would use a prefix &amp;lt;code&amp;gt;magic&amp;lt;/code&amp;gt; (all lower case).&lt;br /&gt;
&lt;br /&gt;
The next function in the &amp;lt;code&amp;gt;router.php&amp;lt;/code&amp;gt; parses the URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function [componentname]ParseRoute( $segments )&lt;br /&gt;
{&lt;br /&gt;
       $vars = array();&lt;br /&gt;
       switch($segments[0])&lt;br /&gt;
       {&lt;br /&gt;
               case &#039;categories&#039;:&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;categories&#039;;&lt;br /&gt;
                       break;&lt;br /&gt;
               case &#039;category&#039;:&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;category&#039;;&lt;br /&gt;
                       $id = explode( &#039;:&#039;, $segments[1] );&lt;br /&gt;
                       $vars[&#039;id&#039;] = (int) $id[0];&lt;br /&gt;
                       break;&lt;br /&gt;
               case &#039;article&#039;:&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;article&#039;;&lt;br /&gt;
                       $id = explode( &#039;:&#039;, $segments[1] );&lt;br /&gt;
                       $vars[&#039;id&#039;] = (int) $id[0];&lt;br /&gt;
                       break;&lt;br /&gt;
       }&lt;br /&gt;
       return $vars;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What happens here? In the function &amp;lt;code&amp;gt;[&#039;&#039;componentname&#039;&#039;]BuildRoute&amp;lt;/code&amp;gt; we arranged the items in the &amp;lt;code&amp;gt;$query&amp;lt;/code&amp;gt; array in a specific sequence. This means that in this example the view is first, the catid is second and the id is third in the array.&lt;br /&gt;
&lt;br /&gt;
By reading &amp;lt;code&amp;gt;$segments[0]&amp;lt;/code&amp;gt;, we access the name of the view. We set the right view and/or identifier depending on its value and we return the &amp;lt;code&amp;gt;$vars&amp;lt;/code&amp;gt; array to &amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt;. $vars should be an associative array similar to the array that was passed to the BuildRoute method.&lt;br /&gt;
&lt;br /&gt;
The above example of the &amp;lt;code&amp;gt;router.php&amp;lt;/code&amp;gt; is a very simple way to generate sef URL&#039;s but should show how this works quite clearly.&lt;br /&gt;
&lt;br /&gt;
The generated URL in this example contains the name of the view and doesn&#039;t reflect the content hierarchy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]/[view]/[slug]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== A More Advanced Example ===&lt;br /&gt;
&lt;br /&gt;
In the next example we will try to get rid of the need for the view and we will try to reflect the current hierarchy level in the URL.&lt;br /&gt;
&lt;br /&gt;
The goal is URL&#039;s that look like:&lt;br /&gt;
&lt;br /&gt;
* When viewing an article: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]/[category]/[article]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* When viewing a category: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]/[category]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* When viewing the categories overview: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s assume we have done step 1 and 2 also for the category.&lt;br /&gt;
&lt;br /&gt;
The link to the article would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JRoute::_( &#039;index.php?view=article&amp;amp;catid=&#039;.$row-­&amp;gt;catslug .&#039;&amp;amp;id=&#039;.$row-­&amp;gt;slug );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the Link to the category would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JRoute::_( &#039;index.php?view=category&amp;amp;id=&#039;.$row-&amp;gt;catslug );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corresponding &amp;lt;code&amp;gt;router.php&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function [&#039;&#039;Componentname&#039;&#039;]BuildRoute(&amp;amp;$query)&lt;br /&gt;
{&lt;br /&gt;
       $segments = array();&lt;br /&gt;
       if(isset( $query[&#039;catid&#039;] ))&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;catid&#039;];&lt;br /&gt;
                unset( $query[&#039;catid&#039;] );&lt;br /&gt;
       };&lt;br /&gt;
       if( isset($query[&#039;id&#039;]) )&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;id&#039;];&lt;br /&gt;
                unset( $query[&#039;id&#039;] );&lt;br /&gt;
       };&lt;br /&gt;
       unset( $query[&#039;view&#039;] );&lt;br /&gt;
       return $segments;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference now is that we don’t add the name of the view to the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array. We still unset the view key since otherwise, &amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt; would add it to the URL as part of the query string. Another new thing here is the additional parameter catid that we push into the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function [&#039;&#039;Componentname&#039;&#039;]ParseRoute($segments)&lt;br /&gt;
{&lt;br /&gt;
       $vars = array();&lt;br /&gt;
       $app =&amp;amp; JFactory::getApplication();&lt;br /&gt;
       $menu =&amp;amp; $app-&amp;gt;getMenu();&lt;br /&gt;
       $item =&amp;amp; $menu-&amp;gt;getActive();&lt;br /&gt;
       // Count segments&lt;br /&gt;
       $count = count( $segments );&lt;br /&gt;
       //Handle View and Identifier&lt;br /&gt;
       switch( $item-&amp;gt;query[&#039;view&#039;] )&lt;br /&gt;
       {&lt;br /&gt;
               case &#039;categories&#039;:&lt;br /&gt;
                       if($count == 1) {&lt;br /&gt;
                               $vars[&#039;view&#039;] = &#039;category&#039;;&lt;br /&gt;
                       }&lt;br /&gt;
                       if($count == 2) {&lt;br /&gt;
                               $vars[&#039;view&#039;] = &#039;article&#039;;&lt;br /&gt;
                       }&lt;br /&gt;
                       $id = explode( &#039;:&#039;, $segments[$count-1] );&lt;br /&gt;
                       $vars[&#039;id&#039;] = (int) $id[0];&lt;br /&gt;
                       break;&lt;br /&gt;
               case &#039;category&#039;:&lt;br /&gt;
                       $id   = explode( &#039;:&#039;, $segments[$count-1] );&lt;br /&gt;
                       $vars[&#039;id&#039;]   = (int) $id[0];&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;article&#039;;&lt;br /&gt;
                       break;&lt;br /&gt;
       }&lt;br /&gt;
       return $vars;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can see that this ParseRoute function has a lot of different code parts in comparison to the previous. The reason for this is simple. We don’t have the name of the view in the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array and we need to find another way to determine it.&lt;br /&gt;
&lt;br /&gt;
We need to find out which level of hierarchy we are in by receiving the root element. We do this by looking to the view name of the active menu item:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$item-­&amp;gt;query[&#039;view&#039;]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also we need to know the number of items in the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$count = count( $segments );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this information we can correctly set the view for all possible three cases:&lt;br /&gt;
&lt;br /&gt;
* The menu item is a link to the categories view and the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array has two items (&amp;lt;code&amp;gt;$catid&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;$id&amp;lt;/code&amp;gt;). In this case we know that we need to parse a link to an article .&lt;br /&gt;
* The menu item is a link to the categories view and the $segments array has one item ($id). In this case we know that we need to parse a link to a category.&lt;br /&gt;
* The menu item is a link to a category. In this case, we know that any item in the $segments array is the identifier for an article .&lt;br /&gt;
&lt;br /&gt;
The result of all this code is nice and human readable component URL&#039;s.&lt;br /&gt;
&lt;br /&gt;
== Application Route Parsing ==&lt;br /&gt;
&lt;br /&gt;
The [[API Execution Order]] outlines that the route (URL) is parsed immediately after initialisation is complete.  Since fancy URL&#039;s are not treated (yet) in the Administrator, we will follow the route parsing process in detail when &amp;lt;code&amp;gt;JSite::route&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;index.php&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
* Call to &amp;lt;code&amp;gt;JApplication::route&amp;lt;/code&amp;gt;&lt;br /&gt;
** Clone the URI&lt;br /&gt;
** Call to &amp;lt;code&amp;gt;JApplication::getRouter&amp;lt;/code&amp;gt;&lt;br /&gt;
*** Call to &amp;lt;code&amp;gt;JRouter::getInstance&amp;lt;/code&amp;gt; passing the type (&amp;quot;site&amp;quot;)&lt;br /&gt;
** Call to &amp;lt;code&amp;gt;JRouterSite::parse&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
*** Strip the suffix if applicable (added to $vars[&#039;format&#039;])&lt;br /&gt;
*** Re-set the route (URI)&lt;br /&gt;
*** Call to &amp;lt;code&amp;gt;JRouter::parse&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
**** Call to &amp;lt;code&amp;gt;JRouterSite::_processParseRules&amp;lt;/code&amp;gt; passing the URI (this will call custom route rules)&lt;br /&gt;
***** Call to &amp;lt;code&amp;gt;JRouter::_processParseRules&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
****** Call any custom routing rules (probably added via a system plugin using the &amp;lt;code&amp;gt;onAfterInitialise&amp;lt;/code&amp;gt; event trigger) passing the URI&lt;br /&gt;
****** Returns an array of vars&lt;br /&gt;
***** If SEF mode, replace &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt; variable with &amp;lt;/code&amp;gt;limitstart&amp;lt;/code&amp;gt;&lt;br /&gt;
**** If raw mode, call to &amp;lt;code&amp;gt;JRouterSite::_parseRawRoute&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
**** If SEF mode, call to &amp;lt;code&amp;gt;JRouterSite::_parseSefRoute&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
***** If the route (the URI path) is empty, load it from the default menu item; set the active menu item as the default&lt;br /&gt;
***** If first part is &amp;lt;code&amp;gt;/component/com_content&amp;lt;/code&amp;gt;, set the &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt; as the second segement.  Null the &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt;.&lt;br /&gt;
***** Else, loop through menu alias values and take off segments that match as the menu tree is traversed.  Set &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt; based on the last menu item found.&lt;br /&gt;
***** If the &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt; is set in the URL, set the active menu item based on this value.&lt;br /&gt;
***** Push the vars collected so far (eg, &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt;, etc) into the router object (&amp;lt;code&amp;gt;$this&amp;lt;/code&amp;gt;).&lt;br /&gt;
***** If the route and &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt; is set, load the component router;&lt;br /&gt;
***** Else, get the active menu item and get the route vars from it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Application Route Building ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Custom Router Rules ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Additional References ==&lt;br /&gt;
&lt;br /&gt;
There is a useful thread on this subject here: [[jtopic:148632]] (note, may be out of date)&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Tutorials]][[Category:Component Development]][[Category:Search Engine Friendly URLs]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Iv660</name></author>
	</entry>
</feed>