Перейти до основного вмісту

Web Asset Manager у Joomla 6: підключення CSS і JavaScript через joomla.asset.json

Як працює Web Asset Manager

У Joomla ресурс проходить два основні стани: registered і used. Після реєстрації Web Asset Manager знає про CSS або JavaScript-файл, але ще не додає його до HTML-документа. Ресурс потрапляє на сторінку тільки після його активації через useStyle(), useScript(), usePreset() або один із методів registerAndUse*().

Це важлива відмінність від прямого підключення файлів: опис ресурсу та фактичне його використання розділені.

Загальна схема виглядає так:

  • CSS і JavaScript розміщуються в media-каталозі розширення або шаблону;
  • ресурси описуються в joomla.asset.json або реєструються через PHP;
  • Web Asset Manager додає їх до реєстру WebAssetRegistry;
  • код розширення активує потрібний ресурс за його ім'ям;
  • Joomla визначає залежності та формує відповідні <link> і <script>.

Головна перевага Web Asset Manager — код розширення працює не безпосередньо з файлами, а з іменованими ресурсами. Joomla може враховувати їхні залежності, не підключати один і той самий ресурс повторно та правильно визначати порядок завантаження.

Як отримати WebAssetManager

Web Asset Manager належить поточному об'єкту документа Joomla. Якщо код уже працює в контексті документа, наприклад у шаблоні, його можна отримати безпосередньо:

$wa = $this->getWebAssetManager();

В іншому коді розширення документ можна отримати через застосунок:

use Joomla\CMS\Factory;

$document = Factory::getApplication()->getDocument();
$wa = $document->getWebAssetManager();

Змінна $wa у наступних прикладах містить екземпляр Joomla\CMS\WebAsset\WebAssetManager.

Файл joomla.asset.json

Для розширень із кількома CSS і JavaScript-файлами Joomla рекомендує описувати ресурси декларативно у файлі joomla.asset.json. У ньому можна вказати URI файлів, залежності, HTML-атрибути та інші параметри ресурсів.

Для компонента файл зазвичай розміщується тут:

media/com_example/joomla.asset.json

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

media/com_example/
├── css/
│   └── site.css
├── js/
│   └── site.js
└── joomla.asset.json

Приклад joomla.asset.json:

{
    "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
    "name": "com_example",
    "version": "1.0.0",
    "description": "Web assets for com_example",
    "license": "GPL-2.0-or-later",
    "assets": [
        {
            "name": "com_example.site",
            "type": "style",
            "uri": "com_example/site.css"
        },
        {
            "name": "com_example.site",
            "type": "script",
            "uri": "com_example/site.js",
            "dependencies": [
                "core"
            ],
            "attributes": {
                "defer": true
            }
        }
    ]
}

CSS і JavaScript можуть мати однакове ім'я, оскільки це ресурси різних типів. У прикладі вище існують окремі style і script з ім'ям com_example.site.

Основні поля ресурсу
Поле Призначення
name Унікальне ім'я ресурсу в межах його типу. Саме це ім'я передається в useStyle() або useScript().
type Тип ресурсу: зазвичай style, script або preset.
uri Шлях до CSS або JavaScript-файлу.
dependencies Імена ресурсів, які необхідно активувати разом із поточним ресурсом.
attributes Атрибути майбутнього HTML-елемента, наприклад defer, async або type="module".
Як Joomla визначає шлях до CSS і JavaScript

URI ресурсу в joomla.asset.json не обов'язково збігається з фізичним шляхом до файлу.

Якщо JavaScript фізично знаходиться тут:

media/com_example/js/site.js

у визначенні ресурсу використовується:

"uri": "com_example/site.js"

Для CSS:

media/com_example/css/site.css

визначення буде таким:

"uri": "com_example/site.css"

Web Asset Manager визначає каталог js або css за типом ресурсу.

Не копіюйте механічно шляхи на зразок media/com_example/js/site.js у поле uri. Для ресурсів у стандартній структурі Joomla використовується логічний URI на кшталт com_example/site.js.

Підключення зареєстрованих ресурсів

Ресурс із joomla.asset.json ще не означає, що файл буде завантажений на кожній сторінці. Його потрібно активувати.

CSS підключається через useStyle():

$wa->useStyle('com_example.site');

JavaScript — через useScript():

$wa->useScript('com_example.site');

Методи підтримують ланцюжок викликів:

$wa
    ->useStyle('com_example.site')
    ->useScript('com_example.site');

Таким способом можна завантажувати ресурси лише в тому layout або view, де вони дійсно потрібні.

Наявність ресурсу в joomla.asset.json означає його реєстрацію, а не автоматичне підключення. Це дозволяє одному файлу описувати всі ресурси розширення, не завантажуючи їх одночасно.

Залежності між ресурсами

Поле dependencies описує інші ресурси, без яких поточний CSS або JavaScript не може працювати.

Наприклад:

{
    "name": "com_example.form",
    "type": "script",
    "uri": "com_example/form.js",
    "dependencies": [
        "core",
        "form.validate"
    ]
}

Після виклику:

$wa->useScript('com_example.form');

Joomla активує не тільки com_example.form, а й потрібні йому залежності. Web Asset Manager також враховує порядок залежностей під час формування HTML.

Це дозволяє не дублювати в PHP-коді послідовність підключення бібліотек.

Не додавайте залежність від Joomla-ресурсу лише за припущенням. Назви на кшталт core, jquery або form.validate повинні відповідати реально зареєстрованим ресурсам поточної версії Joomla.

Атрибути script і link

Через attributes можна передавати атрибути, які Joomla додасть до відповідного HTML-елемента.

Наприклад, JavaScript із defer:

{
    "name": "com_example.site",
    "type": "script",
    "uri": "com_example/site.js",
    "attributes": {
        "defer": true
    }
}

Для JavaScript-модуля можна вказати:

{
    "name": "com_example.module",
    "type": "script",
    "uri": "com_example/module.js",
    "attributes": {
        "type": "module"
    }
}

Атрибути не потрібно формувати вручну через HTML — цим займається Web Asset Manager.

Реєстрація ресурсів без joomla.asset.json

Файл joomla.asset.json є рекомендованим способом опису набору ресурсів розширення, але Web Asset Manager може працювати і без нього.

CSS можна зареєструвати безпосередньо через PHP:

$wa->registerStyle(
    'com_example.custom',
    'com_example/custom.css'
);

Після цього ресурс активується окремо:

$wa->useStyle('com_example.custom');

Або обидві операції можна виконати одним викликом:

$wa->registerAndUseStyle(
    'com_example.custom',
    'com_example/custom.css'
);

Аналогічні методи є для JavaScript:

$wa->registerAndUseScript(
    'com_example.custom',
    'com_example/custom.js',
    [],
    ['defer' => true],
    ['core']
);

Останні два масиви задають відповідно HTML-атрибути та залежності ресурсу.

Коли використовувати PHP, а коли joomla.asset.json

Якщо CSS або JavaScript є постійною частиною розширення, їх краще описати в joomla.asset.json. Це відокремлює конфігурацію ресурсів від логіки PHP та спрощує керування залежностями.

Програмна реєстрація корисна, коли ресурс формується динамічно, його URI залежить від умов або потрібно підключити невеликий ресурс тільки в конкретному контексті.

Коли Joomla автоматично читає joomla.asset.json

Joomla автоматично завантажує кілька стандартних реєстрів ресурсів. Серед них:

  • media/vendor/joomla.asset.json;
  • media/system/joomla.asset.json;
  • media/legacy/joomla.asset.json;
  • media/{active_component}/joomla.asset.json;
  • templates/{active_template}/joomla.asset.json.

Це означає, що для активного компонента файл із media/com_example/joomla.asset.json зазвичай потрапляє до реєстру автоматично.

Для інших випадків, зокрема коли власний joomla.asset.json не входить до стандартного автоматичного завантаження, його можна додати до реєстру вручну:

$registry = $wa->getRegistry();

$registry->addRegistryFile(
    'relative/path/to/joomla.asset.json'
);

Не слід виходити з припущення, що будь-який файл із назвою joomla.asset.json Joomla знайде автоматично. Автоматичне завантаження залежить від типу та контексту розширення.

Preset: групування CSS і JavaScript

Тип preset дозволяє об'єднати кілька ресурсів і активувати їх одним викликом.

Наприклад:

{
    "name": "com_example.bundle",
    "type": "preset",
    "uri": "",
    "dependencies": [
        "com_example.site#style",
        "com_example.site#script"
    ]
}

Тепер обидва ресурси можна активувати так:

$wa->usePreset('com_example.bundle');

Для залежностей preset після символу # вказується тип ресурсу: #style, #script або інший preset.

Preset зручний, якщо функціональність складається з кількох CSS і JavaScript-ресурсів, які майже завжди використовуються разом.

Вимкнення ресурсів

Активований ресурс можна вимкнути:

$wa->disableStyle('com_example.site');
$wa->disableScript('com_example.site');

Однак вимкнення не гарантує, що ресурс остаточно зникне зі сторінки. Якщо інший активний ресурс залежить від нього, Web Asset Manager може знову активувати цю залежність.

Тому disableScript() і disableStyle() не слід використовувати як спосіб безумовно видалити бібліотеку, не перевіривши граф залежностей.

Перевірка наявності та стану ресурсу

Перед роботою з ресурсом можна перевірити, чи зареєстрований він у Web Asset Registry:

if ($wa->assetExists('script', 'com_example.site')) {
    $wa->useScript('com_example.site');
}

Для перевірки того, чи ресурс уже активний:

if ($wa->isAssetActive('script', 'com_example.site')) {
    // The asset is already active.
}

Ці методи корисні насамперед у коді, який взаємодіє з ресурсами інших розширень або повинен працювати в різних контекстах.

Як називати власні ресурси

Ім'я ресурсу є ключем у Web Asset Registry. Тому короткі глобальні назви на кшталт main, style або script створюють непотрібний ризик конфліктів.

Для власного компонента краще використовувати простір імен у назві:

com_example.site
com_example.admin
com_example.form
com_example.product

Для шаблону можна використовувати аналогічну схему:

template.mytemplate
template.mytemplate.navigation

Якщо під час завантаження Joomla зустріне нове визначення ресурсу з тим самим ім'ям і типом, попереднє визначення може бути перевизначене. Тому унікальні та передбачувані імена особливо важливі для сторонніх розширень.

Для більшості компонентів Joomla 6 достатньо наступної структури:

media/com_example/
├── css/
│   └── site.css
├── js/
│   └── site.js
└── joomla.asset.json

joomla.asset.json:

{
    "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
    "name": "com_example",
    "version": "1.0.0",
    "description": "Assets for com_example",
    "license": "GPL-2.0-or-later",
    "assets": [
        {
            "name": "com_example.site",
            "type": "style",
            "uri": "com_example/site.css"
        },
        {
            "name": "com_example.site",
            "type": "script",
            "uri": "com_example/site.js",
            "dependencies": [
                "core"
            ],
            "attributes": {
                "defer": true
            }
        }
    ]
}

У layout або view, де потрібні ці ресурси:

$wa = $this->getDocument()->getWebAssetManager();

$wa
    ->useStyle('com_example.site')
    ->useScript('com_example.site');

У результаті конфігурація ресурсів залишається в joomla.asset.json, а PHP-код лише повідомляє Joomla, яка функціональність потрібна на поточній сторінці.

Типові помилки
  • ресурс доданий до joomla.asset.json, але useStyle() або useScript() ніде не викликається;
  • вказаний неправильний uri, наприклад разом із зайвим каталогом js або css;
  • у dependencies використовується ім'я неіснуючого ресурсу;
  • код викликає useScript() для ресурсу, який ще не потрапив до реєстру;
  • для власних ресурсів використовуються занадто загальні імена, що можуть конфліктувати з іншими розширеннями;
  • розробник очікує, що Joomla автоматично прочитає joomla.asset.json з довільного каталогу;
  • CSS або JavaScript підключається вручну через HTML там, де достатньо Web Asset Manager.

Якщо useScript() або useStyle() викликається для незареєстрованого ресурсу, Web Asset Manager може згенерувати UnknownAssetException. При налагодженні спочатку перевірте, чи файл joomla.asset.json був завантажений і чи правильно вказане ім'я ресурсу.

Що використовувати в Joomla 6

Для CSS і JavaScript, які є частиною розширення, основним підходом варто вважати joomla.asset.json у поєднанні з useStyle() та useScript(). Це дає Joomla інформацію не тільки про сам файл, а й про його залежності та атрибути.

Методи registerStyle(), registerScript() і registerAndUse*() залишаються повноцінною частиною API Joomla 6 та підходять для ресурсів, які доцільніше визначити безпосередньо під час виконання.

Головний принцип простий: спочатку ресурс має бути зареєстрований, а потім — активований. Саме на цьому побудована робота Web Asset Manager.

Використані джерела:
Joomla! Programmers Documentation — Web Asset Manager
Joomla! CMS 6.0 API — WebAssetManager
Joomla! CMS 6.0 API — WebAssetItem
Kevin's Guides — Using Joomla's Web Asset Manager

Зв'язатися зі мною

Залиште свої контакти, і я зв'яжуся з вами найближчим часом.