Принципы вывода данных в Joomla

Разбираемся, каким образом происходит вывод данных в Joomla.

Вывод данных в Joomla зависит от того, какой тип приложения используется.

В консольном приложении (командной строки) вывод данных заключается в простом выводе с помощью команды echo (или другой подобной) необходимой информации.

В API приложении, которое доступно с Joomla 4, вывод данных состоит из ответа в формате JSON.

Наиболее сложным является процесс вывода данных в веб-приложении. Именно в нем раскрываются основные понятия, связанные с выводом: документ, рендерер, шаблон, макеты вывода и их переопределение.

Ниже мы рассмотрим процесс вывода данных в веб-приложении публичной части.

Диспетчеризация веб-приложения

Формирование выходных данных начинается на шаге диспетчеризации цикла выполнения веб-приложения. Именно здесь, помимо выполнения компонента, происходит подготовка объекта документа для его последующего рендеринга.

Документ в Joomla - это класс, который отвечает за подготовку данных (содержимого) к рендерингу. Эти данные до момента их вывода устанавливаются в специальных буферах документа.

Разбивка на различные классы документов зависит от формата выходных данных. Чаще всего мы имеем дело с классом HtmlDocument, который отвечает, как нетрудно догадаться, за вывод данных в формате HTML. На шаге диспетчеризации происходит инициализация необходимого объекта документа в зависимости от формата выходных данных.

Если формат выходных данных соответствует HTML, то дополнительно происходит определение того, какой шаблон будет использоваться для вывода данных.

Шаблон в Joomla - это один из типов расширений, которое определяет внешний вид веб-сайта. Подробнее о шаблоне можно почитать в официальной документации.

Кроме того, на этом шаге происходит установка мета-данных, заголовка и описания документа, а также установка результата выполнения компонента в буфер component документа.

Ниже представлена UML диаграмма последовательности, на которой отображена диспетчеризация веб-приложения:

Диспетчеризации веб-приложения Joomla

Рендеринг веб-приложения

Рендеринг веб-приложения - это отправка содержимого буферов документа в плейсхолдеры (специальные теги jdoc) шаблона и дальнейшая отправка сформированной HTML строки в тело (body) веб-приложения.

Процесс начинается с определения и подключения файла шаблона. По умолчанию это index.php. Могут быть подключены и другие файлы. Например, если сайт находится в режиме оффлайн, то происходит подключение файла offline.php, а если на сайте возникла ошибка, то вызывается файл error.php.

Когда файл шаблона определен, происходит получение содержимого файла шаблона и его разбор (парсинг) - создание массива тегов шаблона со всеми элементами разметки jdoc:include (с информацией о заголовке, компоненте, модулях, сообщениях и отладке).

Подробнее о тегах шаблона читайте здесь.

Далее происходит рендеринг документа - обход массива тегов шаблона с вызовом буферов документа для каждого тега. Во время обхода выполняется загрузка необходимого типа рендерера: head, component, module / modules, message. Результат рендеринга устанавливается в соответствующий буфер документа.

Рендерер - это класс, отвечающий за специфическую обработку своего типа выходных данных. Например, класс HeadRenderer собирает заголовок документа (HTML тег head), а класс ModuleRenderer подготавливает для отображения модули.

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

Ниже представлена UML диаграмма последовательности, на которой отображен рендеринг веб-приложения:

Рендеринг веб-приложения Joomla

Вывод расширений

Итак, мы разобрались, как веб-приложение обрабатывает данные для вывода. Давайте посмотрим, каким образом эти данные доходят до шага рендеринга.

Вывод компонентов

Для того чтобы понять, как работает вывод компонента, необходимо ознакомиться с его структурой. В частности нас интересует структура директории 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 можно почитать здесь.

© 2019 BinaryCraft. Все права защищены.