Upd: English version of the article: The structure of internal links within Joomla site.


За последнее время я написал и внедрил несколько функций, позволяющих фильтровать вывод страниц сайта, работающего на CMS Joomla версии 2.5 и новее. Перед тем, как поделиться ими с общественностью, затрону тему, вынесенную в заголовок этой статьи, поскольку понимание принципа формирования внутренних ссылок на страницы джумловских приложений поможет лучше разобраться в их алгоритмах.

Немного теории

Приложения для CMS Joomla разрабатываются в виде компонентов. Компоненты отвечают за вывод страниц сайта. Ссылка на каждую страницу генерируется в соответствующем компоненте в стандартном формате URI:

http://[имя сайта]/index.php?[строка запроса]

Строка запроса (query string) представляет из себя последовательность пар ключ=значение, разделенных амперсандом. Значения ключей и определяют вывод каждой страницы. URI страниц генерируются в соответствии со структурой компонента. Нас сейчас интересует не механизм формирования ссылок, а результат для каждой страницы или групп страниц конкретного приложения. Зная, как идентифицировать ключи и их значения, можно гибко манипулировать выводом контента.

Замечу лишь, что в вышеприведенном формате вы увидите ссылку в адресной строке браузера только при условии, что для сайта отключено ЧПУ (SEF). При включенном ЧПУ ссылки преобразуются роутером в более вразумительный для человеческого восприятия вид. Нас же интересуют именно внутренние ссылки, поэтому для получения ключей и их значений из адресной строки можно отключить ЧПУ на тестовой площадке.

Фреймворк Джумлы определяет некоторое количество стандартных ключей. Рассмотрим самые используемые из них.

  • option - имя компонента с префиксом 'com_';
  • view - вид (или представление) конкретной страницы компонента;
  • layout - дополнительный вариант вывода конкретного вида;
  • Itemid - идентификатор пункта меню, к которому привязана страница, если таковая привязка имеет место.

В случае мультиязычного сайта добавляется еще и параметр

  • lang - язык страницы.

В каждом компоненте разработчиками могут быть добавлены ключи, используемые для формирования ссылок на страницы данного конкретного приложения. Например, базовый компонент Джумлы com_content, формирующий структуру категорий и материалов, оперирует следующими дополнительными ключами:

  • id - идентификатор материала или категории в зависимости от текущего представления. Принимает значение ID материала в случае вывода конкретной статьи (view=article). ID категории этот ключ содержит при выводе списка категорий (view=categories) или материалов в виде списка или блога категории (view=category);
  • catid - идентификатор категории, в которую входит выводимый материал (view=article).

Значения ключей для этого компонента:

  • option - com_content.
  • view -
    • archive - архивные материалы;
    • article - материал;
    • categories - список категорий;
    • category - материалы категории в виде списка или блога;
    • featured - избранные материалы в виде блога;
    • form - форма создания или редактирования материала.
  • layout -
    • blog - вывод материалов категории в виде блога в представлении категории (view=category);
    • edit - вариант для представления формы создания или редактирования материала (view=form). Есть еще pagebreak и modal. Маловероятно, что какой-нибудь из них пригодится на практике. Разве что первый, да и то лишь для удобства пользователей с правами редактирования.
  • lang - присутствует в URI всех страниц многоязычного Joomla-сайта и содержит двухбуквенный идентификатор активного языка, соответствующий параметру Код языка для URL | URL Language Code в настройках языков в админке - например: ru, en. (О языках и их настройках упоминается, например, в статье о кастомной странице 404.)
  • Itemid, id и саtid - принимают значения идентификаторов в соответствии с видом выводимой страницы контента; при этом, если первый из них всегда содержит ID пункта меню в виде числа, то остальные два в определенном контексте могут иметь форму [ID]:[алиас]. Об этом еще будет упоминаться ниже.

Примеры вывода страниц компонентом com_content

Рассмотрим несколько примеров содержимого ключей строки состояния в URI определенных страниц приложения com_content.

Пример 1. На странице, привязанной к пункту меню 35, отображается блог избранных материалов англоязычной части сайта:

option=com_content&view=featured&Itemid=35&lang=en

Пример 2. Выводится материалы категории с id=27 в виде блога на русской части сайта. Пункт меню, к которому привязана страница - 62:

option=com_content&view=category&layout=blog&id=27&Itemid=62&lang=ru

Если бы отсутствовала пара layout=blog, то материалы выводились бы по умолчанию в виде списка.

Пример 3. Страница статьи, которую вы сейчас читаете:

option=com_content&view=article&id=813:struktura-vnutrennikh-ssylok-sajta-na-joomla&catid=27:stroim-sajty&Itemid=62&lang=ru

Последний пример как раз иллюстрирует случай, когда идентификаторы материала и категории содержат также и алиасы, отделенные двоеточием от ID в числовом представлении. В разделе о применении ключей строки запроса будет разобрано, как их обрабатывать.

Таким образом, отключив ЧПУ на тестовом сайте, можно увидеть параметры любой страницы в строке адреса вашего браузера.

Использование на практике

Если у вас хватило терпения продраться через предыдущие разделы, поздравляю: пришло время рассмотреть область применения полученных сведений.

Знание параметров запроса позволяет сформировать условие для отработки какого-либо кода только на одной или нескольких конкретных страницах сайта, а также для группы страниц, объединенных общим признаком - компонентом, категорией или языком.

Для создания такого условия воспользуемся конструкцией:

$value = JFactory::getApplication()->input->getCmd([ключ]);

в которой вместо [ключ] будем подставлять строки с именами интересующих нас параметров. Возвращает getCmd значение ключа в виде строки. Например, условие для страниц, относящихся к материалам и категориям компонента com_content, выйдет таким:

$option = JFactory::getApplication()->input->getCmd('option');
if ($option == 'com_content') {
  ...
}

Для целочисленных идентификаторов можно использовать метод getInt:

$Itemid = JFactory::getApplication()->input->getInt('Itemid');
if ($Itemid == 1) {
 ...
}

Единственная заковыка возникает в том самом случае, когда идентификаторы могут сопровождаться двоеточием и алиасом (псевдонимом). Хоть эти хвосты и добавляются к ID только когда ЧПУ отключено, такие случаи нужно обработать: а вдруг ЧПУ таки понадобится отключить? Нужен универсальный вариант. Поэтому условие по материалам и категориям будет чуть сложнее:

$temp = explode(':', $jinput->getCmd('id'));
$article_id = $temp[0] + 0;

(Этот подход уже применялся в статьях о скрытии хлебных крошек на определенных страницах и об избирательном выводе кнопок соцсетей.)

Теперь можно создать блок кода инициализации всех переменных, соответствующих интересующим нас ключам запроса компонента:

$jinput = JFactory::getApplication()->input;
 
$option = $jinput->getCmd('option');
$lang = $jinput->getCmd('lang');
$view = $jinput->getCmd('view');
$layout = $jinput->getCmd('layout');
$Itemid = $jinput->getInt('Itemid');
 
$temp   = explode(':', $jinput->getCmd('id'));
$art_cat_id = $temp[0] + 0;
 
$temp   = explode(':', $jinput->getCmd('catid'));
$cat_id = $temp[0] + 0;

Получив значения параметров вывода страниц, можно комбинировать их при создании условий для фильтрации контента. Функции, упомянутые в начале статьи, содержат именно такие условия.

В заключение - несколько замечаний. Те, кто использует дополнительные фреймворки - K2, T3 и т. д. - могут вытащить ключи, предусмотренные их разработчиками, по тому же принципу. Как, впрочем, и из любых других компонентов. Те же, кто хочет сам создавать оригинальные компоненты на основе существующих или с нуля, могут почитать в сети о паттерне MVC (Модель-Вид-Контролер | Model-View-Controller), разобраться с методом JRoute и прочими девелоперскими премудростями. И последнее, что хотел бы отметить: кастомизация под себя - это здорово, но вносить свой код в ядро и расширения следует очень аккуратно, стараясь свести к минимуму процесс восстановления изменений после установки обновлений.

Комментарии  

михаил чугунов
0 # михаил чугунов 18.10.2015 08:09
У меня есть сайт, где при внутренних переходах в каталоге (плагин) я попадаю на страницу с ссылкой /apparaty-dlya-smazki-i-chistki-nakonechnikov.html?Itemid=105

Это опасно для SEO? Для правильного подсчета конверсий?
Ответить | Ответить с цитатой | Цитировать
Ogri
0 # Ogri 18.10.2015 14:01
Я не спец по СЕО, но такой формат ссылки мне кажется странным. Видимо, плагин добавляет Itemid в строку запроса уже после преобразования ссылки ЧПУ. Не знаю, с какой целью, ведь значение идентификатора пункта меню можно вытащить так, как описано в статье.

Вообще-то строки запроса в человекоудобном виде должны появляться только на вспомогательных страницах - результатах поиска, страницах авторизации и т.п. Я, например, внес в robots.txt строку Disallow: /*?, запретив все такие страницы для индексирования.

В вашем случае я попробовал бы исследовать, зачем добавляется значение Itemid. Если бросите линк на сайт (здесь в камментах или в личку - ogri.me/ru/obratnaya-svyaz) - возможно, смогу ответить конкретнее.
Ответить | Ответить с цитатой | Цитировать

Добавить комментарий