Генерация SEF-ссылок (класс JRoute)
В Joomla существует возможность создавать SEF-ссылки (Search-Engine Friendly) вида www.mysite.ru/one/two/three, удобные и для посетителей, и для поисковых систем. Для этого используется единственный метод класса JRoute, переводящий внутреннюю ссылку, генерируемую Joomla, в SEF-ссылку:
string _(string $url, bool $xhtml=true, int $ssl=null)
где
$url | - абсолютный или относительный URI; |
$xhtml | - заменять ли амперсанды на "&"; |
$ssl | - при $ssl=1 полученный URI будет начинаться с протокола https://, в противном случае - http://. |
Данный метод разбирает $url на пары "ключ-значение" и сохраняет результаты разбора в массиве. Из этого массива удаляется элемент option. Его значение добавляется к новому URL в качестве первого сегмента. Затем производится поиск файла /components/com_<option>/router.php. В этом файле должны находиться две функции: функция для генерации SEF-ссылок (<имя компонента>BuildRoute()) и функция для декодирования элементов SEF-ссылок (<имя компонента>ParseRoute()). Метод JRoute::_() вызовет функцию <имя компонента>BuildRoute() и передаст ей массив, полученный при разборе $url. Функция вернет массив $segments. Метод JRoute::_() добавит к новому URL все элементы этого массива, разделив их слэшами. Если в запросе останутся какие-либо необработанные переменные, они будут добавлены в конец URL.
Допустим, метод JRoute::_() получит на вход ссылку вида
index.php?option=com_mycomponent&var1=value1&var2=value2&…&varN=valueN
Тогда он передаст в функцию <имя компонента>BuildRoute() ассоциативный массив
Array([option]=>com_mycomponent [var1]=>value1 [var2]=>value2... [varN]=>valueN)
причем пары "ключ-значение" будут расположены в том порядке, в котором они были в исходной ссылке. Задача функции <имя компонента>BuildRoute() - выбрать необходимые пары и сохранить в результирующем массиве только значения, но так, чтобы впоследствии можно было восстановить соответствующие им ключи. Это достигается использованием какого-либо фиксированного порядка. Функция вернет массив вида
Array([0]=>value1 [1]=>value2 … [N-1]=>valueN)
из которого затем будет создана SEF-ссылка
component/mycomponent/value1/value2/…/valueN
Впоследствии при щелчке на какой-либо SEF-ссылке произойдет обратный процесс. Будет вызван метод <имя компонента>ParseRoute(), который получит на вход массив
Array([0]=>value1 [1]=>value2 ... [N-1]=>valueN)
и вернет ассоциативный массив:
Array([var1]=>value1 [var2]=>value2 … [varN]=>valueN)
который Joomla установит в качестве переменных HTTP-запроса. Таким образом, посетители сайта и поисковые системы увидят SEF-ссылки, а компонент будет работать с обычным набором пар "ключ-значение".
Обратите внимание, что SEF-ссылка не содержит никакой информации о том, как называются ключи массива. Чтобы их можно было восстановить, функция генерации ссылок и функция их декодирования должны неявно задавать шаблон SEF-ссылок для конкретного компонента. В данном примере подразумевается шаблон, который можно сформулировать вербально так: "переменные записываются в следующем порядке: var1, var2, … varN".
Шаблон может быть более сложным. Например, его структура может меняться в зависимости от задачи, т.е. от значения входящей в него переменной task.
В простейшем случае содержимое файла router.php выглядит так:
<?php
defined('_JEXEC') or die ('Restricted access');
function <имя компонента>BuildRoute(&$query)
{
$segments = array();
if (isset($query['var1']))
{
$segments[] = $query['var1'];
unset($query['var1' ]) ;
}
...
if(isset($query['varN' ]))
{
$segments[] = $query['varN'];
unset($query['varN']);
}
return $segments;
}
function <имя компонента>ParseRoute($segments)
{
$vars = array();
$vars['var1'] = @$segments[0];
...
$vars['varN'] = @$segments[1];
return $vars;
}
?>
Обратите внимание, что массив $query должен быть передан в функцию <имя компонента>BuildRoute() по ссылке. По мере заполнения массива $segments обработанные элементы удаляются из массива $query с помощью unset(). Любые элементы, которые останутся в массиве $query после работы функции <имя компонента>BuildRoute(), останутся и в URL. Если мы передадим $query по значению, вызовы функции unset() будут действовать только на локальную копию этого массива и все элементы старого URL будут появляться после SEF-сегментов.