Подключение Медиа- ресурсов в шаблон Joomla v5/6. Технология WebAssets (Часть 2)

Подключаем стили и скрипты

В Joomla версии ≤ 3, CSS-стили, скрипты, изображения обычно размещались в папке самого шаблона, что порой создавало проблемы для оптимизации сайтов, рассчитанных на высокую посещаемость. В Joomla 5/6 для подключения и загрузки применяется технология WebAssets — современная система управления ресурсами (CSS, JavaScript, Шрифтами) в Joomla.

Её основная цель — централизованное управление зависимостями, версиями и порядком загрузки ассетов медиа-ресурсов, для повышения производительности и удобства разработки.

Папка ресурсов (Media)

Все важные медиа-файлы теперь размещаются в папке ресурсов: media . На сайте она будет размещена в: _siteroot/media/templates/site/имя шаблона но мы продолжим вносить изменения в папку проекта:
/Наши проекты/tmpl_simple_1.0/

В будущем, в наш шаблон можно будет вносить изменения непосредственно на сайте, но пока мы вносим изменения в саму структуру шаблона, удобней делать это в отдельном каталоге проекта.

Создадим папку /Наши проекты/tmpl_simple_1.0/media

Папка ресурсов шаблона обычно содержит несколько дополнительных папок:

  • css для файлов CSS,
  • js для файлов JavaScript,
  • images для изображений.
  • fonts для шрифтов, если они есть
  • scss для файлов SCSS (Sass), если этот препроцессор будет использован в разработке.

Продолжаем работу с нашим шаблоном. Добавим некоторые изменения в файл манифеста шаблона. Чтобы шаблон мог унаследовать элементы системного шаблона Joomla, полезно включить для него возможность наследования:

<inheritable>1</inheritable>

Эта директива позволит также создавать стили производные от стиля данного шаблона.

После секции добавим в манифест секцию media.

<media destination="templates/site/simple" folder="media">
    <folder>js</folder>
    <folder>css</folder>
    <folder>scss</folder>
    <folder>fonts</folder>
    <folder>images</folder>
</media>

В папке шаблона для этой секции создадим папку media внутри которой разместим соответствующие описанию каталоги: js,scc,scss,fonts,images.

В папку images сразу имеет смысл добавить две служебные картинки: template_preview.png (Размером: 800x567 px) и template_thumbnail.png (200x142 px).

Когда вы переключали стили на наш шаблон, то уже замечали, что в таблице, где находится иллюстрация к нашему шаблону отображается n/a (не найдено).
Эти картинки являются такими служебными иллюстрациями. Первая (template_preview.png) обычно является скриншетом (копией экрана) готового шаблона, а вторая (template_thumbnail.png) его уменьшенный вариант для оглавлений. Для работы шаблона их наличие не критично, но стоит добавить их для того, чтобы в административной панели все выглядело красиво.

Создадим в каталоге media/css файл стилей шаблона: template.css и скопируем в него секцию стилей из нашего index.php файла. В папке js создадим заготовку под наш файл js-скриптов, пустой текстовый файл: template.js

В папки fonts и scss, которые на данном этапе не используется, имеет смысл записать пустой файл index.html. При установке пустых каталогов, описания которых есть в секции манифеста, система может выдавать ошибку.

В версиях 1-3 Joomla разработчики рекомендовали, размещать в каждый каталог, входящий в состав расширения любого типа, пустой файл index.html из соображений безопасности, Таким образом, предполагалось блокировать вывод списка файлов содержимого каталога Веб-сервером Apache, с включенным параметром: Options +Indexes, что довольно часто встречалось на виртуальных хостингах. Хотя большинство сайтов сейчас уже не работает непосредственно на Apache, привычка записывать в каждый новый каталог расширений пустой index.html, лишней не будет.

Для подключения файлов assets к странице нам нужно подготовить файл описания, который обычно называется joomla.asset.json

В него мы пока добавим только созданный выше файл стилей шаблона template.css.

{
  "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
  "name": "simple",
  "version": "1.0.1",
  "description": "This file contains details of the assets used by Simple template.",
  "license": "GPL-2.0-or-later",
  "assets": [
    {
      "name": "template.simple.mainstyles",
      "description": "The default css style to use.",
      "type": "style",
      "uri": "media/templates/site/simple/css/template.css"
    },
    {
      "name": "template.simple.scripts",
      "description": "The file containing the javascript for this template.",
      "type": "script",
      "uri": "media/templates/site/simple/js/template.js",
      "attributes": {
        "defer": true
      },
      "dependencies": [
        "core"
      ]
    }
  ]
}

Этот файл необходимо описать в секции site манифеста, для того чтобы он был перенесен в папку шаблона при установке и использовался для загрузки медиа-ресурсов.

<filename>joomla.asset.json</filename>
<filename>index.html</filename>

Не забудем также добавить в секции site и media манифеста файлы заглушки: index.html

Для непосредственной загрузки assets потребуется внести изменения в index.php шаблона добавив в него строки для работы с менеджером медиа-ресурсов (Web Asset Manager).

Ниже строки:

defined('_JEXEC') or die;

Добавим импортируем основной класс Joomla приложения и за.

use Joomla\CMS\Factory; // Factory class: 
//Содержит статические методы получения глобальных объектов из приложения Joomla. 

/** @var Joomla\CMS\Document\HtmlDocument $this */
$app   = Factory::getApplication(); 
$wa    = $this->getWebAssetManager(); // Получем ссылку на менеджер медиа-ресурсов - используется для загрузки нашего CSS  и др. в будущем 

//Файлы стилей и сриптов определены в joomla.asset.json!
$wa->useStyle('template.simple.mainstyles');
$wa->useScript('template.simple.scripts');

Далее идет строка, которая выведет в шаблон мета-тэг, сообщающий браузеру, о том что наш шаблон дизайна будет адаптивным (responsive design).

$this->setMetaData('viewport', 'width=device-width, initial-scale=1');

Ниже внесем изменения в страницы для непосредственной загрузки мета-тэгов, стилей и скриптов менеджером медиа-ресурсов.

    <jdoc:include type="metas" />
  <?php // Загрузка CSS и JS файлов web asset manager ?>
    <jdoc:include type="styles" />
    <jdoc:include type="scripts" />

Итоговый манифест шаблона теперь выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<extension type="template" client="site" method="upgrade">
    <name>Simple</name>
    <version>1.0.1</version>
    <creationDate>2025-12-01</creationDate>
    <author>Futurelab LLC by Mike J.K.</author>
    <authorEmail>Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.</authorEmail>
    <authorUrl>https://futurelab.ru</authorUrl>
    <copyright>(C) FutureLab LLC. All rights reserved.</copyright>
    <description>Basic CMS template Joomla 5</description>
    <license>GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html</license>
    <inheritable>1</inheritable>
    <files>
        <filename>index.php</filename>
        <filename>templateDetails.xml</filename>
        <filename>joomla.asset.json</filename>
        <filename>index.html</filename>
    </files>
    <media destination="templates/site/simple" folder="media">
        <folder>js</folder>
        <folder>css</folder>
        <folder>scss</folder>
        <folder>fonts</folder>
        <folder>images</folder>
        <filename>index.html</filename>
    </media>
    <positions>
        <!-- Шапка -->
        <position>header</position>      
        <!-- Контент -->
        <position>main</position>
        <!-- Футер -->
        <position>footer</position>
        <position>debug</position>
    </positions>
</extension>

Сворачиваем папку нашего шаблона в zip-файл и устанавливаем (обновляем) его в CMS.

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

Упрощение загрузки с помощью Preset

Если файлов стилей и сриптов в joomla.asset.json достаточно много, то их загрузка в index.php может выглядеть достаточно громоздко.
Их можно объединить в один блок (ассет) типа Preset. Для нашего шаблона Preset может выглядеть так:

{
  "name": "preset.simple",
  "type": "preset",
  "dependencies": [
    "template.simple.mainstyles#style",
    "template.simple.scripts#script"
  ]
}

После чего конструкция в index.php:

$wa->useStyle('template.simple.mainstyles')
       ->useScript('template.simple.scripts');

легким движением руки превращается в одну единственную строку кода:

$wa->usePreset('preset.simple');

Эта достаточно полезно, когда требуется подключить большое количество файлов ресурсов, например какой-то фронтэнд- фреймворк типа Bootstrap.

Расширяем функциональность шаблона

Путь к медиа-файлам шаблона

Данная строка определяет путь до медиа-файлов текущего шаблона, относительно корневой директории сайта.

// Get this template's Media path
$templatePath = 'templates/' . $this->template;

Ниже узнаем, для чего это можно использовать.

Добавляем favicon

Следующая строка добавляет к сайту favicon — маленький значек, который отображаемому в верхней части экрана браузера или при закладке страницы пользователями на компьютерах или телефонах.

// Get this template's Media path
$templatePath = '/media/templates/site/' . $this->template;
$this->addHeadLink($templatePath . '/images/favicon.ico', 'icon', 'rel', ['type' => 'image/x-icon']);

Эта строка указывает Joomla добавить ссылку на файл favicon.ico в заголовок страницы. Сам favicon.ico надр разместить в папку: _siteroot/media/templates/site/simple/images. Ничего изменять здесь не нужно, кроме случая переименования файла favicon.

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

// Browsers support SVG favicons
$this->addHeadLink($templatePath . '/images/favicon.svg', 'icon', 'rel', ['type' => 'image/svg+xml'])

Активные переменные

Активные переменные будут меняться в зависимости от информации на странице, которую просматривает пользователь. Они позволяют менять поведение шаблона в зависимости от отображаемой страницы.

// Определение активных переменных
$option   = $app->input->getCmd('option', '');
$view     = $app->input->getCmd('view', '');
$layout   = $app->input->getCmd('layout', '');
$task     = $app->input->getCmd('task', '');
$itemid   = $app->input->getCmd('Itemid', '');
$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8');
$menu     = $app->getMenu()->getActive();
$pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';

Например, переменная $itemid содержит значение идентификатора страницы из базы данных. Переменная $sitename хранит название сайта, заданное в глобальных настройках. Переменная $pageclass представляет собой класс CSS страницы, указанный в параметрах пункта меню. Никаких изменений вносить сюда не рекомендуется.

Убираем из заголовка страницы мета-тэг Generator

Joomla "по умолчанию" добавляет в заголовок создаваемой страницы мета-тэг, показывающий что страница создана CMS Joomla:

<meta name="generator" content="Joomla! - Open Source Content Management">

Для отключения этой функциональности добавим в код index.php шаблона следующий код:

$app->getDocument()->setGenerator('');

Иногда полезно задать свой собственный тэг, например:

$app->getDocument()->setGenerator('J-CMS');

Итоговый index.php с результатом этой части руководства:

<?php
defined('_JEXEC') or die;

use Joomla\CMS\Factory; // Factory class: Содержит статические методы получения глобальных объектов из приложения Joomla. Очень важно!

/** @var Joomla\CMS\Document\HtmlDocument $this */
$app   = Factory::getApplication();
$app->getDocument()->setGenerator('J-CMS');

$wa    = $this->getWebAssetManager();   // Получаем ссылку на менеджер медиа-ресурсов - используется для загрузки нашего CSS  и др. в будущем


//Файлы стилей и сриптов определены в joomla.asset.json!
$wa->useStyle('template.simple.mainstyles');
$wa->useScript('template.simple.scripts');

//Set viewport meta tag for mobile responsiveness 
$this->setMetaData('viewport', 'width=device-width, initial-scale=1');

// Get this template's path
$templatePath = 'templates/' . $this->template;
$this->addHeadLink($templatePath . '/images/favicon.ico', 'icon', 'rel', ['type' => 'image/x-icon']);
// Browsers support SVG favicons
$this->addHeadLink($templatePath . '/images/favicon.svg', 'icon', 'rel', ['type' => 'image/svg+xml']);

// Detecting Active Variables
$option   = $input->getCmd('option', '');
$view     = $input->getCmd('view', '');
$layout   = $input->getCmd('layout', '');
$task     = $input->getCmd('task', '');
$itemid   = $input->getCmd('Itemid', '');
$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8');
$menu     = $app->getMenu()->getActive();
$pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';

?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>">
<head>
    <jdoc:include type="metas" />
    <jdoc:include type="styles" />
    <jdoc:include type="scripts" />
 </head>
<body>


 <!-- Header -->
 <header class="header">
     <?php if ($this->countModules('header')) : ?>
        <jdoc:include type="modules" name="header" style="raw" />
    <?php endif; ?>
</header>


<!-- Main Content -->
<main>
<!-- Компонент -->
<jdoc:include type="component" />


<!-- Footer -->
<footer>     
<?php if ($this->countModules('footer')) : ?>
    <jdoc:include type="modules" name="footer" style="raw" />
<?php endif; ?>
</footer>

    <!-- Debug position -->
    <jdoc:include type="modules" name="debug" style="none" />

</body>
</html>

Очередной раз собираем zip-дистрибутив шаблона и обновляем его в системе. Установка добавит в структуру CMS каталоги для медиа-файлов и запишет в них новые картинки. После обновления страницы, должны появиться картинки favicon.
Других изменений во внешнем виде быть не должно,