Joomla Creating a Child Template — Template Inheritance and Customization
In this tutorial, you'll learn how to create a Joomla child template — using templateDetails.xml for inheritance, overriding index.php and CSS, adding custom module positions, and building a complete child template based on Cassiopeia.
What You'll Learn
- What a child template is and when to use it
- Template inheritance in Joomla 4+ vs Joomla 3
- How to create the child template folder structure
- How to write templateDetails.xml with the inherit element
- How to add custom module positions in a child template
- How to override index.php to modify the HTML structure
- How to use CSS overrides with user.css
- How child-specific template styles work with inheritance
- How to make the child template the default
- How to override component and module layouts in a child
- Best practices for child templates
Why It Matters
Template overrides handle most customization needs, but sometimes you need to add new module positions, change the core HTML structure, or modify the template's grid system. A child template lets you do all of this while still inheriting everything from the parent template. When the parent template (Cassiopeia) is updated, your child template still gets those updates — you only maintain the files you explicitly overrode.
Real-World Use
A news website uses Cassiopeia but needs a "breaking news ticker" at the very top of every page, above the header. Cassiopeia does not have a module position there. The developer creates a child template that inherits from Cassiopeia, adds a new position called "top-bar" in templateDetails.xml, inserts the position in index.php above the header, and assigns a custom HTML module with the ticker content. The rest of the template remains identical to Cassiopeia.
Learning Path
flowchart LR A["Template Overrides"] --> B["Creating a Child Template
You are here"]:::current B --> C["CSS & User.css"] classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px
What Is a Child Template?
A child template is a template that inherits everything from a parent template. You create a child template when you need to:
- Add new module positions that the parent does not define
- Change the HTML structure in index.php (different header layout, different grid)
- Add custom CSS or JavaScript that must load before the parent styles
- Create a site-specific template that still receives parent template updates
The child template contains only the files that differ from the parent. Everything else comes from the parent automatically.
Joomla 4+ vs Joomla 3
In Joomla 3, template inheritance worked through subtemplates using $this->subtemplate. The Isis and Hathor templates served as base themes.
In Joomla 4+, template inheritance uses a dedicated <inherit> element in templateDetails.xml. This is cleaner and more explicit.
<!-- Joomla 4+ child template inheritance -->
<inherit>
<template>cassiopeia</template>
</inherit>
Creating the Child Template Structure
First, create a folder for your child template. The folder name becomes the template name internally.
# Create the child template folder structure
mkdir -p templates/my_cassiopeia/css
mkdir -p templates/my_cassiopeia/js
mkdir -p templates/my_cassiopeia/images
mkdir -p templates/my_cassiopeia/html
mkdir -p templates/my_cassiopeia/language/en-GB
Your child template needs at minimum:
templates/my_cassiopeia/
├── templateDetails.xml # Required — defines inheritance
├── css/
│ └── user.css # Optional — custom styles
└── language/
└── en-GB/
└── tpl_my_cassiopeia.ini # Optional — language strings
Writing templateDetails.xml for Inheritance
The most important file is templateDetails.xml. This tells Joomla that your template is a child of Cassiopeia.
<?xml version="1.0" encoding="utf-8"?>
<extension version="4.0" type="template" client="site">
<name>my_cassiopeia</name>
<version>1.0.0</version>
<creationDate>2026-06-27</creationDate>
<author>Your Name</author>
<authorEmail>you@example.com</authorEmail>
<copyright>Your Company</copyright>
<description>My custom child template based on Cassiopeia</description>
<inherit>
<template>cassiopeia</template>
</inherit>
<positions>
<position>top-bar</position>
<position>sidebar-custom</position>
</positions>
<files>
<filename>templateDetails.xml</filename>
<folder>css</folder>
<folder>images</folder>
<folder>language</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/tpl_my_cassiopeia.ini</language>
</languages>
</extension>
Key points about this XML:
<inherit><template>cassiopeia</template></inherit>tells Joomla to inherit from Cassiopeia<positions>defines additional positions beyond what Cassiopeia provides<files>lists only the files in your child template, not inherited files- The template folder name must match the
<name>element
If you do not include any custom positions, you can omit the <positions> element entirely. Joomla will use all positions from the parent.
Adding Custom Module Positions
The positions you define in the child template are added to the parent's positions. If a position has the same name as a parent position, your child definition overrides it.
In the example above, we added two new positions:
- top-bar: For a breaking news ticker or announcement bar
- sidebar-custom: For sidebar content that appears in a different location
To use these positions in a module, go to Extensions > Modules, edit a module, and select the new position from the dropdown. The position appears alongside Cassiopeia's default positions.
<!-- In templateDetails.xml, add positions like this -->
<positions>
<position>top-bar</position>
<position>sidebar-custom</position>
</positions>
Overriding index.php
If you need to change the HTML structure, copy Cassiopeia's index.php to your child template and modify it.
# Copy Cassiopeia's index.php to your child template
cp templates/cassiopeia/index.php templates/my_cassiopeia/index.php
Now edit the copy to add your custom module positions:
<?php
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Uri\Uri;
$app = Factory::getApplication();
$template = $app->getTemplate();
$params = $app->getTemplateParams();
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
<jdoc:include type="head" />
<link href="<?php echo Uri::root(); ?>templates/<?php echo $template; ?>/css/user.css" rel="stylesheet">
</head>
<body>
<!-- New top-bar position added by child template -->
<jdoc:include type="modules" name="top-bar" style="none" />
<!-- Original Cassiopeia header -->
<header>
<jdoc:include type="modules" name="menu" />
</header>
<main>
<jdoc:include type="message" />
<div class="container">
<div class="row">
<div class="col-md-8">
<jdoc:include type="component" />
</div>
<aside class="col-md-4">
<!-- Custom sidebar position -->
<jdoc:include type="modules" name="sidebar-custom" style="card" />
</aside>
</div>
</div>
</main>
<footer>
<jdoc:include type="modules" name="footer" />
</footer>
</body>
</html>
The <jdoc:include type="modules" name="top-bar" /> tag renders all modules assigned to the "top-bar" position. The style parameter controls the module chrome used to wrap the module output.
CSS Overrides
Your child template can have its own user.css file. Joomla loads it automatically if it exists at templates/my_cassiopeia/css/user.css.
/* templates/my_cassiopeia/css/user.css */
/* Override Cassiopeia defaults */
.top-bar {
background-color: #ffcc00;
padding: 8px 0;
text-align: center;
font-weight: bold;
}
.top-bar a {
color: #000;
text-decoration: none;
}
.sidebar-custom .card {
border: none;
border-radius: 0;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
Cassiopeia loads its own stylesheet first, then user.css. Because user.css loads after, your rules override the defaults — as long as your CSS specificity is equal to or higher than the original.
Template Styles in a Child Template
Your child template inherits the style options from Cassiopeia. When you create a style for your child template, you see the same tabs and options as Cassiopeia — Brand, Color, Font, Layout, Header, Menu, Background.
To make a child template style the default:
- Go to Extensions > Templates > Styles
- You see your child template listed with a style "my_cassiopeia — Default"
- Click the star icon to make it the default style
You can create multiple styles for your child template, just like with Cassiopeia.
Overriding Component and Module Layouts in a Child
Override files in a child template work exactly the same as in a regular template. The files go in the html folder:
templates/my_cassiopeia/html/
├── com_content/
│ └── article/
│ └── default.php
├── mod_menu/
│ └── default.php
└── layouts/
└── joomla/
└── pagination/
└── links.php
Joomla checks the active template (your child template) for overrides before falling back to the component default. Since your child inherits from Cassiopeia, if you do not have an override in your child, Joomla checks Cassiopeia's html folder, then falls back to the component.
flowchart TD
A["Joomla looks for layout"] --> B{"Override in child
template?"}
B -->|Yes| C["Use child template override"]
B -->|No| D{"Override in parent
(Cassiopeia)?"}
D -->|Yes| E["Use Cassiopeia override"]
D -->|No| F["Use component default"]
C --> G["Render"]
E --> G
F --> G
Packaging and Installing a Child Template
To install your child template on another site, package it as a zip file:
# Create a distributable zip of your child template
cd templates
zip -r my_cassiopeia.zip my_cassiopeia/
The zip file structure should be:
my_cassiopeia.zip
└── my_cassiopeia/
├── templateDetails.xml
├── index.php # optional
├── css/
│ └── user.css # optional
└── language/
└── en-GB/
└── tpl_my_cassiopeia.ini # optional
Install it via Extensions > Manage > Install > Upload Package File.
When to Use a Child Template vs Overrides
| Situation | Best Approach |
|---|---|
| Change layout of a single component view | Template override |
| Change module output | Module override |
| Add a new module position | Child template |
| Change the HTML structure (index.php) | Child template |
| Add custom CSS | Both (user.css works in both) |
| Multiple sites with shared customizations | Child template |
| One-time layout tweak | Template override |
The rule of thumb: start with overrides. Only create a child template when you need new positions or structure changes.
Best Practices
- Keep child templates minimal — only override what you need
- Document every change in a comment or readme file within the child template folder
- Test the child template after every parent template update
- Use descriptive names for custom module positions
- Do not include files that are identical to the parent — they are unnecessary and create maintenance overhead
- If you override index.php, regularly diff it against the Cassiopeia version to catch upstream changes
Common Mistakes
Creating a child template when overrides would suffice: Beginners create child templates for simple layout changes that overrides handle better. Overrides are simpler and easier to maintain.
Missing the inherit element in templateDetails.xml: Without
<inherit><template>cassiopeia</template></inherit>, Joomla treats your template as a standalone template and does not inherit anything.Copying all Cassiopeia files into the child: The whole point of a child template is to only include files you changed. Copying everything defeats the purpose and creates maintenance work.
Forgetting to set the child style as default: After installing and creating a style for your child template, you must make it the default style. Otherwise, the site still uses Cassiopeia.
Using wrong position names in index.php: You add a position called "top-bar" in templateDetails.xml but use "topbar" in index.php. Modules assigned to "top-bar" never appear. The name must match exactly in both places.
Practice Questions
What is the minimum set of files a child template needs? Answer: The minimum is templateDetails.xml with the
<inherit>element. You can optionally add index.php, css/user.css, html/ overrides, and language files. Everything else is inherited from the parent.How do you add a new module position in a child template? Answer: Add the position name in the
<positions>element of templateDetails.xml. Then add a<jdoc:include type="modules" name="position-name" />tag in index.php at the location where modules should render.What happens to a child template when Cassiopeia is updated? Answer: The child template still works and receives the updated CSS, JavaScript, and inherited features from Cassiopeia. Only the files explicitly overridden in the child template remain unchanged. You should review overridden files after major updates.
Challenge: Create a child template called "my_news" based on Cassiopeia. Add three custom module positions: "announcement" (full-width bar above header), "sidebar-top" (above the main sidebar), and "post-footer" (below the main content). Assign a different background color to the header through user.css. Create an article list override that includes publication date and category. Make it the default template for your site.
FAQ
Mini Project
Your task: Build a complete child template for a corporate intranet portal.
- Create the folder structure for a child template named "corporate_intranet".
- Write templateDetails.xml that inherits from Cassiopeia.
- Add these custom module positions: "global-alert" (full-width banner for company announcements), "quick-links" (icon grid below header), "department-info" (sidebar section).
- Copy and modify index.php to render the positions in the correct order.
- Create user.css with styles for each custom position.
- Override com_content article layout to show a "department" custom field prominently.
- Install the template, create a style, and make it default.
- Create modules and assign them to your new positions.
- Verify everything displays correctly on the frontend.
This project mirrors a real request — intranet portals often need unique layout elements that do not fit standard template designs.
What's Next
Now that you can create child templates, you are ready to fine-tune your site's visual design:
Continue to Lesson 19: CSS and User.css — Learn how to write custom CSS, use body classes for page-specific styling, and implement Responsive Design with Bootstrap 5.
Related lessons:
- Joomla Template Basics — Understand the template folder structure
- Joomla Template Overrides — Customize component and module layouts
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro