Pull to refresh

Joomla 1.5 и ЧПУ

CMS *
Sandbox
Для каждого сайта очень важно ЧПУ (Человекопонятные УРЛ), для того, чтоб его очень «любили» поисковые системы и для того, чтоб можно ключевое слово написать в ссылку.

Для Joomla 1.5 существует очень много компонент для создания ЧПУ. Эти компоненты работают, записывая в БД все ссылки. Это совсем не логично для сайта с большим количеством страниц, потому как много данных хранится в БД. Еще для этих компонент нужно писать свои плагины, для того, чтоб он записал правильно ссылки вашого компонента.

В общем, я никогда не был сторонником этих компонент. Один раз только я использовал, и не сказал бы, что это то, чем я хотел бы пользоваться. Такое строение ЧПУ, я бы назвал «шаманством». И для того, чтобы не писать такое «шаманство», в Joomla 1.5 есть стандартные способы создания ЧПУ для ваших компонентов.

Сначала в административной части, в конфигурации, надо включить ЧПУ. И все ссылки выводить с помощью JRoute::_(‘ссылка’). Будем рассматривать создание ЧПУ, на примере моего компонента.

Маленький рассказ про компонент. Этот компонент я создал для создания базы олимпиадных задач с системой проверки. Его я писал для своей курсовой. Как вы поняли, это должно быть что-то по типу известного acm.timus.ru. В общем, у нас есть база данных олимпиадных алгоритмических задач по информатике. Человек выбирает задачу, отправляет решение, смотрит результат, имеет возможность просматривать статистику каждой задачи. Но ЧПУ для примера, я буду строить только для просмотра задачи. Если будут вопросы, как сделать для большего количества, пишите. Но в принципе, это делается по аналогии.

И так, наш компонент называется com_tasks. Теперь создаем файл router.php в папке нашого компонента. Этот файл состоит из двух функций, это функция (Имя компонента)BuildRoute – функция для построения ссылки, и (Имя компонента)ParseRoute – функция для распознавания ссылки. Будем рассматривать эти функции по очереди.

(Имя компонента)BuildRoute – функция для построения ссылки

Опись функции:
function TasksBuildRoute(&$query)
{}

У нас есть ссылка вида: /index.php?option=com_tasks&view=task&id=/{task_id}&Itemid=2, наша задача сделать из неё /tasks/{task_id}_{task_name}.html

Давайте посмотрим, что нам передается для построения ссылки, массив $query, для задачи с id = 1.
Array ( 
    [option] => com_tasks 
    [view] => task 
    [id] => 1 
    [Itemid] => 2 
)

Эта функция должна вернуть массив частей ссылки, которые нам нужно, между частями Joomla потом ставит «/».

function TasksBuildRoute(&$query)
{
  $segments = array();
  if ($query['view'] == 'task') {
    $segments[] = $query['id'].'_'.$name;
    unset($query['view']); // удаление не нужных уже елементов массива
    unset($query['id']);
  }
  return $segments;
}

С помощью этой функции наша ссылка получила вид: /component/tasks/1_.html.

Как видите, у нас получилось не то, что хотелось. Потому что мы получили не совсем понятный, для нас /component/. Это слово написала Joomla для того, чтоб знать к какому компоненту обращаться. Заметьте, что tasks в ссылке это название компонента. Если сделать пункт меню с указанием нашего компонента, задать alias этому пункту и в ссылках при выводе писать Itemid={id нашого компонента}, то мы будем иметь то, что нам надо.

Я сделал пункт меню с именем Tasks и alias tasks с указанием на компонент и получил, такую ссылку: tasks/1_.html. Тут tasks это alias пункта меню.

Вернемся к просмотру, что мы написали в функции построения. Как вы видите, мы удаляем некоторые елементы массива, потому что те елементы, которые мы не удалим, Joomla подставит как параметр. Например, если не писать unset($query['view']);, то мы бы получили ссылку вида /tasks/1_.html?view=task.

Еще хочу обратить ваше внимание, что мы пока что не вытянули имя задачи. Мы могли сделать, чтоб для данной $query['id'] запросом в базу получить имя. Но при этом, если у нас на одной странице 100 ссылок на задачи, то у нас будет 100 запросов в базу. И это не очень логичный шаг. В этом случаем нам надо сделать отдельную функцию для сбора имен всех задач. Создадим helper route для нашего компонента. Для этого в папке нашего компонента создадим папку helpers и в нем файл route.php.

jimport('joomla.application.component.helper');

class TasksHelperRoute
{
  public static $tasks = null;
  function getTasks()
  {
    if (self::$tasks) return self::$tasks;
    
    
    $db = &JFactory::getDBO();
    $query = "SELECT `id`, `name` FROM `#__tasks`";
    $db->setQuery($query);
    $res = $db->loadObjectList();
    foreach ($res as $r) {
      self::$tasks[$r->id] = $r->name;
    }
    return self::$tasks;
  }

  
}

Теперь подключим этот файл, вызовем функцию, и подставим имя задачи.

include_once(JPATH_ROOT.DS.'components'.DS.'com_tasks'.DS.'helpers'.DS.'route.php');
function TasksBuildRoute(&$query){
  $segments = array();
  $tasks = TasksHelperRoute::getTasks();
  if ($query['view'] == 'task') {
    $segments[] = $query['id'].'_'.$tasks[$query['id']];
    unset($query['view']);
    unset($query['id']);
  }
  return $segments;
}

Теперь мы получили ссылку вида /tasks/1_a_plus_b.html. С этой задачей мы справились.

За счет того, что у нас переменная в классе helpere статическая, то запрос в базу будет только один раз. В том же helpere можно обрабатывать название: забирать пробелы, делать все символы в нижнем регистре и т.д.

Для того, чтоб ЧПУ работало, нужно не только строить, а еще разбирать ссылки. Для этого надо «познакомить» данную ссылку с системой.

(Имя компонента)ParseRoute – функция для распознавания ссылки

Описывается данная функция так:

function TasksParseRoute($segments)
{}

Массив $segments точно такой же, как мы вернули в функции построения. Вернуть надо массив $vars, такой же как мы получали в функции построения.

В данном случае нам передастся такой $segments:
Array ( 
   [0] => 1_a_plus_b 
)

В данном примере view у нас должно быть всегда task, у нас нету ссылок другого вида. И теперь нам надо со строки {id}_{name } достать только {id}. Это делается просто с помощью функций для работы со строками.

function TasksParseRoute($segments)
{
  $vars['view'] = 'task';
  $vars['id']  = substr($segments[0], 0, strpos('_', $segments[0])+1);
  return $vars;
}

Ну вот, в общем мы и познакомили систему с нашими ссылками.

Мы рассмотрели один из самых легких примеров. Более сложное вы сможете сделать сами, опираясь на этот пример. Жду вопросов, предложений по улучшению, критики.
Tags:
Hubs:
Total votes 13: ↑5 and ↓8 -3
Views 7.5K
Comments Comments 11