Joomla 4 templating is more powerful than Joomla 3. But it can be confusing at first because some template files will be stored in the /media/templates/site folder to make use of the Web Asset Manager. The Web Asset Manager tracks and locates files in the media folder, it can be used for adding file attributes and dependencies and it also applies a cache-busting string to those assets.

This article is the first in a series on Joomla 4 templating for developers. The purpose of these articles is to create and install a functional, but barebones J4 template called simple. Layout and styling won't be covered in this series. There will be a complete download available in the final article in this series.

Also, I won't be referring to the Cassiopeia template or using the native bootstrap, google fonts, etc that's built in to Joomla. If you would prefer to do it that way, then see this great article by Kevin's Guides instead.

We'll begin with the manifest file templateDetails.xml which provides the instructions to Joomla as to how to install the template.

The most common reason for failed template installs is basic errors in the templateDetails.xml file. XML is strictly typed, so check the code with an eagle eye!

The Manifest - templateDetails.xml

Since our template is named simple, we will:

  1. Create a folder tpl_simple
  2. Create the manifest file inside that folder: templateDetails.xml

Here are the contents of templateDetails.xml with some explanations to follow. The line numbers are for explanatory purposes, they shouldn't be included in the actual file itself.

1. <?xml version="1.0" encoding="utf-8"?>
2.  <extension type="template" client="site" method="upgrade">
3.  <name>simple</name>
4.  <version>1.0</version>
5.  <creationDate>01/01/2023</creationDate>
6.  <author>Me</author>
7.  <authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it.</authorEmail>
8.  <copyright>My Copyright Notice</copyright>
9.  <description>TPL_SIMPLE_XML_DESCRIPTION</description>
10. <inheritable>1</inheritable>
11.  <files>
12.   <filename>component.php</filename>
13.   <filename>error.php</filename>
14.   <filename>index.php</filename>
15.   <filename>templateDetails.xml</filename>
16.   <filename>joomla.asset.json</filename>
17.   <folder>html</folder>
18.   <folder>language</folder>
19.  </files>
20.  <media destination="templates/site/simple" folder="media">
21.   <folder>js</folder>
22.   <folder>css</folder>
23.   <folder>scss</folder>
24.   <folder>images</folder>
25.  </media>
26.  <languages folder="language">
27.   <language tag="en-GB">en-GB/tpl_simple.ini</language>
28.   <language tag="en-GB">en-GB/tpl_simple.sys.ini</language>
29.  </languages>
30.  <positions>
31.   <position>mainnav</position>
32.   <position>search</position>
33.   <position>banner</position>
34.   <position>breadcrumb</position>
35.   <position>frontleft</position>
36.   <position>frontright</position>
37.   <position>belowcontent</position>
38.   <position>abovefooter</position>
39.   <position>footer</position>
40.   <position>debug</position>
41.  </positions>
42.  <config>
43.   <fields name="params">
44.    <fieldset name="advanced">
45.     <field
46.      name="googlefonts"
47.      type="text"
48.      default=""
49.      label="TPL_SIMPLE_GOOGLEFONTS"
50.      filter="string"
51.     />
52.    </fieldset>
53.   </fields>
54.  </config>
55. </extension>
Lines 1-2

Same for every templateDetails.xml file

Line 3

Your template name, prefer lowercase

Line 4

The version number of your template. Here it's 1.0. The next iteration would be 1.1. To update, you would re-install the entire template with 1.1 as the next version number in the templateDetails.xml file.

Lines 5-8

Optional

Line 9

This is the template description. The placeholder is always in uppercase. It goes into both language files like this (use any description you want really):
TPL_SIMPLE_XML_DESCRIPTION="The Simple Template"

Line 10

inheritable and parent are 2 new tags with J4 templating. If you omit the parent tag and have inheritable as 1, then the template qualifies to be a parent since it is also inheritable, as we are doing here. On the other hand a child template must use the parent tag specifying who the parent template is.

Since simple is a stand-alone template that isn't intended to be a parent or a child template, we omit the parent tag, but find that we must still include inheritable with a value of 1, otherwise the required HTMLHelper functions won't be able to search for images, icons, fonts, assets in the media folder. Technically simple qualifies as a parent template, even though she has no intention of every having children!

Lines 11-19

Inside the <files> tag you will add all files and folders that will be installed into the /templates/simple folder (don't confuse this with the /media/templates/site/simple folder). 

  • component.php (file) - used for Joomla's print function and ?tmpl=component
  • error.php (file) - template for error pages
  • index.php (file) - this is the main templating file
  • templateDetails.xml (file) - the manifest (instructions) file we are working on here
  • joomla.asset.json (file) - instructions for the Web Asset Manager, includes a list of files in the media folder for tracking
  • html (folder) - used for override files of Joomla modules/layouts and plugins
  • language (folder) - see below and also the next article in the series

Notice that I also included the folder: language. This is because I like to keep the languages files inside my /templates/simple folder. This is different to the normal instruction which you can see in lines 26-29. I won't be using those lines. If you decide to use lines 26-29 then omit the language folder from the <files> tags. It's one or the other, not both! If you use lines 26-29, then your language files will get stored in the main Joomla languages folder as in:

  • /languages/en-GB/tpl_simple.ini
  • /languages/en-GB/ tpl_simple.sys.ini

In previous versions of Joomla that meant that your language files did not upgrade even if you upgraded your template. However if you keep the language files in your /templates/simple folder, they will upgrade perfectly on a re-install.

Lines 20-25

These are the files and folders that are going to be put into the /media/templates/site/simple folder. They are put here so we can use the Web Asset Manager to track them and/or add a cache busting strings. Any file in here will be tracked, but only the ones listed in the /templates/simple/joomla.asset.json will be given a cache-busting string in it's url. More on that when we take a look at the joomla.asset.json file in a later article.

You could also put a fonts folder here, if you're locally hosting font files like .woff, .woff2 and so on. I won't be doing that as I'm downloading from Google instead. The folders I'm including here are:

  • images (folder) - images for the template
  • js (folder) - javascript for the template
  • css (folder) - stylesheets for the template
  • scss (folder) - d/l bootstrap scss source files from github and put them here. I'll use dartsass to compile the scss into css for final production. You could also use tailwind or whatever css library you want

Re: images folder - as well as storing your template's svg/png/jpg/webp/etc files, you can also put these two J3 files: template_preview.png and template_thumbnail.png. This is optional, it just gives a template preview in the backend (System - Site Templates). It's also recommended that you include your favicon file(s) in here because you can use Joomla's HTMLHelper methods to access them from here also.

Lines 30-41

These are your template positions. Use as many as you like, and name them whatever you like. You'll use these to position modules inside your index.php template file. So if you create a Search module, you might want to add a position like this: 

<position>search</position>

Later on we can use that position to place the search module exactly where we want it in the index.php template like this:

<?php if ($this->countModules('search', true)) : ?>
  <div class="someclass"> 
   <jdoc:include type="modules" name="search" style="none" />
  </div>
<?php endif; ?>
Lines 42-54

These are for your configs which appear as configurable template options in the Joomla backend (System - Site Template Styles - Simple, choose Advanced tab). If you don't have configs, you can omit it, or just use <config/>

Note the language string on line 49. The label refers to a language placeholder TPL_SIMPLE_GOOGLEFONTS that needs to go into your language file. So you'd enter something like this into your tpl_simple.ini file:

TPL_SIMPLE_GOOGLEFONTS="Please enter the url for your chosen google fonts"

Configure Template Options
Configurable Template Options

The user could then paste their chosen fonts like:

https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@200&family=Roboto:wght@200;300&display=swap

We will later extract that string into our templating files (index.php, error.php and component.php) and put in the necessary code to have the fonts imported.

Installable Template

This article has dealt with setting up the manifest file: templateDetails.xml. In order for the simple template to be installable we'll prepare the file structure as follows:

tpl_simple (folder)
  templateDetails.xml
  joomla.asset.json
  index.php
  component.php
  error.php
  html (folder)
  language (folder)
    en-GB (folder)
      tpl_simple.ini
      tpl_simple.sys.ini
   media (folder)
    css (folder)
      style.css
      style.min.css
      error.css
      error.min.css
    js (folder)
      template.js
      template.min.js
    scss (folder)
    images (folder)

What's Next?

Next in the series, we'll deal with how to set up the language folder for the installable template.