Привет Dillimon,
Я нашел один вариант, но единственно чем он плох, надо править немного файлы ядра. Вот, что единственно мне не нравиться в моем варианте, ну а остальная логика переноситься на тебя самого.
Я только начал разбираться с этой проблемой, мне было бы очень интересно посмотреть как с этим разбираются известные компоненты SEF. Но под рукой ни одного нет. Но моя главная цель была не использовать как раз эти компоненты. И так вот мое решение:
1) Ищем файл /includes/router.php
/*
* Build the application route
*/
//вот откуда берется в урле component!
//если не нашли Элемент меню и он не является текущим компонентов
$built = false;
if (isset($query['Itemid']) && !empty($query['Itemid']))
{
$item = $menu->getItem($query['Itemid']);
if (is_object($item) && $query['option'] == $item->component) {
$tmp = !empty($tmp)? $item->route.'/'.$tmp : $item->route;
$built = true;
}
}
//и собственной здесь строка собирается уже вместе с компонентом
if($built) {
$tmp = 'component/'.substr($query['option'], 4).'/'.$tmp;
}
Вот проблемная часть в кода. Как видно вся проблема именно здесь. Понятно почему они так сделали, им же надо знать, что это за компонент, если он не является ссылкой меню. Хотя можно было предусмотреть другую логику.
И так я немного модифицировал последнее условие
if(isset($query['option']) && !$built) {
$tmp = 'component/'.substr($query['option'], 4).'/'.$tmp;
}
То если не передан option в URI, мы не добавляем component.
В но для этого нам надо самим удалил option из url, Router.php вашего компонент удаляем option:
function [ComponentName]BuildRoute(&$query)
{
unset($query['option']);
//build your URI
}
Далее нам надо самостоятельно обработать URI, а иначе получим 404 ошибку "Компонент не найден". Для этого создаем плагин.
Плагин будет делать следующее, парсить урл по вашим правилам и затем возвращать переменную option в URI в зависимости от того, как вы распарсили URI.
Пример:
class plgSystem[Name]Router extends JPlugin {
var $_config = null;
function plgSystemSushiRouter(& $subject, $config) {
global $mainframe;
if ($mainframe->isAdmin()) {
return;
}
parent::__construct($subject, $config);
}
function onAfterInitialise() {
$app = &JFactory::getApplication();
$router = &$app->getRouter();
$router->attachBuildRule('route[Name]Rule');
$this->parseSushiRule($router);
}
function Parse[Name]Rule($router){
$uri = &JURI::getInstance();
if (!$uri->getVar('option')){
//Парсим урл по своей логике здесь
//В конце не забываем добавить option в URI
$uri->setVar('option', $component_name);
}
}
}
Подведу итоги.
1) У нас только одна модификация ядра /includes/router.php, что очень удобно
2) У нас один плагин, в котором сосредоточена логика, для всех наших компонентов. При этом если router.php получил название компонента (option), все идет стандартным путем.
3) Мы определяем как будут вести себя компоненты в их файлах Router.php, то есть убрали option все будет обрабатывать plugin. Не убрали, все работает как есть
4) Пока не нашел ничего лучше, может оно и есть
5) Кажется немного запутано на первый взгляд, но если проделать и понять, все довольно просто.
6) Спрашивайте отвечу на любые вопросы