CMS / content platform12 min readNot archived on GitHub

Joomla: an extensible PHP CMS and its extension model

A guide to Joomla as a CMS product, based only on the official Programmers Documentation introduction, with clear notes on what the source does not say.

PHP compatibility and project lifecycle

Joomla's supported PHP versions, database requirements and release support status are unknown from the supplied source, which only labels the manual as Version 6.1 (Current). The learning track uses PHP 8.4 with PHP 8.5 planned. The example script is independent of Joomla and targets the PHP 8.4 CLI only.

Official sources checked 2026-10-22. Browser lessons on this site run PHP 8.5.

What Joomla is

Joomla is a content management system (CMS) written for PHP. It is a product that you install and extend, not a PHP runtime, not a language feature and not a standalone framework. PHP core is the language engine and its bundled extensions. Joomla is application code that runs on top of PHP. The same distinction applies to Drupal and WordPress, and it applies to framework components, which are libraries that a developer assembles into an application. A CMS product ships an application with an administration interface, content handling and an extension system.

This guide rests on a single official source: the introduction page of the Joomla Programmers Documentation. That page is short. It tells us the manual is for developers of Joomla extensions, and it labels the documentation version as 6.1 (Current). It does not state PHP version requirements, database requirements, licensing, installation steps, support windows or performance characteristics. This guide treats all of those as unknown. Because the evidence is incomplete, the lifecycle field is set to unknown rather than current. The documentation label alone is not a statement about support status.

Architecture: the extension model

The source names five kinds of extension: components, modules, libraries, plugins and templates. It also splits extensions into two groups by origin:

  • Joomla core extensions, produced by the Joomla project and shipped with the installation packages.
  • Third-party extensions, produced by independent developers and installed separately.

The source adds that the people involved are often the same, and that independent developers often become core developers and the reverse. So the manual aims to serve both groups. Beyond these five names and two origins, the supplied source does not describe how the extensions interact, how events are dispatched or how templates are resolved. Learn those details from the later pages of the manual rather than from this guide.

Execution and content model

The source does not describe Joomla's request handling. The general PHP model is the classic request lifetime. A web server hands each request to PHP, PHP builds application state, produces a response and then discards that state. Persistent workers are a different model. A long-running process keeps the application booted and serves many requests. Swoole and Open Swoole are separate projects in that second space, and neither should be confused with the other or with Joomla. The Joomla source says nothing about persistent workers, so do not assume that Joomla or its third-party extensions are safe to run in one.

The risk in persistent workers is state leakage. Static properties, singletons, globals, caches, open database connections, the current user, session data and request-scoped objects can survive from one request into the next. A leak can show one visitor's data to another or keep stale configuration alive. A worker setup needs an explicit reset step after every request, and each extension you rely on must be audited for hidden state. For Joomla, whether that is feasible is unknown from the supplied source. Plan on the classic request lifetime unless the official documentation says otherwise.

The source also does not define Joomla's content model, such as articles, categories or fields. Consult the full manual for that.

Practical use cases

The documentation is aimed at people building extensions, so the clearest use cases from the source are these:

  • Building a component to add a feature area to a site.
  • Building a module for a small, reusable piece of output.
  • Building a plugin to extend behavior.
  • Building a template to control presentation.
  • Packaging shared code as a library.

Whether Joomla suits a particular site, such as a brochure site, a publication or a community portal, is not discussed in the source. Judge that from the wider official documentation and your own requirements.

Installation approach

The supplied page contains no installation instructions, so this guide does not invent any. A responsible approach is to open the official manual, find the current installation and requirements pages, and check the PHP version, web server and database requirements for the Joomla version you intend to use. Then compare those requirements with this learning track, which uses PHP 8.4 and plans PHP 8.5. Whether a given Joomla release supports either version is unknown from the source. Verify it before building anything.

The example below is deliberately not a Joomla installation. It is a plain PHP 8.4 command-line script that checks a planning file against the five extension types and two origins named in the manual. It uses no Joomla API and needs no Composer packages, network services or Docker. It is not a browser exercise.

Strengths

  • The documented extension categories are clear and give a shared vocabulary for planning work.
  • The manual explicitly serves both core and third-party developers, and invites contributions through GitHub.
  • It is a CMS product, so the application shell is not something you assemble yourself.

Limitations

  • The manual describes itself as incomplete, so expect gaps.
  • The supplied source gives no evidence on versions, PHP compatibility, licensing, security policy, performance or hosting. These are all unknown here.
  • Persistent-worker suitability is unknown and should not be assumed.

Deployment

The source gives no deployment guidance. In general, deploying a CMS involves a PHP-capable web server, a database, writable storage, backups and a plan for updating the core and its extensions. Check each of those against the official documentation for your chosen version. If you ever place PHP-FPM or any FastCGI service behind a web server, keep it on a private interface and never expose it publicly. Any local development port should be bound to 127.0.0.1.

Where to go next

Read the later pages of the official manual, starting with the Development Strategy page that follows the introduction. Then pick one extension type, confirm its requirements in the official documentation, and prototype it in an isolated environment.

Practical examples

These examples have not been run in a live environment yet. Commands and versions follow the official documentation linked on this page; check them before relying on them, and report a problem if one does not work.

Plan and validate Joomla extension types with a PHP 8.4 CLI script

A plain PHP script, not a Joomla API, that reads a JSON planning file and checks each planned extension against the five extension types (component, module, library, plugin, template) and two origins (core, third-party) named in the official manual. It helps you organize a project before you consult the official Joomla installation and extension pages.

joomla-plan/bin/check-plan.php

<?php

declare(strict_types=1);

const DOCUMENTED_TYPES = ['component', 'module', 'library', 'plugin', 'template'];
const DOCUMENTED_ORIGINS = ['core', 'third-party'];

$path = $argv[1] ?? null;

if ($path === null || !is_file($path)) {
    fwrite(STDERR, "Usage: php bin/check-plan.php <plan.json>\n");
    exit(2);
}

try {
    $data = json_decode((string) file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    fwrite(STDERR, 'Invalid JSON: ' . $e->getMessage() . "\n");
    exit(2);
}

$extensions = is_array($data) ? ($data['extensions'] ?? null) : null;

if (!is_array($extensions)) {
    fwrite(STDERR, "The plan must contain an 'extensions' array.\n");
    exit(2);
}

$errors = [];

foreach ($extensions as $index => $extension) {
    $name = is_array($extension) ? ($extension['name'] ?? '') : '';
    $type = is_array($extension) ? ($extension['type'] ?? '') : '';
    $origin = is_array($extension) ? ($extension['origin'] ?? '') : '';

    if (!is_string($name) || $name === '') {
        $errors[] = "Item $index: missing name";
        continue;
    }
    if (!in_array($type, DOCUMENTED_TYPES, true)) {
        $errors[] = "$name: unknown type";
        continue;
    }
    if (!in_array($origin, DOCUMENTED_ORIGINS, true)) {
        $errors[] = "$name: unknown origin";
        continue;
    }
    echo "OK: $name ($type, $origin)\n";
}

if ($errors !== []) {
    foreach ($errors as $error) {
        fwrite(STDERR, "ERROR: $error\n");
    }
    exit(1);
}

echo "All planned extensions use documented types and origins.\n";

joomla-plan/planning/extensions.json

{
  "extensions": [
    { "name": "Event Notes", "type": "component", "origin": "third-party" },
    { "name": "Latest Notes", "type": "module", "origin": "third-party" },
    { "name": "Note Formatting", "type": "plugin", "origin": "third-party" },
    { "name": "Shared Helpers", "type": "library", "origin": "third-party" },
    { "name": "Site Theme", "type": "template", "origin": "third-party" }
  ]
}

joomla-plan/planning/invalid.json

{
  "extensions": [
    { "name": "Mystery Add-on", "type": "widget", "origin": "third-party" }
  ]
}

Install and run

cd joomla-plan
php --version
php bin/check-plan.php planning/extensions.json
php bin/check-plan.php planning/invalid.json

Expected behavior

With PHP 8.4 CLI installed, the first check should print one OK line per planned extension and a closing confirmation, then exit with status 0. The second check should print an error that the type is unknown and exit with status 1.

Requires only a PHP 8.4 CLI. It is not a Joomla installation, does not call any Joomla API and does not validate real extension manifests or packages. The type and origin lists come only from the introduction page of the official manual.