Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

The first module

A module is a block the administrator places in a template position. We start with the simplest one: the mod_hello module prints a single greeting line. It shows which files every Joomla 4 and 5 extension is made of.

Module files

In the modules folder of the site create a mod_hello folder with four files:

modules/mod_hello/
├── mod_hello.xml                    the manifest
├── services/
│   └── provider.php                 wires the module into Joomla
├── src/
│   └── Dispatcher/
│       └── Dispatcher.php           prepares the data
└── tmpl/
    └── default.php                  the layout: HTML markup

Joomla has no command that generates files — folders and files are created by hand.

The manifest

The mod_hello.xml file is the one covered in the previous lesson. Two parts of it matter here:

<namespace path="src">My\Module\Hello</namespace>
 
<files>
    <folder module="mod_hello">services</folder>
    <folder>src</folder>
    <folder>tmpl</folder>
</files>

The first sets the namespace of the classes, the second lists the module folders.

The service provider

The provider is the file Joomla starts with when it works with an extension. It tells Joomla where to look for the module classes:

// modules/mod_hello/services/provider.php
defined('_JEXEC') or die;
 
use Joomla\CMS\Extension\Service\Provider\HelperFactory;
use Joomla\CMS\Extension\Service\Provider\Module;
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
 
return new class () implements ServiceProviderInterface {
    public function register(Container $container): void
    {
        $container->registerServiceProvider(new ModuleDispatcherFactory('\\My\\Module\\Hello'));
        $container->registerServiceProvider(new HelperFactory('\\My\\Module\\Hello\\Site\\Helper'));
        $container->registerServiceProvider(new Module());
    }
};

The file is almost identical in every module — only the namespace changes. The HelperFactory line is needed in the next lesson.

The dispatcher

The dispatcher is a class that prepares data for the layout:

// modules/mod_hello/src/Dispatcher/Dispatcher.php
namespace My\Module\Hello\Site\Dispatcher;
 
defined('_JEXEC') or die;
 
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
 
class Dispatcher extends AbstractModuleDispatcher
{
    protected function getLayoutData(): array
    {
        $data = parent::getLayoutData();
 
        $data['greeting'] = 'Hello!';
 
        return $data;
    }
}

The getLayoutData() method returns an array. Joomla adds the word Site to the namespace from the manifest by itself — because the module is meant for the site.

The layout

<?php
// modules/mod_hello/tmpl/default.php
 
defined('_JEXEC') or die;
?>
<p class="mod-hello"><?php echo htmlspecialchars($greeting, ENT_QUOTES, 'UTF-8'); ?></p>

Every key of the dispatcher array becomes a variable in the layout: $data['greeting'] turned into $greeting.

The defined('_JEXEC') line

The _JEXEC constant is defined only when the code runs through Joomla. If the file is opened directly by its address, it stops at once. This line goes at the top of every PHP file of an extension.

Installing and seeing the result

  1. System → Install → Discover → Discover → tick mod_hello → Install.
  2. Content → Site Modules → New → choose mod_hello.
  3. Set the title "Greeting", the position sidebar-right, the status Published.
  4. On the Menu Assignment tab choose On all pages and save.

Open the site: the right column now has a "Greeting" block with the line "Hello!".

Common mistake

The namespace must match in three places: the namespace tag of the manifest, the provider and the class itself. With a typo the module is not rendered or shows a "class not found" error. Compare the three lines and remember: on a Linux server the letter case of folder names such as src/Dispatcher matters.

Thanks for reading!

Donate to the site — we work hard for you.