Joomla is a powerful content management system but much of that power comes from the ability to add extensions without breaking the system. Extensions are opaque though and there is a lot to get to grips with to create them. There are many dependencies and knowledge points that you need to have to succeed. You might wisely choose to use a component creator to do this heavy lifting for you but I wondered what help there might be from AI. The answer is quite a bit and that I now have two working extensions - a plugin and a a component - but it wasn't exactly a straight out of the box experience. This article explores how to build a Joomla component using AI that dynamically generates meta descriptions from article content, thus enhancing SEO without manual input. You can learn more about Joomla development at the Joomla developer website.
Anyway, to the topic. I decided my meta descriptions were poor. I'm not sure how much they are relevant anymore in SEO so I didn't want to spend a lot of time curating them, but I want them to be useful. So I need to generate them automatically when an article is created and optionally need to regenerate them all if I change the logic for generation. We'll cover key aspects, including model creation, controller handling, and the UI for a "Regenerate All" button. By the end, you'll have a functional extension that automatically fills the metadesc
field in Joomla articles.
TL:DR – The following guide walks through building Joomla extensions, a (component and a plugin) that automatically generate SEO-friendly meta descriptions. You'll create the necessary MVC files, ensure proper database updates, and add a button for bulk regeneration. The process automates a manual task in Joomla's content creation and should improve article visibility in search engines.
Getting your environment Setup - what you'll need to create and test a Joomla component
To create a Joomla content plugin and a component that automatically generate meta descriptions from the title and content of an article, you'll need the following:
- Joomla installed (latest production version)
- Access to Joomla’s filesystem and database
- Basic understanding of Joomla and its extensions system
Generating the Plugin
I used AI to help generate the source code for the plugin.
AI prompt – Explain how to make a Plugin
Plugin structure
A Joomla content plugin resides in plugins/content/yourpluginname
and typically includes:
yourpluginname.php
(main plugin file)yourpluginname.xml
(plugin descriptor)
Plugin Event Hook
You should use Joomla’s onContentBeforeSave
event to intercept and modify the article’s metadata before it's saved.
Generating the Meta Description
I want to generate a nice meta description, which can be safely up to 160 characters but vaguely google say it can sometimes be up to 300 characters. Sticking with 160 for now!
So the plugin needs to:
- Extract text from
$article->title
and$article->introtext
- Process content (strip tags, remove excessive whitespace, trim to ~150-160 characters)
Assign generated description to$article->metadesc
And because it uses the event hook it is part of the save process. Nice.
The AI generated some code, but it didn't work out of the box. It was very nearly right but also quite wrong about a few fundamentals. It tried to store the metadata as JSON encoded attributes. This didn't work. Telling the AI helped.
AI prompt – fixing the generated example
So the Plugin directly modifies $article->metadesc, ensures that an existing meta description isn't overwritten if manually set, Cleans up the content by removing HTML tags and extra whitespace and Limits the generated meta description to 160 characters, the standard SEO length.
It saved me a massive amount of time though as all I neede to do was clean it up and heres the code I ended up with. The AI didn't add a licence or copyright, to its snippets so I added copyright since these are my edits to boilerplate code to create a finished working plugin, and I added the GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html which is Joomla's preferred licence for extensions.
Plugin code (autometa.php)
autometa.php
<?php
/*
* @package Plugin Autometa for Joomla!
* @version 1.1.0 autometa.php
* @author Angus Fox
* @copyright (C) 2025 - Multizone Limited
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Factory;
class PlgContentAutoMeta extends CMSPlugin
{
public function onContentBeforeSave($context, $article, $isNew)
{
// Ensure it's a Joomla article
if ($context !== 'com_content.article') {
return true;
}
// Skip if a meta description already exists
if (!empty($article->metadesc)) {
return true;
}
// Generate a meta description using the title and introtext
$article->metadesc = $this->generateMetaDescription($article->title, $article->introtext);
return true;
}
private function generateMetaDescription($title, $introtext)
{
$summary = $this->extractText($introtext);
$metaDesc = trim($title);
if (!empty($summary)) {
$metaDesc .= ' - ' . $summary;
}
return mb_substr($metaDesc, 0, 160); // Trim to 160 characters
}
private function extractText($text)
{
// Remove HTML tags, decode special characters, and clean up spaces
$cleanText = trim(strip_tags(html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8')));
return $cleanText;
}
}
Plugin Manifest (autometa.xml)
This defines the plugin metadata and installation parameters.
autometa.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" version="5.0" group="content" method="upgrade">
<name>PLG_CONTENT_AUTOMETA</name>
<version>1.1.0</version>
<creationDate>19 February 2025</creationDate>
<author>Angus Fox</author>
<copyright>(C) 2025 Multizone Limited. All rights reserved.</copyright>
<authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it. </authorEmail>
<authorUrl>https://www.multizone.co.uk</authorUrl>
<license>GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html</license>
<description>PLG_CONTENT_AUTOMETA_XML_DESCRIPTION</description>
<files>
<filename plugin="autometa">autometa.php</filename>
<folder>language</folder>
</files>
</extension>
Installation and activation
- Zip the yourpluginname.php and yourpluginname.xml into a package
- Add the licence as a text file from the GPL website.
- Install via Joomla Extensions Manager
- Enable the plugin in Joomla's Plugin Manager
This will ensure every new article gets a meta description if one isn’t provided manually.
Testing the plugin
The AI even listed the example scenarios, which I've rewritten to take account of my changes to the original logic.
- Case 1, Article with introtext
- Case 2, Article without introtext
- Case 3 No text at all
Case 1 Article with introtext
<p class="lead">AI is changing the world.</p>
<p>New developments in machine learning...</p>
Generated Meta Description
Article Title - AI is changing the world.
Example outputs
The AI gave me some helpful output examples too.
Example article Data
Title | Introtext | Generated Meta Description |
---|---|---|
"Exciting Tech News" | "AI is transforming the industry..." | "Exciting Tech News - AI is transforming the industry..." |
"Future of Space" | "<p>NASA plans new Mars missions...</p>" | "Future of Space - NASA plans new Mars missions..." |
Generating the component
To update meta descriptions for all articles as a maintenance task as opposed to individually, we need to:
- Create a Joomla administrator component with a button in the backend.
- When clicked, it will regenerate all articles meta descriptions.
Again AI can be used to help generate the source code for the component.
AI Prompt – making a component to do the task on all articles rather than one at a time
Setting up the component structure
Joomla components require a structured directory layout. this isn't the most advanced MVC layout for Joomla but it works.
It provides a separation of concerns. The Meta description logic is in a helper, making it reusable.
It provides good readability. The model focuses on database operations.
It provides easier maintenance it is easy to edit the logic without disturbing the rest.
The extension folder layout looks like this:
Folder structure
/com_autometa/
│── autometa.php # Main entry file
│── controller.php # Handles actions
│── manifest.xml # an XML file detailing information about the component
│── models/ # Model logic
│ ├── autometa.php # Processes meta descriptions
│── views/
│ ├── autometa/
│ │ ├── view.html.php
│ │ ├── tmpl/
│ │ │ ├── default.php (UI for regenerating metadata)
Creating the model
The model processes each article and regenerates metadata. It fetches articles, extracts a summary, and updates the database.
models/autometa.php
<?php
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Factory;
class AutometaModelAutometa extends BaseDatabaseModel
{
public function regenerateAllMetaDescriptions()
{
$db = Factory::getDbo();
// Select all articles
$query = $db->getQuery(true)
->select(['id', 'title', 'introtext'])
->from('#__content');
$db->setQuery($query);
$articles = $db->loadObjectList();
// Loop through each article and update meta description
foreach ($articles as $article) {
$metaDesc = $this->generateMetaDescription($article->title, $article->introtext);
// Update query
$updateQuery = $db->getQuery(true)
->update('#__content')
->set($db->quoteName('metadesc') . ' = ' . $db->quote($metaDesc))
->where($db->quoteName('id') . ' = ' . (int) $article->id);
$db->setQuery($updateQuery);
$db->execute();
}
}
// Generate a meta description from title + introtext
private function generateMetaDescription($title, $introtext)
{
// Remove HTML tags and trim
$cleanIntro = strip_tags($introtext);
$cleanIntro = trim($cleanIntro);
// Limit intro text to 150 characters
$summary = mb_substr($cleanIntro, 0, 150);
return $title . ' - ' . $summary;
}
}
Adding the controller logic
The controller handles user interactions, such as clicking the "Regenerate All" button. It ensures the model executes properly.
controller.php
<?php
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Factory;
class AutometaController extends BaseController
{
public function regenerateAll()
{
$model = $this->getModel('Autometa', 'AutometaModel', ['ignore_request' => true]);
if ($model) {
$model->regenerateAllMetaDescriptions();
Factory::getApplication()->enqueueMessage('All meta descriptions regenerated.', 'message');
} else {
Factory::getApplication()->enqueueMessage('Error: Could not load model.', 'error');
}
$this->setRedirect('index.php?option=com_autometa');
}
}
Building the user interface
The UI provides a button to regenerate meta descriptions. This form submits a request to trigger the controller action.
views/autometa/tmpl/default.php
<?php
defined('_JEXEC') or die;
use Joomla\CMS\Router\Route;
?>
<form action="<?php echo Route::_('index.php?option=com_autometa&task=regenerateAll'); ?>" method="post">
<button type="submit" class="btn btn-primary">Regenerate All Meta Descriptions</button>
</form>
Creating a manifest and installing and testing the component
The final step is ensuring the Joomla manifest correctly installs all files. The manifest.xml
must reference all essential components. Pay careful attention here, as the AI essed up the hierarchy of the XML so it needed to be manually reordered in line with Joomla standards.
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="5.0" method="upgrade">
<name>com_autometa</name>
<version>1.0.0</version>
<creationDate>2025-02-20</creationDate>
<author>Angus Fox</author>
<description>Automatically generates meta descriptions for Joomla articles.</description>
<administration>
<menu link="index.php?option=com_autometa">AutoMeta</menu>
<files folder="admin">
<filename>autometa.php</filename>
<filename>controller.php</filename>
<folder>models</folder>
<folder>views</folder>
</files>
</administration>
</extension>
Conclusion
This process provided a structured way for me to develop a working Joomla plugin and corresponding maintenance component that dynamically generates meta descriptions. By implementing a proper MVC pattern, leveraging Joomla's database API, and integrating a user-friendly interface, it can help streamline the content management workflow and enhance SEO. AI is like having a coach helping. It doesn't really know all these answers but can find them if you ask it the right questions. I wouldn't have been able to achieve this on my own in anywhere near the time it took - less than a day - I guess in the future it is the prompt writers who will inherit the Earth.