Хорошим примером ссылки является статья “Welcome to Joomla”. Первая ссылка была сгенерирована без mod_rewrite, и вторая с mod_rewrite:
http://www.example.com/index.php/thenews/1latestnews/1welcometojoomla
http://www.example.com/thenews/1latestnews/1welcometojoomla
Алиясы
Первым шагом мы всегда создаем алияс (псевдоним). Алияс добавляется в адрес URL вместо заголовка. Алияс должен быть URI безопасным, а это означает, что некоторые UTF8 символы заменяются на их эквиваленты 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, тогда заголовок будет использован в качестве алияса.
Слаг
В продолжение примера, “слаг” - “1welcometojoomla” имеет две части.
Первая часть — это это 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 состоит из двух этапов:
-
Создать обработчик маршрута
В приложениях маршрутом полностью занимается JRouter и разработчик компонента не нужно делать ничего, чтобы он работал.
-
Создать обработчик маршрута компонента
Для создания маршрута компонента, 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. Мы по-прежнему отключено считает ключевым, поскольку в противном случае JRouter бы добавить его в URL в качестве части строки запроса. Еще одна новая вещь здесь, это дополнительный параметр 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 ); С помощью этой информации мы сможем правильно устанавливать иерархию во всех возможных трех случаях.
В итоге мы получаем человекочитаемую ссылку.
Оригинал на английском





