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:

  1. Hit the Delete All button, or
  2. 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:

  1. Must be located in the /media/templates/site/simple folder
  2. 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:

  1. Is this asset registered?
  2. Yes? Have I been told to use it?
  3. 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 use style.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.