Макеты в Joomla! 3, создание собственных макетов

Макеты в CMS Joomla! – это обычные php файлы, которые выполняют задачу формирования результирующего html кода страницы. Хранятся они всегда в директории tmpl. Для компонентов этот путь выглядит следующим образом:
components/имя_компонента/views/имя_представления/tmpl/имя_макета.php
В модулях путь значительно проще:
modules/имя_модуля/tmpl/имя_макета.php
Как правильно пользоваться макетами и как создавать собственные макеты для представлений компонентов и модулей рассмотрим ниже.
Что делают макеты, зачем они нужны?
В файлах макетов не проводится никаких важных вычислений, касающихся бизнес логики приложения. Большинство алгоритмов отвечает за вывод информации на странице. Зачастую макеты подключаются в представлении и из него получают данные для отображения. Кроме этого в макете доступен ряд настроек, для возможности изменения вывода отдельных его элементов.
По полученным данным и настройкам макет формирует html содержимое страницы со всеми элементами ее оформления, дополнительными графическими эффектами, формами, интерактивным содержимым и т.д. Например, макет
components/com_content/views/article/tmpl/default.php
отвечает за отображение страницы статьи.
В общем случае путь к файлу макета компонента можно описать так:
components/com_компонент/views/имя_представления/tmpl/имямакета.php
Для макетов в модулях путь значительно короче:
modules/mod_модуль/tmpl/имямакета.php
Создание собственного макета компонента
С необходимостью создания собственного маке чаще всего можно столкнуться, когда вам необходимо несколько вариантов отображения одного и того же содержимого. Предположим, что нам понадобилось выводить второй вариант материала Joomla!, а стандартные средства настройки макета не могут предоставить соответствующего варианта отображения. Пусть это будут материалы, содержащие новости.
Мы уже писали о перекрытии макетов в шаблоне. Далее в примерах будем использовать стандартный шаблон Joomla! - protostar. Чтобы создать новый макет сразу в шаблоне, скопируем стандартный макет статьи
components/com_content/views/article/tmpl/default.php
и разместим его по пути
templates/protostar/html/com_content/article/news.php
Мы планируем использовать этот макет в административной части сайта, значит его название не должно содержать символа нижнего подчеркивания.
Теперь можно внести изменения в новый макет. Предположим, что мы бы хотели выводить e-mail автора статьи в этом макете, но в коде стандартного макета нам доступно только имя автора. Вставим в макет следующий код в блоке, который отображает имя автора:
<?php $authorUser = JUser::getInstance($this->item->created_by); ?> <?php if(!empty($authorUser->email)) : ?> <a href="mailto:<?php echo $authorUser->email; ?>" title="<?php echo $authorUser->email; ?>"> <?php echo $authorUser->email; ?> </a> <?php endif; ?>
Для того, чтобы увидеть результат, необходимо выбрать новый макет для отображения статей. Попробуем установить его, как макет по-умолчанию для всех статей на сайте. Для этого в админ части заходим в менеджер материалов и переходим в его настройки.

Первым пунктом здесь видим Выбор макета.

Для того, чтобы в этом списке новый макет имел более понятное название, чем news, необходимо определить языковую константу по шаблону: TPL_ШАБЛОН_COM_КОМПОНЕНТ_ПРЕДСТАВЛЕНИЕ_LAYOUT_МАКЕТ
. В нашем примере эта константа будет иметь вид: TPL_PROTOSTAR_COM_CONTENT_ARTICLE_LAYOUT_NEWS="Макет новостей"
. По префиксу константы можно догадаться, что ее размещение подразумевается в языковом файле шаблона. Но поскольку использовать мы ее будем не в шаблоне, а в настройках материалов, то нужно использовать файл с суффиксом sys. Для русского я зыка это будет файл:
language/ru-RU/ru-RU.tpl_protostar.sys.ini
Для других языков нужно использовать другой путь и название языкового файла, где ru-RU заменено на соответствующее значение кода языка. Кроме этого, если вы создаете макет в другом шаблоне, то и название файла с языковыми константами будет содержать его название.
Если же по каким-либо причинам вы не можете добавить константу в языковой файл шаблона, можно воспользоваться встроенным в CMS Joomla! механизмом переопределения языковых констант. Для этого нужно создать два файлы для русского языка.
language/overrides/ru-RU.override.ini
administrator/language/overrides/ru-RU.override.ini
В первом будут храниться переопределенные языковые константы для пользовательской части сайта, а во втором - для административной соответственно. Новую языковую константу нужно добавить в файл для административной части, поскольку мы хотим, чтобы она выводилась именно там. Для нас второй способ с добавлением языковой константы в файл ru-RU.override.ini
более предпочтителен, чем добавление ее в файл с константами шаблона.
Теперь в нашем списке макетов в административной части сайта выводится указанное нами название нового макета. Выбираем его и сохраняем настройки менеджера материалов.

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

Для того, чтобы переопределить макет одного конкретного материала в Joomla!, необходимо зайти в Менеджер материалов, найти в списке нужный материал и нажать на его название.

После этого перейти на вкладку Отображение в нижнюю ее часть.

Там есть поле Альтернативный макет, в котором мы аналогично выбираем свой собственный макет отображения статьи. После этого сохраняем изменения.

При просмотре этой статьи должен использоваться выбранный нами макет. Для остальных материалов макет должен остаться стандартный.
Использование дополнительных макетов внутри основного
Иногда возникает необходимость вынести часть оформления из макета в отдельный файл макета, чтобы в дальнейшем повторно использовать его или просто разделить страницу на составные блоки. Например, при циклическом выводе элементов массива или для выделения обособленного блока.
Для того, чтобы в рамках существующего макета выделить часть кода в отдельный файл нужно создать файл, имя которого состоит из имени основного макета и названия дополнительного макета, разделенных нижним подчеркивание. Например, если мы ходим создать дополнительный макет для news.php
, то его имя может быть news_author.php
. Как уже многие догадались, именно с этим было связано ограничение на использование нижнего подчеркивания в названиях файлов основного макета. Если в названии файла макета будет присутствовать нижнее подчеркивание, то он не будет выводиться в адим части сайта, как вариант альтернативного макета.
Теперь рассмотрим как использовать дополнительный макет в файле основного на примере. За основу возьмем пример, описанный выше, где мы переопределили макет материала. Попробуем вынести добавленный нами блок с e-mail адресом автора в отдельный макет. Создадим новый файл
templates/protostar/html/com_content/article/news_author.php
со следующим кодом
<?php defined('_JEXEC') or die; ?> <?php $authorUser = JUser::getInstance($this->item->created_by); ?> <?php if(!empty($authorUser->email)) : ?> <a href="mailto:<?php echo $authorUser->email; ?>" title="<?php echo $authorUser->email; ?>"> <?php echo $authorUser->email; ?> </a> <?php endif;
Вместо добавленного в макете news.php
аналогичного блока запишем строку подключения дополнительного макета.
<?php echo $this->loadTemplate('author'); ?>
Как видите, в качестве параметра для функции loadTemplate()
используется только часть имени файла после нижнего подчеркивания. Механизм подключения здесь аналогичен использованию include
или require
, при этом в файле news_author.php
нам доступно все окружение главного макета и мы можем использовать в нем переменные и функции, имеющиеся в основном макете.
Хотя внешне на странице материала ничего и не изменилось, мы выполнили выделение части макета в отдельные дополнительный макет. Аналогично можно выделить и другой код или добавить новый, количество используемых дополнительных макетов не ограничено.
Создание собственного макета модуля
Здесь все очень похоже на создание альтернативного макета для компонента, описанного выше. Рассмотрим пример на базе стандартного модуля для авторизации пользователей – mod_login
. Для начала скопируем базовый файл макета
modules/mod_login/tmpl/default.php
по пути
templates/protostar/html/mod_login/overlogin.php
Как и в примере с компонентом, название макета не содержит символа нижнего подчеркивания. Теперь мы можем внести все необходимые изменения в наш новый макет. Например, добавим простой блок с текстом в верхней его части.
... JHtml::_('bootstrap.tooltip'); ?> <!-- Новый текстовый блок --> <div class="mod_login_top"> Введите свои данные для авторизации на сайте </div> <!-- Конец нового текстового блока --> <form action="<?php echo JRoute::_('index.php', true, $params->get('usesecure')); ?>" method="post" id="login-form" class="form-inline"> ...
Для отображения макета нам нужно в какой-либо части сайта вывести сам модуль, а в его настройках на вкладке Дополнительные параметры выбрать соответствующий Альтернативный макет.

Аналогично примеру с компонентом, добавим языковую константу для нового макета модуля по шаблону: TPL_ШАБЛОН_MOD_МОДУЛЬ_LAYOUT_МАКЕТ
. В нашем примере нужно добавить следующий код TPL_PROTOSTAR_MOD_LOGIN_LAYOUT_OVERLOGIN="Новый макет"
в файл
administrator/language/overrides/ru-RU.override.ini
Убедимся что модуль выводится правильно.

С использованием дополнительных макетов в модулях ситуация немного отличается от их использования в компонентах. Создание файла дополнительного макета происходит аналогично, он помещается в ту же папку, что и основной макет, а его название состоит из названия основного макета, нижнего подчеркивания и дополнительного названия. Отличается код подключения этого файла в основном макете. Если рассматривать ситуацию с примером модуля авторизации и выделить новый текстовый блок в макет overlogin_text.php
, то для его подключения в файле overlogin.php
на месте этого блока нужно поместить строку
<?php require JModuleHelper::getLayoutPath('mod_login', 'overlogin_text'); ?>
Как видите, мы самостоятельно подключаем файл, используя оператор require
. Первым параметром в статический метод JModuleHelper::getLayoutPath()
передается название модуля, а вторым – полное имя макета overlogin_text
.
Как Joomla определяет выбранный макет
Для получения имени макета, который выбран в административной части сайта, Joomla! использует стандартный механизм настроек для компонентов и модулей. Если опираться на приведенные выше примеры, то можем рассмотреть файл
administrator/components/com_content/config.xml
В нем есть поле, отвечающее за выбор макета для материалов сайта.
<field name="article_layout" type="componentlayout" label="JGLOBAL_FIELD_LAYOUT_LABEL" description="JGLOBAL_FIELD_LAYOUT_DESC" menuitems="true" extension="com_content" view="article" />
Получение данного параметра в файле представления
components/com_content/views/article/view.html.php
происходит за счет кода
$item->params->get('article_layout');
Если рассматривать пример с модулем mod_login
, то интересующий нас параметр описывается в файле
modules/mod_login/mod_login.xml
и имеет вид
<field name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" description="JFIELD_ALT_MODULE_LAYOUT_DESC" />
Получение самого параметра происходит в файле
modules/mod_login/mod_login.php
в строке
$params->get('layout', 'default');
Здесь вторым параметром в функцию get
передается название макета по-умолчанию.
Как видите, у Joomla! есть отдельные типы полей для выбора макета в компонентах и модулях. В случае с компонентами это поле типа componentlayout
, а для модулей используется modulelayout
. Это стоит учитывать при создании собственных компонентов или модулей, которые поддерживают функционал выбора макета в административной части сайта.