Creating a router.php file for making sef urls.

Creating a router.php file in a joomla component for making the urls SEO friendly is a little bit complex task, as compared to what we have learned in the previous steps. Let me explain to you in most simple words, as I can.

Why Search Engine Friendly urls?

Search engine friendly (SEF) urls are indeed human readable urls that provide particular information regarding the page they point to.  They posses good search engine ranking as compared to non-sef urls but there are also other reasons because of which sef urls are used in joomla and index.php is eliminated. Some of those reasons are, matching with the logic of the website as you will not have to use this file every time and on every page url with other variables, secondly they are easier to type, memorize and vocalize. Third, while making urls sef, you have to use .htaccess file for eliminating index.php from the url. The benefit of using this file is, it can provide a lot of security enhancements. For using .htaccess file, rename the htaccess.txt file in the joomla root to .htaccess. After you have set it, go to joomla backend configuration manager and switch on search engine friendly urls.

Concept of using alias in url:

When there is no sef on in joomla, generally records are loaded on the basis of their unique ids. But as these numeric keys are not allowed in the sef url structure, so in place of this, aliases are used which are generated for each url as they are saved. For example, while creating a new article at backend, you will see an alias field, which will automatically calculate the correct alias for that article if you don’t provide it by your own.

So, in our breed component, on which we have worked so far, we also have to create alias support first so that joomla could pick it and use it to construct a url.

Files to create / update

create router.php /site/router.php

File Details

update breedform.xml     /site/models/forms/breedform.xml

  <field name="alias" type="text"   
            label="COM_BREED_FORM_LBL_BREED_ALIAS"
            description="COM_BREED_FORM_DESC_BREED_ALIAS" />

First update the breedform.xml file located in /site/models/forms folder as listed above. This code will create a field for alias in the breed form view.

update default.php /site/views/breedform/tmpl/default.php

<div class="control-group">
		<div class="control-label"><?php echo $this->form->getLabel('alias'); ?></div>
		<div class="controls"><?php echo $this->form->getInput('alias'); ?></div>
	</div>

Next in default.php, located in /site/views/breedform/tmpl folder, put the above mentioned code, right after the breed name field code. After this, refresh the breed form in frontend and you will see an additional alias field there.

update breedform.php     /site/models/breedform.php

	public function &getData($id = null)
	{
		if ($this->item === null)
		{
			$this->item = false;

			$alias = JRequest::getVar('alias');
			if($alias!=''){
					$db = JFactory::getDbo();
						$dbQuery = $db->getQuery(true)
							->select('id')
							->from('#__breed_breed')
							->where('alias="'.$alias.'"');
						$db->setQuery($dbQuery);
					$id = $db->loadResult();	
			}

                else{
	        $id =  JRequest::getVar('id');
		
			if (empty($id))
			{
				$id = $this->getState('breed.id');
			}
			
			}

We are also updating breedform.php model file to revise the dynamics of getting the id of the record, because we are using alias, in place of id, in the sef mode. So, according to it, we have written some code in the getData() method which is first getting the alias value from the url and based on this, gets the proper id from the database table, corresponding the alias. The remaining code is same for this method.

update breed.php     /administrator/tables/breed.php

if (trim($this->alias) == '') {
			$this->alias = $this->breedname;
		}

		$this->alias = JApplication::stringURLSafe($this->alias);

Then put the above mentioned code in the breed.php file, located in  administrator/tables folder, in the check() method, right before return parent::check(); code. This code will automatically create alias suitable for being used in the urls.

update breed.xml     /administrator/models/forms/breed.xml

  <field name="alias" type="text"
            label="COM_BREED_FORM_LBL_BREED_ALIAS"
            description="COM_BREED_FORM_DESC_BREED_ALIAS"  /> 

Update the breed.xml form file at backend by adding alias field to it, so that an alias field could be rendered in the process of adding or editing a breed form.

 

update edit.php     /administrator/views/breed/tmpl/edit.php

<div class="control-group">
		<div class="control-label"><?php echo $this->form->getLabel('alias'); ?></div>
		<div class="controls"><?php echo $this->form->getInput('alias'); ?></div>
	</div>

In the edit.php breed view file, we are fetching the alias field we have created in the breed.xml file in this step for adding the alias value to the record.

create router.php /site/router.php

<?php
// No direct access
defined('_JEXEC') or die;

JLoader::register('BreedFrontendHelper', JPATH_BASE . '/components/com_breed/helpers/breed.php');

class BreedRouter extends JComponentRouterBase
{

	public function build(&$query)
	{
		$segments = array();
		$view     = null;

		if (isset($query['task']))
		{
			$taskParts  = explode('.edit', $query['task']);
			$segments[] = implode('/', $taskParts);
			$view       = $taskParts[0];
			unset($query['task']);
			unset($query['view']);
		}

		if (isset($query['view']))
		{
			$segments[] = $query['view'];
			$view       = $query['view'];
			unset($query['view']);
		}

		if (isset($query['id']))
		{
			if ($view !== null)
			{   
			 	$db = JFactory::getDbo();
						$dbQuery = $db->getQuery(true)
							->select('alias')
							->from('#__breed_breed')
							->where('id=' . (int) $query['id']);
						$db->setQuery($dbQuery);
					$alias = $db->loadResult();
				$segments[] = $alias;
			}
			else
			{
				$segments[] = $query['id'];
			}

			unset($query['id']);
		}

		return $segments;
	}


	public function parse(&$segments)
	{
		$vars = array();
		$vars['view'] = array_shift($segments);
		$model        = BreedFrontendHelper::getModel($vars['view']);

		while (!empty($segments))
		{
			$segment = array_pop($segments);

			if (is_numeric($segment))
			{
				$vars['id'] = $segment;
			}
			else
			{
				$vars['alias'] = $segment;
			}
		}

		return $vars;
	}
}

The way Joomla creates a url is, it first gets alias from the menu for the component for creating a base and after this, the component is responsible for generating rest of the url. This is the router.php file in the component root, at the frontend, which is meant to generate sef urls on the basis of provided aliases.

In the above mentioned router.php file, first we have declared a class called BreedRouter which is extending JComponentRouterBase class, which holds all the methods required to generate a proper human readable url. Next we have declared a standardized function called “build” which is passing in a query array by referrence and it holds all the variables that the joomla is using for this component to build a url. So, first we have created a $segments array which would be returned in the end for informing joomla about the url pieces we want to build.

At first, we are checking that if there is a “task” variable in the query array and if this is the case, we are going to eliminate the “.edit” part of it and rendering the remaining one by imploding the array with “/”. After that we are unsetting the “task” variable and in this way, it will not be added to the url. Next we are looking for the view variable and if it is found, we are going to unset it as well.

Next we are looking for the id variable in the url and it is the most important one. If the system finds any, on the basis of this id, we are going to get the alias for that specific record from the database and once we got the alias, we will pass it to segments array and then will unset the query id thus we are removing id from the url.

After that, we have a parse method and we are passing in the segments array that we have build in the build method and the purpose of this method is, to translate the SEF url that is coming out from the previous method, back to a query. It will only be executed when the joomla sef mode is switched on. In this method, first we are shifting in the ‘views’ element of the array, to make it the first element and then on the basis of this array, we are putting id or the alias back to the url.

Download Code

Add a Comment

Your email address will not be published. Required fields are marked *

Enjoy best web development services at an affordable price. Looking forward to build a good relationship and serve you better...

ABOUT CODINGACE

My name is Nohman Habib and I am a web developer with over 10 years of experience, programming in Joomla, Wordpress, WHMCS, vTiger and Hybrid Apps. My plan to start codingace.com is to share my experience and expertise with others. Here my basic area of focus is to post tutorials primarily on Joomla development, HTML5, CSS3 and PHP.

Nohman Habib

CEO: codingace.com

Request a Quote