Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

A site template

A template is an extension that defines the overall page markup: where the header is, where the main content goes, where the column with modules sits. The component and the modules output only their own fragments, and the template assembles a whole HTML page from them.

Where it lives

Site templates are stored in the templates folder, panel templates in administrator/templates. Create a minimal template by hand:

templates/mytheme/
├── templateDetails.xml          the manifest
├── index.php                    the page markup
└── html/                        layout overrides
 
media/templates/site/mytheme/
└── css/
    └── template.css             styles

The manifest

<?xml version="1.0" encoding="UTF-8"?>
<!-- templates/mytheme/templateDetails.xml -->
<extension type="template" client="site" method="upgrade">
    <name>mytheme</name>
    <version>1.0.0</version>
    <description>A learning template</description>
 
    <files>
        <filename>index.php</filename>
        <filename>templateDetails.xml</filename>
        <folder>html</folder>
    </files>
 
    <media destination="templates/site/mytheme" folder="media">
        <folder>css</folder>
    </media>
 
    <positions>
        <position>menu</position>
        <position>sidebar</position>
        <position>footer</position>
    </positions>
</extension>

The positions section lists the positions: these are the names the administrator sees in the Position list when configuring a module.

The index.php file

<?php
// templates/mytheme/index.php
 
defined('_JEXEC') or die;
 
$this->getWebAssetManager()->registerAndUseStyle('template.mytheme', 'template.css');
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <jdoc:include type="metas" />
    <jdoc:include type="styles" />
    <jdoc:include type="scripts" />
</head>
<body>
    <header>
        <jdoc:include type="modules" name="menu" style="none" />
    </header>
 
    <main>
        <jdoc:include type="message" />
        <jdoc:include type="component" />
    </main>
 
    <?php if ($this->countModules('sidebar')) : ?>
        <aside>
            <jdoc:include type="modules" name="sidebar" style="html5" />
        </aside>
    <?php endif; ?>
 
    <footer>
        <jdoc:include type="modules" name="footer" style="none" />
    </footer>
</body>
</html>

In a template $this is the document object. The jdoc:include tags are the places where Joomla inserts ready parts of the page.

The jdoc:include tags

TagWhat it inserts
type="metas"The page title and meta tags
type="styles", type="scripts"Styles and scripts from the asset manager
type="component"The component output — the main content
type="message"System messages such as "Item saved"
type="modules" name="sidebar"All modules of the sidebar position

The style attribute picks the module wrapper: none prints the module as is, html5 adds a block with the module title. The countModules() method returns the number of modules in a position — this way an empty column is not printed at all.

Styles

/* media/templates/site/mytheme/css/template.css */
body {
    max-width: 960px;
    margin: 0 auto;
    font-family: sans-serif;
}

Joomla looks for the bare name template.css in the css folder of the active template inside media/templates/site.

Installing and seeing the result

  1. System → Install → Discover → install mytheme.
  2. System → Site Template Styles → tick mytheme and press Default.
  3. Give the mod_hello module the sidebar position and the main menu module the menu position.

Open the site: the Cassiopeia look is gone and the page is built from your markup — the menu on top, the content, the greeting block in the column.

A child template

Writing a template from scratch is rarely needed. More often you take a ready one and change a few files in it. Child templates exist for that: System → Site Templates → Cassiopeia, the Create Child Template button. Joomla creates a folder such as templates/cassiopeia_mychild whose manifest names the parent in the parent tag. A child template takes every file from its parent except those it contains itself: that is where you put your own styles and layout overrides from the html folder. Updating Cassiopeia does not touch them.

Common mistake

The jdoc:include type="message" tag is forgotten in index.php. The site works, but messages — "Wrong password", "Form submitted" — never appear, and the visitor does not understand what happened. This tag is mandatory in every template.

Thanks for reading!

Donate to the site — we work hard for you.