В Joomla 1.5 механизм генерации ссылок был полностью переработан. Теперь вы можете как угодно парсить свои ссылки, делая их человеко-читаемыми. Другое важное новвоведение — теперь необязательно при этом включать на апаче модуль mod_rewrite.

Хорошим примером ссылки является статья “Welcome to Joomla”. Первая ссылка была сгенерирована без mod_rewrite, и вторая с mod_rewrite:

http://www.example.com/index.php/the­news/1­latest­news/1­welcome­to­joomla
http://www.example.com/the­news/1­latest­news/1­welcome­to­joomla

Алиасы

Первым шагом мы всегда создаем алиас (псевдоним). Алиас добавляется в адрес URL вместо заголовка. Алиас должен быть URI безопасным,  это означает, что некоторые UTF-8 символы заменяются на их эквиваленты ASCII7, например пробелы на дефисы и т.д.

Алиас обычно определяется самим пользователем при создании ссылки в меню, но вы должны обеспечить, чтобы вышеуказанные требования к безопасному URL были выполнены. Самый простой способ сделать так — это использовать метод класса Jtable::check(). Вот как это выглядит на примере:

function check()  {
 jimport( 'joomla.filter.output' );
 $alias = JOutputFilter::stringURLSafe( $this->title );
 if(empty( $this->alias ) || $this->alias === $alias ) {
 $this->alias = $alias;        
 }
 /* тут выполняем другие проверки */
 return true;
 }

Если алиас пустое поле или алиас не является безопасным URL, тогда заголовок будет использован в качестве алиаса.

Слаг

В продолжение примера, “слаг” - “1­welcome­to­joomla” имеет две части.
Первая часть — это это id статьи, и вторая — это алиас. Они разделены дефисом.
Эти два элемента комбинируются в модели при запросе к базе данных:

$query = 'SELECT a.* CASE WHEN CHAR_LENGTH (a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug,'.
[...];

После этого шага слаг используется вместо id.

JRoute

Метод JRoute::_() переводит наши ссылки Joomla, в ссылки произвольного вида. JRoute имеет три параметра (на js и php одни и теже):

JRoute::_( $url, $xhtml = true, $ssl=0 );

$url — это строка содержащая абсолютную или относительную ссылку внутри joomla.
$xhtml - булево значение, которое указывает, должен ли результат быть в XHTML. Этот параметр необязательный
$ssl - это целое число, которое указывает, должен ли URI шифроваться. 1 - означает, что URI глобально защищен, 0 — стандартное состояние, когда он был принят, и -1 - чтобы URI был небезопасным.

Наиболее важный параметр это $url. Работает метод так:

 JRoute::_( 'index.php?view=article&id='.$row->slug );

$row->slug это значение, генерируемое в шаге 2, которое комбинирует id и заголовок-алияс.

Другим преимуществом JRoute является то, что роутер обрабатывает $option (имя компонента) и $Itemid (идентификатор меню). Теперь в ссылке не нужны $option и $Itemid, в отличие от предыдущих версий Joomla.

Важно чтобы вы поняли параметры на этом этапе. К router.php мы перейдем далее.

Процесс построения JRouter состоит из двух этапов:

1. Создать обработчик маршрута
В приложениях маршрутом полностью занимается JRouter и разработчик компонента не нужно делать ничего, чтобы он работал.

2. Создать обработчик маршрута компонента
Для создания маршрута компонента, JRouter ищет файл router.php в каталоге компонента. Файл router.php отвечает за строительство ссылок для компонента.

router.php
Мы будем иметь две функции в router.php. Одна отвечает за строительство URL, а другая за разбор ссылки. В последующих примерах, мы будем считать, что есть три Вида. Во-первых, это один Вид категорий (view = categories), второй - одна категория (option = category), а третий — это конкретная статья (view=article).

Простой пример:
Этот простой пример покажет основы работы маршрутизатора в вашем компоненте.

function [Componentname]BuildRoute( &$query )  {
 $segments = array();        
 if(isset($query['view'])) {                 
 $segments[] = $query['view'];                 
 unset( $query['view'] );        
 }        
 if(isset($query['id']))   {                 
 $segments[] = $query['id'];                 
 unset( $query['id'] );        
 };        
 return $segments;  }

JRouter передает массив $query к функции [Componentname] BuildRoute. Эта функция будет добавлять соответствующие части в массив $segments в правильном порядке. Значения массива запроса $query нужно отключать, иначе JRouter добавит его в URL.

Следующая функция в router.php парсит URL:

 function [Componentname]ParseRoute( $segments )  {
 $vars = array();        
 switch($segments[0])        
 {                
 case 'categories':                        
 $vars['view'] = 'categories';                        
 break;                
 case 'category':                        
 $vars['view'] = 'category';                        
 $id = explode( ':', $segments[1] );                        
 $vars['id'] = (int) $id[0];                        
 break;                
 case 'article':                        
 $vars['view'] = 'article';                        
 $id = explode( ':', $segments[1] );                        
 $vars['id'] = (int) $id[0];                        
 break;        
 }        
 return $vars;  }

Что происходит здесь? В функции [Componentname]BuildRoute мы организовали элементы в массиве $query в конкретной последовательности. Это означает, что в данном примере Вид идет первым, вторым catid и id третьим.
Считывая $segments[0], мы получаем доступ к Виду. Мы выбрали правильные вид, в зависимости от значения id, и вернули массив $vars в JRouter.

Это очень простой пример. Генерируемый URL в этом примере содержит имя Вида, и не отражает содержания иерархии, так как отображает ссылки в следующем виде:
http://www.example.com/[menualias]/[view]/[slug] .

Более сложный пример:

В этом примере мы создадим иерархию следующего вида:

Когда мы смотрим статью: http://www.example.com/[menualias]/[category]/[article]
Когда смотрим категорию: http://www.example.com/[menualias]/[category]
Когда смотрим категории: http://www.example.com/[menualias]

Давайте представим, что мы сделали шаг 1 и 2 также для категории.
Ссылка на статью выглядит так:

JRoute::_( 'index.php?view=article&catid='.$row->catslug .'&id='.$row->slug );

И ссылка на категорию выглядит так:

JRoute::_( 'index.php?view=category&id='.$row->catslug );

Вот router.php

 function  [Componentname]BuildRoute(&$query){        
 $segments = array();        
 if(isset( $query['catid'] ))        
 {                 
 $segments[] = $query['catid'];                 
 unset( $query['catid'] );        
 };        
 if( isset($query['id']) )        
 {                 
 $segments[] = $query['id'];                 
 unset( $query['id'] );        
 };        
 unset( $query['view'] );       
 return $segments; 
 }

Обратите внимание, что мы не добавили имя Вида в массив $segments. Еще одна новая вещь здесь, это дополнительный параметр catid том, что мы нажимаем на $ сегментов массива. Мы по прежнему отключаем переменную $query['view'], чтобы убрать ее из url.

Еще одна новая вещь здесь, это дополнительный параметр catid, который мы передаем в массив $segments.

function [Componentname]ParseRoute($segments)  {        
$vars = array();        
$menu =& JMenu::getInstance();        
$item =& $menu->getActive();        
// колличество сегментов        
$count = count( $segments );        
//обработчик вида и идентификатора        
switch( $item->query['view'] )        
{                
case 'categories':                        
if($count == 1) {                                
$vars['view'] = 'category';                        
}                        
if($count == 2) {                                
$vars['view'] = 'article';                        
}                        
$id = explode( ':', $segments[$count] );                        
$vars['id'] = (int) $id[0];                        
break;                
case 'category':                        
$id   = explode( ':', $segments[$count] );                        
$vars['id']   = (int) $id[0];                        
$vars['view'] = 'article';                        
break;        
}        
return $vars;  }

В этой функции ParseRoute есть много различных частей кода по сравнению с предыдущим. Причина этого проста. Мы не имеем имя вида в масcиве $segments, и мы должны найти другой способ передать ее.

Мы должны узнать, в каком уровне иерархии мы находимся, получая корневой элемент. Мы делаем это, посмотрев имя Вида в названии активного меню:

$item->query['view']

Кроме того, нам необходимо знать количество элементов в массиве $segments: $count = count( $segments ); С помощью этой информации мы сможем правильно устанавливать иерархию во всех возможных трех случаях.

В итоге мы получаем человекочитаемую ссылку.


Если у Вас возникли вопросы, то для скорейшего получения ответа рекомендуем воспользоваться нашим форумом

    Комментарии  

    +1 #1 akute 18.05.2011 11:21
    Спасибо за статью!
    +1 #2 Вадим 26.08.2011 11:58
    Спасибо, очень полезно!
    #3 Lisa 19.08.2012 14:40
    Здрасти
    Подскажите пожалуста как убрать Itemid именно в меню
    Например если навести на ссылку в меню то адрес такой
    http://site.com/index.php?option=com_muscol&view=search&Itemid=54
    Как сделать так что бы ссылка была вот ак
    http://site.com/index.php?option=com_muscol&view=search&Itemid=54
    То есть что бы не было этого &Itemid=54 в конце
    Как только я не пробовала у меня не получаеться
    #4 Денис 01.11.2012 17:25
    Спасибо за материал, хорош :)
    #5 ilianna 29.05.2014 08:53
    Спасибо, в новых версиях джумлы нужно использовать JFilterOutput старое не робит...

    You have no rights to post comments