Принципы вывода данных в Joomla
Разбираемся, каким образом происходит вывод данных в Joomla.
Оглавление
Вывод данных в Joomla зависит от того, какой тип приложения используется.
В консольном приложении (командной строки) вывод данных заключается в простом выводе с помощью команды echo (или другой подобной) необходимой информации.
В API приложении, которое доступно с Joomla 4, вывод данных состоит из ответа в формате JSON.
Наиболее сложным является процесс вывода данных в веб-приложении. Именно в нем раскрываются основные понятия, связанные с выводом: документ, рендерер, шаблон, макеты вывода и их переопределение.
Ниже мы рассмотрим процесс вывода данных в веб-приложении публичной части.
Диспетчеризация веб-приложения
Формирование выходных данных начинается на шаге диспетчеризации цикла выполнения веб-приложения. Именно здесь, помимо выполнения компонента, происходит подготовка объекта документа для его последующего рендеринга.
Документ в Joomla - это класс, который отвечает за подготовку данных (содержимого) к рендерингу. Эти данные до момента их вывода устанавливаются в специальных буферах документа.
Разбивка на различные классы документов зависит от формата выходных данных. Чаще всего мы имеем дело с классом HtmlDocument, который отвечает, как нетрудно догадаться, за вывод данных в формате HTML. На шаге диспетчеризации происходит инициализация необходимого объекта документа в зависимости от формата выходных данных.
Если формат выходных данных соответствует HTML, то дополнительно происходит определение того, какой шаблон будет использоваться для вывода данных.
Шаблон в Joomla - это один из типов расширений, которое определяет внешний вид веб-сайта. Подробнее о шаблоне можно почитать в официальной документации.
Кроме того, на этом шаге происходит установка мета-данных, заголовка и описания документа, а также установка результата выполнения компонента в буфер component документа.
Ниже представлена UML диаграмма последовательности, на которой отображена диспетчеризация веб-приложения:
Рендеринг веб-приложения
Рендеринг веб-приложения - это отправка содержимого буферов документа в плейсхолдеры (специальные теги jdoc
) шаблона и дальнейшая отправка сформированной HTML строки в тело (body) веб-приложения.
Процесс начинается с определения и подключения файла шаблона. По умолчанию это index.php. Могут быть подключены и другие файлы. Например, если сайт находится в режиме оффлайн, то происходит подключение файла offline.php, а если на сайте возникла ошибка, то вызывается файл error.php.
Когда файл шаблона определен, происходит получение содержимого файла шаблона и его разбор (парсинг) - создание массива тегов шаблона со всеми элементами разметки jdoc:include
(с информацией о заголовке, компоненте, модулях, сообщениях и отладке).
Подробнее о тегах шаблона читайте здесь.
Далее происходит рендеринг документа - обход массива тегов шаблона с вызовом буферов документа для каждого тега. Во время обхода выполняется загрузка необходимого типа рендерера: head, component, module / modules, message. Результат рендеринга устанавливается в соответствующий буфер документа.
Рендерер - это класс, отвечающий за специфическую обработку своего типа выходных данных. Например, класс HeadRenderer собирает заголовок документа (HTML тег head
), а класс ModuleRenderer подготавливает для отображения модули.
После того, как все буферы документа заполнены данными, выполняется замена тегов шаблона соответствующим содержимым документа и установка полученных данных рендеринга в тело веб-приложения.
Ниже представлена UML диаграмма последовательности, на которой отображен рендеринг веб-приложения:
Вывод расширений
Итак, мы разобрались, как веб-приложение обрабатывает данные для вывода. Давайте посмотрим, каким образом эти данные доходят до шага рендеринга.
Вывод компонентов
Для того чтобы понять, как работает вывод компонента, необходимо ознакомиться с его структурой. В частности нас интересует структура директории views. Именно здесь происходит работа по выводу данных.
В качестве примера, ниже представлена частичная структура views компонента com_content (Менеджер материалов):
/components /com_content /views ... /article /tmpl default.php (макет) default.xml (параметры макета) default_links.php (суб-макет) view.html.php (представление для вывода HTML) /category /tmpl blog.php (макет) blog.xml (параметры макета) blog_children.php (суб-макет) blog_item.php (суб-макет) blog_items.php (суб-макет) default.php (макет) default.xml (параметры макета) default_articles.php (суб-макет) default_children.php (суб-макет) view.html.php (представление для вывода HTML) view.feed.php (представление для вывода RSS) ...
Представление
За вывод данных в компоненте отвечает представление (view). В компоненте представления расположены в директории views.
Классы представления, так же как и документ, зависят от формата выводимых данных.
Необходимое представление устанавливается путем передачи параметра view в URL. Например, если был передан view=category
, то будет вызван файл представления views/category/view.html.php.
Когда необходимый класс представления установлен, он подготавливает данные для вывода и подключает макет вывода для их отображения.
Макет вывода
Макеты вывода располагаются в директории tmpl представления. По умолчанию подключается макет default.php. Чтобы задать другой макет вывода, необходимо использовать параметр layout
в URL. Например, если в дополнение к параметру view=category
был передан layout=blog
, то будет подключен макет views/category/tmpl/blog.php.
Суб-макет
Для разбивки макета на несколько частей используется суб-макет. Например, макет блога категории состоит из четырех частей - основного макета blog.php и трех суб-макетов: blog_children.php, blog_item.php и blog_links.php.
Для подключения суб-макета используется метод loadTemplate
класса представления:
echo $this->loadTemplate('item');
При этом представление знает, в каком макете мы находимся, и нет необходимости указывать его в качестве префикса. Поэтому мы подключаем item, а не blog_item.
Параметры макета
Параметры макета - это специальный XML файл манифеста, который необходим для возможности создания пункта меню и определения настроек макета, которые доступны при создании пункта меню. Название этого файла должно совпадать с названием файла макета. Если файл манифеста отсутствует, то пункт меню создать невозможно.
Пункт меню
Чтобы понять, как связаны между собой представления, макеты и параметры, взглянем на создание пункта меню Менеджера материалов:
Здесь наглядно виден список всех представлений и относящихся к ним макетов. Каждый из файлов манифеста формирует свой тип пункта меню. Например, в рамках представления категории доступна два разных макета Блог категории и Список материалов категории.
Вот так выглядят параметры макета в пункте меню Блог категории:
Рендеринг
Всё, что выводится в макетах компонента, далее попадает для рендеринга в буфер документа. За рендеринг компонента отвечает класс ComponentRenderer. Никакой специальной обработки он не делает, напрямую выводя то, что выводит компонент.
Макеты вывода модулей и плагинов
В отличии от компонента, в модулях и плагинах нет представления. Вывод данных в них происходит напрямую в макеты, которые располагаются в директории tmpl. По умолчанию подключается макет default.php.
Как правило, в настройках модуля можно выбрать, какой именно макет должен использоваться для отображения.
Вот так выглядит подключение макета модуля на примере модуля mod_articles_latest:
require ModuleHelper::getLayoutPath('mod_articles_latest', $params->get('layout', 'default'));
И пример подключения макета плагина из плагина pagebreak:
$path = PluginHelper::getLayoutPath('content', 'pagebreak', 'toc');
ob_start();
include $path;
$row->toc = ob_get_clean();
За рендеринг модуля отвечает класс ModuleRenderer, если jdoc
шаблона выводит конкретный модуль, или ModulesRenderer, если jdoc
шаблона выводит сразу несколько модулей в одной позиции.
Рендеринг плагина не требует специального рендерера, так как выводится либо в рамках отображения компонента, либо в рамках отображения модуля.
Layouts
Кроме обычных макетов вывода, в Joomla существуют так называемые layouts. Это тоже своего рода макеты и изначально их основное применение - вывод повторяющихся частей HTML кода. Например, один и тот же код необходимо использовать в разных представлениях компонента или даже в разных расширениях.
При желании их можно использовать в качестве обычных макетов, а также вместе с обычными макетами для разбивки макетов на несколько частей.
Такие макеты располагаются в директории layouts расширения. Макеты, которые использует Joomla для своих расширений, располагаются в директории layouts корня установки Joomla.
За реализацию layouts отвечает пакет классов Layout. В частности, применяется класс LayoutHelper, который принимает название макета (содержит в себе путь до макета) и данные для отображения.
Например, изображение вступительного текста материала в Менеджере материалов используется в разных представлениях, поэтому оно вынесено в отдельный макет, который расположен в /layouts/joomla/content/intro_image.php. Выводится он следующим образом:
<?php echo LayoutHelper::render('joomla.content.intro_image', $this->item); ?>
Переопределение макетов вывода
Мы добрались до одной из лучших возможностей Joomla - переопределение макетов вывода.
Суть переопределения заключается в том, что все макеты вывода, используемые для отображения расширений, можно настроить под себя. Это даёт практически безграничные возможности внешнего оформления веб-сайта.
Выше мы разобрались, каким образом происходит подключение макетов для вывода данных из расширений. Секрет переопределения в том, что перед тем, как подключить необходимый макет, Joomla ищет его не в директории расширения, а в директории переопределений, которая располагается по пути templates/{активный_шаблон}/html.
Предположим, нам необходимо переопределить макет default материала. За вывод материала отвечает представление article компонента com_content (Менеджер материалов). Тогда переоформление макета должно располагаться в директории html/com_content/article/default.php.
Для переопределения макетов модуля создаем файлы в html/mod_{название_модуля}
Для переопределения плагина в html/plg_{группа_плагина}_{название_плагина}
Если мы переопределяем layouts, то используем путь html/layouts/{название_расширения}
Подробное руководство о переопределениях макетов доступно здесь. Руководство по переопределению layouts можно почитать здесь.
Layout LayoutHelper PluginHelper ModuleHelper HtmlDocument HeadRenderer ModuleRenderer ComponentRenderer ModulesRenderer
- Последнее обновление: .