Joomla 4 Templating. Part 3: Web Asset Manager
In the previous article we looked at setting up the language folder for our installable simple
Joomla 4 template.
In this article, we look at the Web Asset Manager which is a new feature in Joomla 4. The Web Asset Manager can track your theme's assets installed to the media/site/templates
folder. It can be used to add dependencies and attributes to style and script tags. It will also append a cache-busting string (see in orange below) to your template's css and javascript files.
Joomla 3
<head> ... <link href="style.min.css" rel="stylesheet"> <script src="scripts.min.js"></script> ... </head>
Joomla 4
<head> ... <link href="style.min.css?42677341ba1dcc6427003a110610aac5" rel="stylesheet"> <script src="scripts.min.js?42677341ba1dcc6427003a110610aac5" defer></script> ... </head>
Find out more about the cache busting string
As of this writing, the cache busting string applied to your theme's js/css is not hashed based on the file contents, but on a variable called the Media Version. The Media Version doesn't update unless Joomla itself updates. So even if you change and resave your js/css files, you're bound to notice that the hash on your cache busting string doesn't change either.
This means that browsers are getting the old version (unless you do a hard refresh, in which case you'll get the new version, but the hash string stays the same). To force the hash to change go to Site-Clear Cache and do either of these two actions:
- Hit the
Delete All
button, or - Put a check into the checkbox beside
_media_version
and then hit Delete
Refresh the page and the cache busting strings will be changed.
Or you can add a version attribute to the asset itself in joomla.asset.json
Another way you can force a change in the hash string is to add the optional "version" attribute to the asset itself in joomla.asset.json (see below). Anytime you change this value it will be applied to the string.
"version":"1.2"
(Results in: style.css?1.2
)
Adding Assets to the Web Asset Manager
Since we are constructing the installable simple
template in this series of articles, any assets that we want tracked by the Web Asset Manager:
- Must be located in the
/media/templates/site/simple
folder - Must be registered to the Web Asset Manager
The Media Folder
In the first article in this Joomla 4 templating series, we constructed the template's manifest file (templateDetails.xml
) and instructed it to install the scss, css, js, and images folder into the /media/templates/site/simple
folder. We did this so that we could use the Web Asset Manager for the css and js files.
You might then ask - so why put the images, or even a fonts folder in there as well?
Firstly, for ease of referencing from the css file itself. Secondly, you'll likely be making use of Joomla's HTMLHelper
functions which have a flag that you can set to true so that it will search for assets (including images, favicons etc) in the /media/templates/site
folder. You don't even need to include a file path. In other words, we're not looking for Web Asset Manager functionality for the images, but more for ease of use and referencing.
Example: favicon stored in /media/templates/site/simple/images
//Add favicon to head section
//true means search for it in media folder
//and prioritise results from our theme if present
$this->addHeadLink(HTMLHelper::_('image', 'favicon.png', '', [], true, 1), 'icon', 'rel', ['type' => 'image/png']);
Registering Assets
The simplest way to register assets with the Web Asset Manager is to include them in the template's joomla.asset.json
file. Once they're included in this file, they are already registered. Once they're registered, all you have to do is to use them. The Web Asset Manager works like this:
- Is this asset registered?
- Yes? Have I been told to use it?
- Yes? OK let's go!
The real code might look something like this in the head section of your index.php templating file:
//provides access to the Web Asset Manager use Joomla\CMS\HTML\HTMLHelper; //get a Web Asset Manager object $wa = $this->getWebAssetManager(); //anything in joomla.asset.json is now REGISTERED automatically //no need for $wa->registerStyle('some.style') etc //but we must still tell wa to USE our style/script $wa->useStyle('some.style')->useScript('some.script');
joomla.asset.json
In the template we are constructing, this file is stored in /templates/simple
folder, NOT the /media/templates/site/simple
folder.
One of the neat things about joomla.asset.json
is that we can also specify dependencies and attributes for each file listed in it:
- Dependencies - don't load this file until you've loaded that one
- Attributes - eg defer, lazy, cross-origin, integrity and so on
Good to Know
- Each asset in joomla.asset.json is also given a name - anything you like. You use this name when you want to register/use an asset with the Web Asset Manager.
- You don't need to use a file path. The Web Asset Manager uses joomla.asset.json to track our
simple
template files in the/media/templates/site/simple
folder. It knows where to find stuff. - Web Asset Manager will prefer the minified file to the unminified file. If you add
style.css
to joomla.asset.json, the Web Asset Manager will usestyle.min.css
if it's present instead. Same for javascripts. This is very useful while developing.
Simple Theme's joomla.asset.json
In our simple
template we will use joomla.asset.json to register 3 assets to the Web Asset Manager:
- style.css
- Bootstrap's javascript (from their CDN) - an external script. Note we add the attributes as recommended by Bootstrap
- template.js which has a dependency on Bootstrap's js and must be loaded after it
joomla.asset.json
{
"version": "4.0.0",
"description": "This file contains details of the assets used by simple, a Joomla 4 compatible site template.",
"license": "GPL-2.0-or-later",
"assets": [
{
"name": "template.style.simple",
"description": "The css file to be used for the site.",
"type": "style",
"uri": "style.css",
"version": "1.1"
},
{
"name": "bootstrapjs",
"description": "Bootstrap 5.2.2 js files including popper.",
"type": "script",
"uri": "https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js",
"attributes" : {
"defer": true,
"crossorigin":"anonymous",
"integrity":"sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3"
}
},
{
"name": "template.script.simple",
"description": "The file containing the javascript for this template.",
"type": "script",
"uri": "template.js",
"attributes" : {
"defer": true
},
"dependencies": [
"bootstrapjs"
]
}
]
}
Note: I have put a version number against the style file. This is optional for any of the assets in here. You can put in any string as a value against the version. One reason to add a version is that it allows you to control and change your own cache busting string. Find out more about the cache busting string.
What's Next?
In the next article in the series about Joomla 4 Templating, we'll look at setting up the main template file: index.php.