Loading...
Loading...
Master the template overrides system in Joomla 5/6. Customize component views (com_content, articles, categories), modules, plugins, create alternative layouts, use JLayout for reusable components, implement child templates and field overrides. Includes complete examples of blog_item.php, article/default.php, mod_login, layout alternatives, best practices and troubleshooting.
npx skill4agent add nicolasflores9/skills joomla-template-overrides/templates/[name]/html//templates/[active]/html/[path]/[component]/views/[view]/tmpl//templates/cassiopeia/html/
├── com_content/ # Components (com_)
│ ├── article/
│ │ └── default.php
│ └── category/
│ ├── blog.php
│ ├── blog_item.php
│ └── default.php
├── mod_login/ # Modules (mod_)
│ ├── default.php
│ └── slim.php
├── plg_content_pagenavigation/ # Plugins (plg_)
│ └── default.php
└── layouts/ # Reusable JLayouts
└── joomla/
└── content/
├── intro_image.php
└── info_block.phpcom_[component]mod_[module]plg_[group]_[plugin]/components/com_content/views/article/tmpl/default.php/templates/cassiopeia/html/com_content/article/default.php$this->item$this->params$this->item->jcfields<?php defined('_JEXEC') or die; ?>
<article class="article-container">
<header class="article-header">
<h1><?php echo htmlspecialchars($this->item->title); ?></h1>
</header>
<section class="article-body">
<?php if (!empty($this->item->images)): ?>
<?php echo JLayoutHelper::render('joomla.content.intro_image',
['item' => $this->item]); ?>
<?php endif; ?>
<?php echo $this->item->text; ?>
</section>
<?php if (!empty($this->item->jcfields)): ?>
<section class="article-custom-fields">
<?php foreach ($this->item->jcfields as $field): ?>
<div class="field-<?php echo htmlspecialchars($field->type); ?>">
<strong><?php echo htmlspecialchars($field->label); ?></strong>
<?php echo $field->rawvalue; ?>
</div>
<?php endforeach; ?>
</section>
<?php endif; ?>
</article>/templates/cassiopeia/html/com_content/category/blog_item.php<?php defined('_JEXEC') or die;
$item = $this->item; ?>
<article class="blog-item">
<h2 class="item-title">
<?php echo JHtml::_('link', JRoute::_($item->link),
htmlspecialchars($item->title)); ?>
</h2>
<?php if (!empty($item->images)): ?>
<?php echo JLayoutHelper::render('joomla.content.intro_image',
['item' => $item]); ?>
<?php endif; ?>
<div class="item-content">
<?php echo $item->introtext; ?>
</div>
<a href="<?php echo JRoute::_($item->link); ?>" class="read-more">
Read more
</a>
</article>/templates/cassiopeia/html/com_content/category/default.php/templates/[template]/html/mod_[module]/[layout].phpmod_loginmod_menumod_custommod_articles_latestmod_breadcrumbs/templates/cassiopeia/html/mod_login/default.php<?php defined('_JEXEC') or die;
$params = $this->params; ?>
<form action="<?php echo JRoute::_('index.php'); ?>" method="post" class="login-form">
<div class="form-group">
<label for="login-username">Username</label>
<input type="text" name="username" id="login-username"
class="form-control" required>
</div>
<div class="form-group">
<label for="login-password">Password</label>
<input type="password" name="password" id="login-password"
class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Log In</button>
<input type="hidden" name="option" value="com_users">
<input type="hidden" name="task" value="user.login">
<input type="hidden" name="return" value="<?php echo base64_encode(JUri::current()); ?>">
<?php echo JHtml::_('form.token'); ?>
</form>| Aspect | Override | Alternative Layout |
|---|---|---|
| Application | Automatic site-wide | Selectable per module |
| File | default.php (replaces) | Unique name (e.g.: grid.php) |
| Usage | Replaces original view | Option alongside original |
/html/mod_[module]/// /templates/cassiopeia/html/mod_login/grid.php
// Alternative grid layout for mod_login
<?php defined('_JEXEC') or die; ?>
<div class="login-grid">
<!-- grid structure -->
</div>grid.phpminimal.phpcard.phpdefault.php/layouts/joomla/[group]/[layout].php/templates/cassiopeia/html/layouts/joomla/[group]/[layout].php// /templates/cassiopeia/html/layouts/joomla/custom/article-card.php
<?php defined('_JEXEC') or die;
$title = $displayData['title'] ?? '';
$content = $displayData['content'] ?? '';
$image = $displayData['image'] ?? '';
$link = $displayData['link'] ?? '#';
?>
<article class="card">
<?php if ($image): ?>
<figure class="card-image">
<img src="<?php echo htmlspecialchars($image); ?>"
alt="<?php echo htmlspecialchars($title); ?>">
</figure>
<?php endif; ?>
<div class="card-body">
<h3><?php echo htmlspecialchars($title); ?></h3>
<div class="card-content">
<?php echo $content; ?>
</div>
<a href="<?php echo htmlspecialchars($link); ?>" class="card-link">
View more
</a>
</div>
</article><?php echo JLayoutHelper::render('joomla.custom.article-card', [
'title' => $this->item->title,
'content' => $this->item->introtext,
'image' => json_decode($this->item->images)->image_intro ?? '',
'link' => JRoute::_($this->item->link),
]); ?>/templates/cassiopeia-child/
├── html/
│ └── com_content/article/default.php (custom override)
├── css/
│ └── custom.css
└── templateDetails.xml<?xml version="1.0" encoding="utf-8"?>
<extension type="template" client="site">
<name>Cassiopeia Child</name>
<version>1.0.0</version>
<description>Child template based on Cassiopeia</description>
<parent>cassiopeia</parent>
<files>
<folder>html</folder>
<folder>css</folder>
<filename>templateDetails.xml</filename>
</files>
<positions>
<position>header</position>
<position>sidebar</position>
<position>footer</position>
</positions>
</extension>/templates/[template]/html/layouts/com_fields/field/[layout].php// /templates/cassiopeia/html/layouts/com_fields/field/render.php
<?php defined('_JEXEC') or die;
$field = $displayData['field'] ?? null;
$value = $displayData['value'] ?? null;
if (!$field || !$value) return;
?>
<div class="field-container" data-field-id="<?php echo (int)$field->id; ?>">
<label class="field-label">
<?php echo htmlspecialchars($field->label); ?>
</label>
<div class="field-value">
<?php echo $value; ?>
</div>
</div><?php
/**
* Override: Custom article
*
* Component: com_content
* Original view: article/tmpl/default.php
*
* CHANGES:
* - Improved semantic structure
* - Added custom fields
* - Reordered metadata
*
* DEPENDENCIES: Custom field 'author-bio'
* JOOMLA: 5.0+
* DATE: 2024-03-06
*/
defined('_JEXEC') or die;// GOOD: Escape outputs
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
<?php echo JHtml::_('string.truncate', $item->text, 100); ?>
// GOOD: URLs with JRoute
<?php echo JRoute::_('index.php?option=com_content&view=article&id=' . $item->id); ?>
// BAD: Unescaped output
<?php echo $item->title; ?># Compare overrides with core files
diff -u /components/com_content/views/article/tmpl/default.php \
/templates/cassiopeia/html/com_content/article/default.php
# Backup overrides before updating
cp -r templates/cassiopeia/html templates/cassiopeia/html.backup/templates/[active]/html//logs/# Folders: read+execute
chmod 755 /templates/cassiopeia/html/
# Files: read
chmod 644 /templates/cassiopeia/html/com_content/article/default.phpcom_content/article/featured.phplayouts/joomla/custom/featured-card.php/referencias/| Element | Original | Override |
|---|---|---|
| Article | | |
| Blog item | | |
| Category list | | |
| Login module | | |
| JLayout image | | |
| Nav plugin | | |
/html/// Articles
$this->item->id
$this->item->title
$this->item->introtext
$this->item->text
$this->item->images (JSON)
$this->item->jcfields (custom fields)
// Parameters
$this->params->get('show_author')
$this->params->get('show_category')
// Modules
$this->module->id
$this->module->title
$this->params
// JLayout
$displayData (array of passed data)