Photo by Bilal Ayadi on Unsplash
Over two decades, the project has embodied three core values: freedom (open licensing and transparent governance), flexibility (a powerful extension ecosystem and robust templating), and innovation (modern architecture, accessibility, and performance improvements across major releases).
Joomla’s success is powered by people—maintainers, extension developers, designers, translators, documentation teams, event organizers, and users worldwide. Their volunteer spirit and shared purpose have sustained the project’s momentum and quality for two decades.
As we celebrate 20 years, we also look to the future: continued improvements in usability, accessibility, and developer experience; deeper integration with modern tooling; and a renewed focus on performance and sustainability. The roadmap remains guided by real-world needs and the open-source ethos that has defined Joomla from the start.
Thank you to everyone who has contributed time, code, documentation, support, and inspiration. Joomla is more than software—it is a community that builds the web together.
Happy 20th Birthday, Joomla! Here’s to the next chapter.
Subform fields are mighty, but did you know they look like a list? - Here, I will show you how you can spice up the look of your Subform.
Although Subforms are not a new feature in Joomla 4 but were available already in Joomla 3, in Joomla 3, they were introduced as "Repeatable-Fields". But Subforms are taking things to the maks. If you use the Subforms as the default, it looks like a simple list separated by a comma. Here you can read "How to override the output of the default subform in Joomla 4," but we will now dive into the full power of the framework for which Joomla 4 is built.
Creating overrides in Joomla 4 is relatively easy. If you can read code and know HTML, it is not so difficult. Just follow these steps:
Joomla 4 left menu
Select "System" from the left menu.
Joomla 4 select "Site Templates"
Select the "Site Template" to go into the area for creating overrides of Joomla 4.
The difference between Site Templates and Site Template Styles is that the overrides for the Template that is put on the Site Templates place, here you put all your customization of the site. The Styles are set in the separate Site Template Styles, which you only use to change the site's primary colors and put things like a custom logo and the template's name.
This opens the place where you create the overrides. There is a selection called "Create Overrides"; go into it.
<?php
/**
* @package Joomla.Plugin
* @subpackage Fields.Subform
*
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
defined('_JEXEC') or die;
if (!$context || empty($field->subform_rows)) {
return;
}
$result = '';
// Iterate over each row that we have
foreach ($field->subform_rows as $subform_row) {
// Placeholder array to generate this rows output
$row_output = array();
// Iterate over each sub field inside of that row
foreach ($subform_row as $subfield) {
$class = trim($subfield->params->get('render_class', ''));
$layout = trim($subfield->params->get('layout', 'render'));
$content = trim(
FieldsHelper::render(
$context,
'field.' . $layout, // normally just 'field.render'
array('field' => $subfield)
)
);
// Skip empty output
if ($content === '') {
continue;
}
// Generate the output for this sub field and row
$row_output[] = '<span class="field-entry' . ($class ? (' ' . $class) : '') . '">' . $content . '</span>';
}
// Skip empty rows
if (count($row_output) == 0) {
continue;
}
$result .= '<li>' . implode(', ', $row_output) . '</li>';
}
?>
<?php if (trim($result) != '') : ?>
<ul class="fields-container">
<?php echo $result; ?>
</ul>
<?php endif; ?>
On lines 52 and 56
<?php
/**
* @package Joomla.Plugin
* @subpackage Fields.Subform
*
* @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
defined('_JEXEC') or die;
if (!$context || empty($field->subform_rows)) {
return;
}
$result = '';
// Iterate over each row that we have
foreach ($field->subform_rows as $subform_row) {
// Placeholder array to generate this rows output
$row_output = array();
// Iterate over each sub field inside of that row
foreach ($subform_row as $subfield) {
$class = trim($subfield->params->get('render_class', ''));
$layout = trim($subfield->params->get('layout', 'render'));
$content = trim(
FieldsHelper::render(
$context,
'field.' . $layout, // normally just 'field.render'
array('field' => $subfield)
)
);
// Skip empty output
if ($content === '') {
continue;
}
// Generate the output for this sub field and row
$row_output[] = '<span class="field-entry' . ($class ? (' ' . $class) : '') . '">' . $content . '</span>';
}
// Skip empty rows
if (count($row_output) == 0) {
continue;
}
$result .= '<li class="list-group-item">' . implode(', ', $row_output) . '</li>';
}
?>
<?php if (trim($result) != '') : ?>
<ul class="fields-container list-group">
<?php echo $result; ?>
</ul>
<?php endif; ?>
- LET ME KNOW IF YOU KNOW ANY OTHER WAYS TO DO THIS IN THE COMMENTS BELOW -
In Joomla, it is relatively easy to create CSS overrides. If you would like to change the color of the Invalidate Cache button, you can read on.
Joomla is built with the intention of user customization of how it looks. CSS customization in Joomla 3 is slightly different than in Joomla 4. I will show how to create a CSS override for the "Invalidate Cache" module in Joomla 4 Administrator Template Atum. You can read my Invalidate Cache Module review.
written in the file "custom.css"-file under "templates/[templatename]/css/", however the path to the CSS files in Joomla 4.1+ was changed to "media/templates/[site]/[templatename]/css/" and the file is called "user.css". This CSS override is written for Joomla 4+, but it will likely work also in Joomla 3. The recommended module position for Invalidate Cache is "status", putting it on the top.
Joomla 4 left menu
Select "System" from the left menu.
Joomla 4 select "Administrator Templates."
The difference between Administrator Templates and Administrator Template Styles is that the overrides for the Template that is put on the Administrator Templates place, here you put all your customization of the site. The Styles are set in the separate Administrator Template Styles, which you only use to change the site's primary colors and put things like a custom logo and the template's name.
Select the "Administrator Template" to go into the area for creating overrides of Joomla 4.
Here you choose what folder to put the override files in. This is the same for both Frontend and Administrator Templates.
Here you create the files for any overrides. For the CSS create a file called "user" and select ".css" as the File Type
.js_modInvalidatecach {
background-color: #ff0000;
}
- LET ME KNOW IF YOU KNOW ANY OTHER WAYS TO DO THIS IN THE COMMENTS BELOW -
Joomla is a widely-used, open-source content management system (CMS) recognized globally for its flexibility, scalability, and ease of use. It powers millions of websites ranging from personal blogs to large-scale corporate portals and government websites. Joomla provides a robust framework that allows users and developers to manage, organize, and publish content efficiently, making it a preferred platform for web development worldwide.
Read more: Creating Secure and Effective Joomla Extensions: A Guide
Using custom characters in JCE Editor can be challenging, especially if you want to use symbols, not on the JCEs default list. There are two ways to do this.
Special characters are often used in content to show something, but could you please explain how a field is inserted into an article? You know it's by inserting curly brackets { and }, but you can't insert the field number in between because you will then show the field instead of the text.
There are two ways to do this. One is by overriding/adding the characters to the Character Map in JCE; how come this method requires you to add each code separately in each of your JCE profiles using an HTML entity? Using this way, you must ensure that JCE does not strip your code. The other way is by using CSS and pseudo-elements
Adding special characters to the Character Map is very time-consuming. First, you'll need to find the HTML entities you want to add. Here is a list of them. Now go into your JCE profile of choice; go into "Plugin Parameters" and find Character Map. There you need to add all your entities.
<span class="special-chars curly-backets">field 1</span>
// Curly Brackets
span.special-chars {
display: inline-block;
background-color: 777;
}
span.curly-brackets:before {
content: "{";
}
span.curly-brackets:after {
content: "}";
}
Go to Components → JCE Editor → Profiles → [YOUR PROFILE] usually "Default" → Editors Parameters ↔ Typography → Write your file path and name in "Custom CSS Files"
Go into your Profile (as above) → Plugin Parameters → Style Select (scroll down to find)
Here you add your styles
There are three places to make sure you add the styles. Give it a Name, Tag, and Classes (for Tag, it is helpful to use "span").
In your article, select the test to have, like the Styles dropdown, and your "Curly Brackets" will appear.
REMEMBER TO ADD YOUR STYLES TO THE TEMPLATE!
- LET ME KNOW IF YOU KNOW ANY OTHER WAYS TO DO THIS IN THE COMMENTS BELOW -