J3.x: Поддержка SEF-URL в вашем компоненте

  1. Концепт
  2. Применение маршрута :: _
  3. Написание роутера
  4. Подготовка ваших данных для маршрутизации
  5. Псевдоним
  6. Слизень
  7. URL-адреса маршрутизации
  8. Создание внешних веб-адресов SEF в администраторе
  9. Маршрутизатор компонентов
  10. Простой пример на основе вида
  11. Более сложный пример
  12. Смотрите также

Обратите внимание на множество примеров использования классов имен в Интернете. Это было введено в Joomla 3.8. Существуют версии всех этих классов без пространств имен, которые будут работать в Joomla 3.4+.


Поисковая система (SEF) , удобочитаемая или чистые URL URL-адреса, которые имеют смысл как для людей, так и для поисковых систем, потому что они объясняют путь к конкретной странице, на которую они указывают. Начиная с версии 1.5, Joomla! способен создавать и анализировать URL-адреса в любом формате, включая URL-адреса SEF. Это не зависит от перезаписи URL, выполняемой веб-сервером, поэтому работает, даже если Joomla! запускает сервер, отличный от Apache, с модулем mod_rewrite. URL-адреса SEF следуют определенному фиксированному шаблону, но пользователь может определить краткий описательный текст (псевдоним) для каждого сегмента URL.

Внутренне локальная часть URL SEF (часть после имени домена) называется маршрутом . Поэтому создание и обработка URL-адресов SEF называется маршрутизацией , а соответствующий код называется маршрутизатором .

В Joomla !, друг составная часть отвечает за обработку своих собственных URL SEF. Следовательно, как разработчик компонента, вам нужно будет создать свой собственный маршрутизатор, чтобы позволить вашему компоненту использовать URL-адреса SEF.

Концепт

Предполагая, что вы следуете стандартным методам разработки, ваш компонент, вероятно, использует «системные URL-адреса», которые очень похожи на http://www.example.com/index.php?option=com_yourcomponent&view=article&id=1&catid=20&Itemid=50 и ваши цель состоит в том, чтобы преобразовать это в http://www.example.com/example-menu-item/example-category/example-article. Как разработчик, у вас есть две задачи: сообщить системе о том, что определенные фрагменты текста являются URL-адресами, которые необходимо преобразовать, и объяснить системе, как преобразовывать URL-адреса.

Применение маршрута :: _

Это сложно и неэффективно для Joomla! чтобы выяснить, какие части вывода вашего компонента являются URL-адресами. Для поддержки SEF-URL вам нужно изменить код, генерирующий URL-адрес, чтобы он применял \ Joomla \ CMS \ Router \ Route :: _ перед выводом URL-адреса:

echo \ Joomla \ CMS \ Router \ Route :: _ ('index.php? view = article & id = 1 & catid = 20');

Обратите внимание, что можно не указывать параметр параметров и Itemid. Параметр по умолчанию соответствует имени выполняемого в данный момент компонента, а Itemid - идентификатору текущего элемента меню.

Как правило, это следует применять только к тем URL-адресам, которые могут видеть пользователи и / или поисковые системы. Например, нет необходимости преобразовывать URL-адреса, используемые в перенаправлениях, которые немедленно приводят к другим перенаправлениям.

Если пользователь отключит URL-адреса SEF в настройках сайта, \ Joomla \ CMS \ Router \ Route :: _ создаст рабочие URL-адреса без SEF без каких-либо изменений в коде.

Написание роутера

Вам также необходимо написать маршрутизатор, который представляет собой отдельный файл, содержащий класс с тремя функциями, которые преобразуют системные URL-адреса в URL-адреса SEF и из них. Этот файл необходимо разместить по адресу /components/com_yourcomponent/router.php.

Класс должен называться [componentname] Router (например, для com_content ContentRouter) и должен реализовывать Joomla \ CMS \ Component \ Router \ RouterInterface

Первая функция build (& $ query) должна преобразовать массив параметров URL в массив сегментов, которые будут формировать URL SEF. Схематично преобразование работает следующим образом:

http://www.example.com/index.php?option=com_yourcomponent&view=article&id=1&catid=20&Itemid=50 ↓ \ Joomla \ CMS \ Router \ Route :: _, вызванный вашим компонентом или любым другим расширением $ query = array ('view' => 'article', 'id' => 1, 'catid' => 20) ↓ Ваш роутер [имя_компонента] Router :: build $ сегментов = массив (20, 1); ↓ Внутреннее здание маршрута Joomla (для отображения) http://www.example.com/example-menu-item/20/1

Вторая функция, parse ($ сегменты), должна преобразовать массив сегментов обратно в массив параметров URL. Схематично:

http://www.example.com/example-menu-item/20/1 ↓ Внутренний маршрут Joomla для разбора $ сегментов = массива (20, 1); ↓ Ваш маршрутизатор [имя компонента] Router :: parse $ query = array ('view' => 'article', 'id' => 1, 'catid' => 20)

Эти две функции должны взаимодействовать таким образом, чтобы исходный URL-адрес можно было восстановить. Вы можете думать о сборке как о форме кодирование и разбирать как соответствующее декодирование. Если исходный URL-адрес не будет правильно воспроизведен, ваш компонент перестанет работать.

Последняя функция preprocess ($ query) - это метод подготовки URL-адресов. Этот метод выполняется для каждого URL независимо от того, включен режим SEF или нет. Мы вернемся к этому методу позже в этом уроке.

Подготовка ваших данных для маршрутизации

Очевидно, что любой формат URL должен содержать некоторую информацию, которая идентифицирует данные, которые вы хотите показать. Если ваши системные URL-адреса выглядят как http://www.example.com/index.php?option=com_yourcomponent&view=article&id=1&catid=20&Itemid=50, эта информация в настоящее время является параметром id URL (id = 1). Возможно, вы хотите, чтобы ваши SEF-URL содержали текстовое описание данных, на которые они указывают. В Joomla !, это обычно делается путем предоставления пользователям возможности ввести псевдоним, который будет использоваться в URL.

Псевдоним

Даже если ваши пользователи могут ввести псевдоним, они могут этого не делать, оставляя создание разумного псевдонима для вашего компонента. Если ваши данные имеют поле заголовка, вы можете использовать его в качестве кандидата на псевдоним (например, ядро содержание компонент делает). Учитывая, что псевдоним будет использоваться в URL, он должен быть безопасным для URL. Joomla! предоставляет метод, обеспечивающий безопасность произвольных строк URI, который включает замену акцентированных символов UTF8 их эквивалентами ASCII7, пробелов на дефисы и т. д. Независимо от того, введен ли пользователем псевдоним или кандидат, автоматически, вы должны убедиться, что вышеуказанные требования для URL безопасные псевдонимы выполнены. Хорошее место для реализации этого, если вы используете JTable, это метод JTable :: check (), который вызывается во время процесса сохранения. Посмотрите на этот пример кода:

function check () {jimport ('joomla.filter.output'); if (empty ($ this -> alias)) {$ this -> alias = $ this -> title; } $ this -> alias = JFilterOutput :: stringURLSafe ($ this -> alias); / * Все остальные ваши чеки * / верните true; }

Если поле псевдонима пусто, заголовок используется в качестве псевдонима. Затем псевдоним делается безопасным для URL с помощью метода JFilterOutput :: stringURLSafe ().

Слизень

Плагин используется для минимизации количества кода, необходимого для поддержки SEF-URL. Он состоит из числового идентификатора (id) используемых системных URL-адресов, двоеточия (:) и псевдонима, созданного вами, как описано выше.

Рассмотрим SEF URL для Статья с идентификатором 1 и названием «Добро пожаловать в Joomla!». Автоматически сгенерированный псевдоним для этой статьи - welcome-to-joomla, а слаг становится 1: welcome-to-joomla. в содержание Компонент, два элемента объединяются во время запроса к базе данных в модели (a представляет #__content):

$ query = 'SELECT a. *,'. 'CASE WHEN CHAR_LENGTH (a.alias) THEN CONCAT_WS (":", a.id, a.alias) ELSE a.id END as slug,' /*...*/;

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

URL-адреса маршрутизации

Метод \ Joomla \ CMS \ Router \ Route :: _ переводит внутреннюю Joomla! URL на пользовательский URL. \ Joomla \ CMS \ Router \ Route :: _ имеет три параметра, а его прототип:

\ Joomla \ CMS \ Router \ Route :: _ ($ url, $ xhtml = true, $ ssl = null);

Куда:

  • $ url - это строка, содержащая абсолютный или относительный внутренний Joomla! URL.
  • $ xhtml - это логическое значение, которое указывает, должен ли вывод быть в XHTML. Этот параметр является необязательным, и по умолчанию он имеет значение true.
  • $ ssl является целочисленным значением, которое указывает, должен ли URI быть безопасным. Должно быть установлено значение 1, чтобы заставить URI быть защищенным с использованием глобального URI защищенного сайта, 0, чтобы оставить его в том же состоянии, в котором оно было передано, и -1, чтобы заставить URI быть незащищенным, используя глобальный URI незащищенного сайта. ,

Самый важный параметр - это $ url. Вызов этого метода может выглядеть следующим образом:

\ Joomla \ CMS \ Router \ Route :: _ ('index.php? View = article & id ='. $ Row -> slug);

$ row-> slug - это значение, сгенерированное на шаге 2 из комбинации псевдонима id и заголовка.

Другое преимущество использования \ Joomla \ CMS \ Router \ Route :: _ заключается в том, что маршрутизатор теперь обрабатывает параметр $ option (имя компонента) и $ Itemid (идентификатор элемента меню). Самому компоненту не нужно знать свое имя ($ option) или активный пункт меню ($ Itemid), как это было в предыдущей версии Joomla.

На этом этапе важно подумать о последовательности параметра URL. Это станет более понятным, когда мы более подробно рассмотрим router.php в следующем разделе.

Процесс сборки \ Joomla \ CMS \ Router \ Router состоит из двух этапов:

  • Создайте маршрут приложения. Маршрут приложения полностью обрабатывается \ Joomla \ CMS \ Router \ Router, и разработчику компонента не нужно ничего делать, чтобы он работал.
  • Создайте маршрут компонента. Чтобы создать маршрут компонента, \ Joomla \ CMS \ Router \ Router ищет файл router.php в каталоге компонентов, который отвечает за построение маршрута для компонента.

Создание внешних веб-адресов SEF в администраторе

От От   Вы также можете создавать URL-адреса SEF между любыми приложениями (наиболее важным вариантом использования этого будет создание URL-адресов от администратора / API до внешнего интерфейса Joomla) Вы также можете создавать URL-адреса SEF между любыми приложениями (наиболее важным вариантом использования этого будет создание URL-адресов от администратора / API до внешнего интерфейса Joomla). Для достижения этой цели был введен новый метод. Ссылка \ Joomla \ CMS \ Router \ Route :: очень похожа на \ Joomla \ CMS \ Router \ Route :: _, описанную в предыдущем разделе. \ Joomla \ CMS \ Router \ Route :: link имеет четыре параметра, а ее прототип:

\ Joomla \ CMS \ Router \ Route :: link ($ client, $ url, $ xhtml = true, $ ssl = null);

Параметр $ client в этом случае является именем клиента приложения. Так что для Joomla Frontend это будет сайт. Таким образом, пример, который вы можете запустить в разделе администратора

$ app -> enqueueMessage ('3. Администратор сайта:'. JRoute :: link ('site', 'index.php? option = com_content & catid = 1 & view = article & id = 1'));

чтобы получить SEF URL статьи Joomla с идентификатором 1.

Маршрутизатор компонентов

У нас будет три функции в нашем классе в router.php. Один отвечает за создание URL-адреса, а другой - за его разбор. В следующих примерах, очень простых и более продвинутых, мы предполагаем, что у нас есть три представления, на которые могут ссылаться ссылки. Первый - это обзор категорий (view = category), второй - отдельная категория (view = category), а третий - отдельная статья (view = article). Файл router.php должен находиться в области сайта вашего компонента. Он не используется на страницах администратора / бэкэнда. Не забудьте добавить его в свой XML файл манифеста в папке сайта.

Простой пример на основе вида

Часто в структуре URL Joomla у вас будут структуры маршрутизации, основанные на иерархиях представлений. В этом примере мы попытаемся отразить текущий уровень иерархии в URL из существующего пункта меню. Цель состоит в том, чтобы URL выглядели так:

  • При просмотре статьи: http://www.example.com/[menualias]/[category]/[article]
  • При просмотре категории: http://www.example.com/[menualias]/[category]
  • При просмотре обзора категорий: http://www.example.com/[menualias]

Ссылка на статью будет выглядеть так:

\ Joomla \ CMS \ Router \ Route :: _ ('index.php? View = article & catid ='. $ Row -> catslug. '& Id ='. $ Row -> slug);

И ссылка на категорию будет выглядеть так:

\ Joomla \ CMS \ Router \ Route :: _ ('index.php? View = category & id ='. $ Row -> catslug);

поскольку поскольку   (и реализованы в основных компонентах, так как   в качестве «новых компонентных маршрутизаторов») существует новый способ работы с маршрутизаторами с использованием базового класса \ Joomla \ CMS \ Component \ Router \ RouterView (и реализованы в основных компонентах, так как в качестве «новых компонентных маршрутизаторов») существует новый способ работы с маршрутизаторами с использованием базового класса \ Joomla \ CMS \ Component \ Router \ RouterView. Это обрабатывает маршрутизацию, позволяя вам регистрировать представления в вашей системе. Итак, прежде всего, давайте создадим конструктор маршрутизатора нашего компонента:

/ ** * Конструктор маршрутизатора Magic Component * * @param CMSApplication $ app Объект приложения * @param AbstractMenu $ menu Объект меню для работы с * / public function __construct ($ app = null, $ menu = null) {$ category = новая RouterViewConfiguration ('категория'); $ category -> setKey ('id') -> setNestable (); $ this -> registerView ($ category); $ article = new RouterViewConfiguration ('article'); $ article -> setKey ('id') -> setParent ($ category, 'catid'); $ this -> registerView ($ article); }

Так что мы здесь сделали? Итак, мы зарегистрировали представление категории, у которого есть ключ маршрутизации с его идентификатором, который может быть вложенным (то есть иметь несколько уровней). Мы также зарегистрировали представление статьи, которое также имеет ключ маршрутизации id, у которого есть родительский элемент представления категории.

Теперь мы зарегистрировали представления нашего компонента в нашем маршрутизаторе. Следующим шагом является регистрация правил Joomla, которые используют эти правила. Есть 3 правила, предоставленные Joomla из коробки. Первый \ Joomla \ CMS \ Component \ Router \ Rules \ MenuRules проверяет, соответствует ли URL-адрес известному элементу меню, и обеспечивает на многоязычных сайтах наличие языкового тега. Второе правило \ Joomla \ CMS \ Component \ Router \ Rules \ StandardRules использует конфигурацию вашего представления для построения пути меню. Наконец, третье правило \ Joomla \ CMS \ Component \ Router \ Rules \ NomenuRules предоставляет запасной вариант, когда не найдено подходящего соответствия для построения или анализа URL-адреса. После применения этих правил наш законченный конструктор маршрутизатора выглядит так:

публичная функция __construct (CMSApplication $ app = null, AbstractMenu $ menu = null) {$ category = new RouterViewConfiguration ('category'); $ category -> setKey ('id') -> setNestable (); $ this -> registerView ($ category); $ article = new RouterViewConfiguration ('article'); $ article -> setKey ('id') -> setParent ($ category, 'catid'); $ this -> registerView ($ article); parent :: __construct ($ app, $ menu); $ this -> attachRule (новые MenuRules ($ this)); $ this -> attachRule (new StandardRules ($ this)); $ this -> attachRule (new NomenuRules ($ this)); }

Последняя часть головоломки, в которой нуждается Joomla, - преобразовать идентификаторы в их псевдонимы и обратно. Таким образом, для каждого зарегистрированного представления вам нужно предоставить метод get Viewname Segment ($ id, $ query) и метод get Viewname Id ($ сегмент, $ query) для построения и анализа URL-адресов. Таким образом, для нашего примера нам нужны четыре функции: getCategorySegment, getCategoryId, getArticleSegment и getArticleId. Вы можете увидеть реализацию этих четырех функций на https://github.com/joomla/joomla-cms/blob/3.8.0/components/com_content/router.php , Для статей мы собираемся непосредственно проверить наши слагы в базе данных, а для категорий мы будем использовать класс Jomategor'а Joomla для проверки пути к нашей категории.

Создать сложный маршрутизатор в Joomla действительно так просто!

Более сложный пример

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

использовать Joomla \ CMS \ Component \ Router \ RouterBase; class [componentname] Маршрутизатор расширяет RouterBase {сборка публичной функции (& $ query) {$ сегменты = массив (); if (isset ($ query ['view'])) {$ сегменты [] = $ query ['view']; unset ($ query ['view']); } if (isset ($ query ['id'])) {$ сегменты [] = $ query ['id']; unset ($ query ['id']); }; вернуть $ сегменты; }

\ Joomla \ CMS \ Router \ Router передает массив $ query в функцию [ componentname ] Router :: build. Эта функция добавит соответствующие части массива в массив $ сегментов в правильном порядке и вернет правильно упорядоченный массив. Содержимое массива $ query должно быть не установлено, в противном случае \ Joomla \ CMS \ Router \ Router добавит его в URL в виде строки запроса (т. Е. Любые переменные, которые не обрабатываются маршрутизатором, будут переданы в Строка запроса). Обратите внимание на то, что выше мы решили расширить \ Joomla \ CMS \ Component \ Router \ RouterBase, так как нам не нужно выполнять никакой предварительной обработки в этом простом примере.

Префикс имени компонента - это имя вашего компонента, которое находится в каталоге, содержащем файлы компонента. Например, компонент «Magic» в каталоге / components / com_magic / ... будет использовать префикс magic (все строчные). Следующая функция в router.php анализирует URL:

публичная функция parse (& $ сегменты) {$ vars = array (); switch ($ сегменты [0]) {регистр 'категорий': $ vars ['view'] = 'категории'; перерыв ; case 'category': $ vars ['view'] = 'category'; $ id = explode (':', $ сегменты [1]); $ vars ['id'] = (int) $ id [0]; перерыв ; case 'article': $ vars ['view'] = 'article'; $ id = explode (':', $ сегменты [1]); $ vars ['id'] = (int) $ id [0]; перерыв ; } вернуть $ vars; }

Что здесь происходит? В функции [ componentname ] Router :: build мы расположили элементы в массиве $ query в определенной последовательности. Это означает, что в этом примере представление является первым, а идентификатор - вторым в массиве.

Читая $ сегменты [0], мы получаем доступ к имени представления. Мы устанавливаем правильный вид и / или идентификатор в зависимости от его значения и возвращаем массив $ vars в \ Joomla \ CMS \ Router \ Router. $ vars должен быть ассоциативным массивом, аналогичным массиву, который был передан в метод BuildRoute.

Приведенный выше пример router.php - очень простой способ создания URL-адресов SEF, но он должен показать, как это работает достаточно четко. Сгенерированный URL в этом примере содержит имя представления и не отражает иерархию содержимого:

http://www.example.com/[menualias]/[view]/[slug]

Последней важной частью создания маршрутизатора является рассмотрение того, что делать с пунктами меню. Как объяснено на Поисковая система выходной сигнал маршрутизатора компонента используется после первого сегмента маршрута, причем первый сегмент является псевдонимом пункта меню. Это создает сложный вопрос: как ваш маршрутизатор и / или другой код узнают, через какой пункт меню будет проходить маршрутизация?

Предположим, например, что ваш компонент в настоящее время производит вывод для страницы / собак, в которой перечислены все собаки в системе. Конечно, элементы в списке должны быть ссылками на страницы, которые отображают более подробную информацию об одной собаке. Каким должен быть URL к собаке с ID 21 и именем Fido? Используя маршрутизатор, который работает в соответствии с принципами, которые мы видели до сих пор, получается маршрут собак / 21-фидо или с дополнительной работой / собаками / фидо. Но, возможно, пользователь создал пункт меню с псевдонимом mydoggy, который отображает именно данные этой собаки. Тогда, вероятно, пользователь намерен направить этот URL через этот пункт меню, и элемент в списке должен ссылаться на страницу / mydoggy.

В целом, когда вы строите маршрут, вам нужно будет найти пункт меню, который наиболее подходит в качестве отправной точки для построения вашего маршрута. Термин начальная точка подчеркнут, потому что остальная часть маршрута зависит от конфигурации пункта меню. В нашем примере выше, / dogs / 21-fido является приемлемым маршрутом, / mydoggy, возможно, даже лучше, но / mydoggy / 21-fido просто неверен, так как / mydoggy сам по себе является элементом меню, который настроен для отображения Информация. Существует несколько подходов для решения этой проблемы. Основные компоненты Joomla! Используют смешанный подход, разделяя обязанности в двух единицах кода: самом маршрутизаторе и так называемом [componentname] RouteHelper. [Componentname] RouteHelper предоставляет методы, которые находят наиболее подходящий элемент меню для данного фрагмента данных, который должен отображаться, в то время как маршрутизатор анализирует элемент меню и помещает в маршрут любую информацию, которая не определяется конфигурацией элемента меню. Это означает, что вызывающий код должен явно вызывать метод помощника перед маршрутизацией (echo \ Joomla \ CMS \ Router \ Route :: _ (DogsRouteHelper :: getDogRoute (21));).

Смотрите также

Подробнее о внутренностях маршрутизации см. Детали реализации маршрутизации ,

Php?
Php?
Php?
Php?
Php?
Php?
Php?
Php?
Это создает сложный вопрос: как ваш маршрутизатор и / или другой код узнают, через какой пункт меню будет проходить маршрутизация?
Каким должен быть URL к собаке с ID 21 и именем Fido?