Joomla Developer Manual
Manual Index
Creating a Simple Module
Joomla! 4.x >Tutorial Creating a Simple Module for Joomla 4.x
This is a tutorial on how to Create a simple module for Joomla Version 4x.
Introduction¶
Joomlaǃ 4 provides five types of extensionsː
-
Components
A component is the main part of the site. A component handles data manipulation as well as input and storage into the database. A component on most sites is the primary focus of the page. -
Modules
A module is an add-on to the site that extends the functionality. A module usually occupies a secondary portion of the web page and is not considered the primary focus of a page. It can be displayed on different positions and you can choose on which active menu items it should be displayed. Modules are lightweight and flexible extensions. They are used for small bits of the page that are generally less complex and are able to be seen across different components. -
Plugins
A Plugin manipulates output that is already generated by the system. It typically does not run as separate part of the site. It takes data from other sources (i.e. the content) and manipulates this data before displaying. A plugin typically work behind the scenes. -
Languages
Probably the most basic extensions are languages. In essence the language package files consist of key/value pairs, which provide the translation of static text strings, assigned within the Joomla! source code. -
Templates
A template is basically the design of your Joomla! powered website.
Joomla! 4 is constructed using five different applications:
- Installation (used for installing Joomla and have to delete after installation);
- Administrator (backend - used for managing content);
- Public or site (frontend - used for displaying content);
- CLI (used for accessing Joomla on the command line and for cron jobs);
- API (web services - used for creating APIs for machine accessible content);
The installation application is used once. The administrator and public
are used through the concept of components with modules. Each module
has a single entry point located in the modules and accordingly
administrator/modules directory. This entry point is called
mod_modulename/mod_modulename.php
(the mod_ prefix is a
historical trace). The entry point for the login module is for example
/mod_login/mod_login.php.
Requirements¶
You need Joomla! 4.x installation available to use for this tutorial (Download latest release here)
You can download Joomla! 4 at GitHub, on the Developer website or you can create a free website at https://launch.joomla.org.
Creating a simple module/Developing a Basic Module - Part 1¶
You can see many examples of modules in the standard Joomla! install. For example:
- Menus
- Latest News
- Login form
- and many more.
This tutorial will explain how to create a simple module. Through this tutorial you will learn the basic file structure of a Joomlaǃ 4 module. This basic structure can then be expanded to produce more elaborate modules.
File Structure¶
There are a few basic files that are used in the standard pattern of module development:
-
mod_foo.php
- This file is the main entry point for the module. It will perform any necessary initialization routines, call helper routines to collect any necessary data, and include the template which will display the module output. -
mod_foo.xml
- This file contains information about the module. It defines the files that need to be installed by the Joomla! installer and specifies configuration parameters for the module. -
tmpl/default.php
- This is the module template. This file will take the data collected by mod_foo.php and generate the HTML to be displayed on the page. -
language/en-GB/mod_foo.ini
andlanguage/en-GB/mod_foo.sys.ini
- This are the files that provide the text in United Kingdom English.
Creating mod_foo.php¶
The mod_foo.php
file will perform following tasks:
- Import the class
ModuleHelper
to the current scope. We need it later for displaying the output. - Include the template to display the output.
The helper class is imported to our current scope at the begin of the file.
use Joomla\CMS\Helper\ModuleHelper;
Last we include the template to display the output via
require ModuleHelper::getLayoutPath('mod_foo', $params->get('layout', 'default'));
Completed mod_foo.php file¶
The complete mod_foo.php
file is as follows:
<?php
/**
* @package [PACKAGE_NAME]
*
* @author [AUTHOR] <[AUTHOR_EMAIL]>
* @copyright [COPYRIGHT]
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @link [AUTHOR_URL]
*/
// No direct access to this file
defined('_JEXEC') or die;
use Joomla\CMS\Helper\ModuleHelper;
require ModuleHelper::getLayoutPath('mod_foo', $params->get('layout', 'default'));
Side noteː In Joomla 3x you usually used a line like
$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
.
You don't need this anymore. See this PRː
https://github.com/joomla/joomla-cms/pull/17447.
The one line that we haven’t explained so far is the first line
defined('_JEXEC') or die;
. This line checks to make sure that this
file is being included from the Joomla application. This is necessary to
prevent variable injection and other potential security concerns.
Creating tmpl/default.php¶
The default.php
file is the template which displays the module output.
Completed tmpl/default.php file¶
The code for the tmpl/default.php file is as follows:
<?php
/**
* @package [PACKAGE_NAME]
*
* @author [AUTHOR] <[AUTHOR_EMAIL]>
* @copyright [COPYRIGHT]
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @link [AUTHOR_URL]
*/
// No direct access to this file
defined('_JEXEC') or die;
echo '[PROJECT_NAME]';
An important point to note is that the template file has the same scope
as the mod_foo.php
file. It means that a variable can be defined in
the mod_foo.php
file and then used in the template file without any
extra declarations or function calls.
Creating mod_foo.xml¶
The mod_foo.xml
file is the installation file. Most entries are
self-explanatory.
Completed mod_foo.xml file¶
The code for the mod_foo.xml
file is as follows:
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="4.0" client="site" method="upgrade">
<name>MOD_FOO</name>
<creationDate>[DATE]</creationDate>
<author>[AUTHOR]</author>
<authorEmail>[AUTHOR_EMAIL]</authorEmail>
<authorUrl>[AUTHOR_URL]</authorUrl>
<copyright>[COPYRIGHT]</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<version>1.0</version>
<description>MOD_FOO_XML_DESCRIPTION</description>
<files>
<filename module="mod_foo">mod_foo.php</filename>
<folder>tmpl</folder>
<folder>language</folder>
<filename>mod_foo.xml</filename>
</files>
</extension>
Creating the language files¶
The files language/en-GB/mod_foo.ini
and
language/en-GB/mod_foo.sys.ini
are used to translate text in the
frontend and in the backend. Note that the language file structure has
been updated in Joomla 4, and language prefixes on the individual files
in a language folder are no longer required.
The code for language/en-GB/mod_foo.sys.ini
is as follows:
MOD_FOO="[PROJECT_NAME]"
MOD_FOO_XML_DESCRIPTION="Foo Module"
The code for language/en-GB/mod_foo.ini
is as follows:
MOD_FOO="[PROJECT_NAME]"
MOD_FOO_XML_DESCRIPTION="Foo Module"
The .sys.ini
file is used to translate the description of the
extension upon installation, where as the .ini
file is used to
translate the remaining strings and the description when viewing your
extension.
More information about language files can be found here.
Test your module¶
Now you can zip all files and install them via the Joomla Extension
Manager.
After that you can choose your module in the module manager, when you
create a new site module.
In the frontend, you will see your module like displayed in the next image.
Conclusion¶
Module development for Joomla is a fairly simple, straightforward process. Using the techniques described in this tutorial, an endless variety of modules can be developed with little hassle.
You can find boilerplates hereː
The sample files for this Tutorial can be found hereː
Add a helper class using namespaces - Part 2¶
Requirements¶
You need Joomla! 4.x for this tutorial (as of writing currently Joomla! 4.0.0-alpha6-dev)
Namespaces¶
With PHP 5.3, the namespaces came into their own. In other programming languages for a long time in use, these small structures now also help us with the clarity of our code.
Namespaces are separate areas in which certain logical things (in our case, classes, interfaces, functions, and constants) can live. These areas provide encapsulation of the code and prevent name conflicts.
Let's take a look how to use them in Joomla 4. We use the helper file for this.
File Structure¶
We will create/change the following files:
-
Helper/FooHelper.php
- This is the file we use here as an example. We have to create it. -
mod_foo.php
- In this file, we will mainly load the namespace. -
tmpl/default.php
- In this file, we will demonstrate how the data of a helper can be displayed. -
mod_foo.xml
- We create a new directory with a new file. This must be installed during the installation. For this we have to specify them in this file.
Creating Helper/FooHelper.php¶
Our new helper class should belong to a namespace. We achieve this with the following code. It is important, that this line is at the beginning of the file.
namespace Joomla\Module\Foo\Site\Helper;
Then we create a simple class with a simple method. Of course you can do a lot more here. Take a look at the Joomla core methods. Here are many examples. They show you first-hand what options you have.
Completed Helper/FooHelper.php¶
The complete FooHelper.php
file is as follows:
<?php
/**
* @package Joomla.Site
* @subpackage mod_foo
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Foo\Site\Helper;
// No direct access to this file
defined('_JEXEC') or die;
/**
* Helper for mod_foo
*
* @since 4.0
*/
class FooHelper
{
/**
* Retrieve foo test
*
* @param Registry $params The module parameters
* @param CMSApplication $app The application
*
* @return array
*/
public static function getText()
{
return 'FooHelpertest';
}
}
Editing mod_foo.php¶
Our new helper class is imported to our current scope at the beginning of the file.
use Joomla\Module\Foo\Site\Helper\FooHelper;
Last use the helper file for testing if it is loaded correctlyː
$test = FooHelper::getText($params, $app);
Completed mod_foo.php file¶
The complete mod_foo.php
file is as follows:
<?php
/**
* @package [PACKAGE_NAME]
*
* @author [AUTHOR] <[AUTHOR_EMAIL]>
* @copyright [COPYRIGHT]
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @link [AUTHOR_URL]
*/
// No direct access to this file
defined('_JEXEC') or die;
use Joomla\CMS\Helper\ModuleHelper;
use Joomla\Module\Foo\Site\Helper\FooHelper;
$test = FooHelper::getText();
require ModuleHelper::getLayoutPath('mod_foo', $params->get('layout', 'default'));
Editing tmpl/default.php¶
In this file you make only a small change to demonstrate in the frontend that your helper file is working properly. You only add the value of the variable at the end of the current output.
echo '[PROJECT_NAME]' . $test;
Completed tmpl/default.php¶
The complete tmpl/default.php
file is as follows:
<?php
/**
* @package [PACKAGE_NAME]
*
* @author [AUTHOR] <[AUTHOR_EMAIL]>
* @copyright [COPYRIGHT]
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @link [AUTHOR_URL]
*/
// No direct access to this file
defined('_JEXEC') or die;
echo '[PROJECT_NAME]' . $test;
Editing mod_foo.xml¶
First you have to add a line, so that the namespace is set automatically
in Joomla. After this change, you have to re-install your module. A
simple change in an already installed module is not enough. If you are
doing local development you can also delete the files
libraries/autoload_psr4.php and it will automatically be re-created.
After inserting and installing, the namespace is known by the loader
JPATH_LIBRARIES . '/autoload_psr4.php'
.
<namespace>Joomla\Module\Foo</namespace>
Joomla! should copy your helper file when installing the module. So Joomla! needs to know your helper file. For this, you need to add the following line to your XML file.
<folder>Helper</folder>
Completed mod_foo.xml¶
The complete mod_foo.xml
file is as follows:
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="4.0" client="site" method="upgrade">
<name>MOD_FOO</name>
<creationDate>[DATE]</creationDate>
<author>[AUTHOR]</author>
<authorEmail>[AUTHOR_EMAIL]</authorEmail>
<authorUrl>[AUTHOR_URL]</authorUrl>
<copyright>[COPYRIGHT]</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<version>1.0</version>
<description>MOD_FOO_XML_DESCRIPTION</description>
<namespace>Joomla\Module\Foo</namespace>
<files>
<filename module="mod_foo">mod_foo.php</filename>
<folder>tmpl</folder>
<folder>Helper</folder>
<folder>language</folder>
<filename>mod_foo.xml</filename>
</files>
</extension>
Test your module¶
Now you can zip all files and install them via the Joomla Extension Manager. After that you can choose your module in the module manager, when you create a new site module.
In the frontend you will see your module like displayed in the next image. The text from your helper file is displayed.
Conclusion¶
As you can see, once you get a bit into the namespaces, they are not that complicated anymore. In big projects they can bring a lot of benefits. However, we should plan namespaces, as otherwise it will soon be more time-consuming.
You can find boilerplates hereː
The sample files for this Tutorial can be found hereː
Customizationː Add parameters via form fields - Part 3¶
Requirements¶
You need Joomla! 4.x for this tutorial (as of writing currently Joomla! 4.0.0-alpha6-dev)
Customization with form fields and parameters¶
Form fields give a great deal of customization in Joomla and for modules are the sole way of allowing the user to tweak the module to the needs of their site.
In this case we are going to extend our previous example using a url field for inserting a domain that we can use as link in the front end. To allow this to happen we will use the URL Form Field type.
After that, we insert parameters that allow to use standard functionality of Joomla.
Let's take a look on how to use them in Joomla 4.
File Structure¶
We will change the following files:
-
mod_foo.xml
- This is the file where we add the fields. -
tmpl/default.php
- In this file demonstrate how the data of a field can be used. -
language/en-GB/en-GB.mod_foo.ini
- Here we use a language string so that the field can be labeled correctly in different languages.
Editing mod_foo.xml¶
First we set a custom parameter.
<field
name="domain"
type="url"
label="MOD_FOO_FIELD_URL_LABEL"
filter="url"
/>
Then we insert Joomla default fields, so that we can use cache, moduleclass-suffix and layouts.
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="custom-select"
/>
<field
name="moduleclass_sfx"
type="textarea"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
rows="3"
/>
<field
name="cache"
type="list"
label="COM_MODULES_FIELD_CACHING_LABEL"
default="0"
>
<option value="1">JGLOBAL_USE_GLOBAL</option>
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="number"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
default="0"
/>
<field
name="cachemode"
type="hidden"
default="itemid"
>
<option value="itemid"></option>
</field>
Completed mod_foo.xml¶
The complete mod_foo.xml
file is as follows:
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="4.0" client="site" method="upgrade">
<name>MOD_FOO</name>
<creationDate>[DATE]</creationDate>
<author>[AUTHOR]</author>
<authorEmail>[AUTHOR_EMAIL]</authorEmail>
<authorUrl>[AUTHOR_URL]</authorUrl>
<copyright>[COPYRIGHT]</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<version>1.0</version>
<description>MOD_FOO_XML_DESCRIPTION</description>
<namespace>Joomla\Module\Foo</namespace>
<files>
<filename module="mod_foo">mod_foo.php</filename>
<folder>tmpl</folder>
<folder>Helper</folder>
<folder>language</folder>
<filename>mod_foo.xml</filename>
</files>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="domain"
type="url"
label="MOD_FOO_FIELD_URL_LABEL"
filter="url"
/>
</fieldset>
<fieldset name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="custom-select"
/>
<field
name="moduleclass_sfx"
type="textarea"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
rows="3"
/>
<field
name="cache"
type="list"
label="COM_MODULES_FIELD_CACHING_LABEL"
default="0"
>
<option value="1">JGLOBAL_USE_GLOBAL</option>
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="number"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
default="0"
/>
<field
name="cachemode"
type="hidden"
default="itemid"
>
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>
Editing tmpl/default.php¶
We can use the value of the parameter for creating a hyperlink in the frontend. We can access the value via the variable $params.
$domain = $params->get('domain', 'https://www.joomla.org');
Later we set use this value for creating the hyperlink.
<a href="/<?php echo $domain; ?>">
<?php echo '[PROJECT_NAME]' . $test; ?>
</a>
Completed tmpl/default.php file¶
The complete tmpl/default.php
file is as follows:
<?php
/**
* @package [PACKAGE_NAME]
*
* @author [AUTHOR] <[AUTHOR_EMAIL]>
* @copyright [COPYRIGHT]
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @link [AUTHOR_URL]
*/
// No direct access to this file
defined('_JEXEC') or die;
$domain = $params->get('domain', 'https://www.joomla.org');
?>
<a href="/<?php echo $domain; ?>">
<?php echo '[PROJECT_NAME]' . $test; ?>
</a>
Editing language/en-GB/en-GB.mod_foo.ini¶
Here we can specify the text for the English version of the field label.
MOD_FOO_FIELD_URL_LABEL="Url"
Completed language/en-GB/en-GB.mod_foo.ini¶
The complete language/en-GB/en-GB.mod_foo.ini
file is as follows:
MOD_FOO="[PROJECT_NAME]"
MOD_FOO_XML_DESCRIPTION="Foo Module"
MOD_FOO_FIELD_URL_LABEL="Url"
Test your module¶
Now you can zip all files and install them via the Joomla Extension Manager. After that you can choose your module in the module manager, when you create a new site module.
In the backend, you will see your module like displayed in the next image.
In the basic tab, you will see the custom field where you can insert a domain. The text for the label is fetched from the language file.
In the advanced tab, you will see all default options except the cache mode because of this is a hidden field.
In the frontend, you will see your module like displayed in the next image. The text form your helper file is displayed and you should see a hyperlink.
Conclusion¶
Form fields give the user an easy way to customize the module to their sites settings. This allows the modules scope to be increased.
You can find boilerplates hereː
The sample files for this Tutorial can be found hereː
See this issue for possible future changes:
Use Install, Update and Uninstall script - Part 4¶
Requirements¶
You need Joomla! 4.x for this tutorial (as of writing currently Joomla! 4.0.0-alpha6-dev)
Scripts¶
Installing, updating and uninstalling a module may require additional operations that cannot be achieved by the basic operations described in the main XML file. Joomla offers a new approach to solve this problem. It consists in using a PHP script file containing a class using five methods:
- preflight which is executed before install and update
- install
- update
- uninstall
- postflight which is executed after install and update
Let's take a look how to use them in Joomla 4. We use the helper file for this.
File Structure¶
We will create/change the following files:
-
script.php
- This is the file we use here as an example. We have to create it. -
language/en-GB/en-GB.mod_foo.sys.ini
- In this file we will add text. -
mod_foo.xml
- We create a new file. This must be installed during the installation. For this we have to specify it in this file.
Creating script.php¶
Writing an extension script consists in declaring a class whose name is
mod_ModuleNameInstallerScript
with these 5 methods. See the comments
in the file for more information. In this comments I explain when a
method is called.
In this example, I only use text to show when which method will be executed. In addition, I show you how to check the minimum requirements. Of course you can do much more. For example, you can delete files that are no longer needed in a new version of your module. This can be seen in the file. Another idea for this file is to create sample content, to show a success message with the current installed version number or you can redirect after a successful installation to the page with the module settings.
Completed script.php¶
The complete script.php
file is as follows:
<?php
/**
* @package [PACKAGE_NAME]
*
* @author [AUTHOR] <[AUTHOR_EMAIL]>
* @copyright [COPYRIGHT]
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @link [AUTHOR_URL]
*/
// No direct access to this file
defined('_JEXEC') or die;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
/**
* Script file of Foo module
*/
class mod_fooInstallerScript {
/**
* Extension script constructor.
*
* @return void
*/
public function __construct() {
$this->minimumJoomla = '4.0';
$this->minimumPhp = JOOMLA_MINIMUM_PHP;
}
/**
* Method to install the extension
*
* @param InstallerAdapter $parent The class calling this method
*
* @return boolean True on success
*/
function install($parent) {
echo Text::_('MOD_FOO_INSTALLERSCRIPT_INSTALL');
return true;
}
/**
* Method to uninstall the extension
*
* @param InstallerAdapter $parent The class calling this method
*
* @return boolean True on success
*/
function uninstall($parent) {
echo Text::_('MOD_FOO_INSTALLERSCRIPT_UNINSTALL');
return true;
}
/**
* Method to update the extension
*
* @param InstallerAdapter $parent The class calling this method
*
* @return boolean True on success
*/
function update($parent) {
echo Text::_('MOD_FOO_INSTALLERSCRIPT_UPDATE');
return true;
}
/**
* Function called before extension installation/update/removal procedure commences
*
* @param string $type The type of change (install, update or discover_install, not uninstall)
* @param InstallerAdapter $parent The class calling this method
*
* @return boolean True on success
*/
function preflight($type, $parent) {
// Check for the minimum PHP version before continuing
if (!empty($this->minimumPhp) && version_compare(PHP_VERSION, $this->minimumPhp, '<')) {
Log::add(Text::sprintf('JLIB_INSTALLER_MINIMUM_PHP', $this->minimumPhp), Log::WARNING, 'jerror');
return false;
}
// Check for the minimum Joomla version before continuing
if (!empty($this->minimumJoomla) && version_compare(JVERSION, $this->minimumJoomla, '<')) {
Log::add(Text::sprintf('JLIB_INSTALLER_MINIMUM_JOOMLA', $this->minimumJoomla), Log::WARNING, 'jerror');
return false;
}
echo Text::_('MOD_FOO_INSTALLERSCRIPT_PREFLIGHT');
echo $this->minimumJoomla . ' ' . $this->minimumPhp;
return true;
}
/**
* Function called after extension installation/update/removal procedure commences
*
* @param string $type The type of change (install, update or discover_install, not uninstall)
* @param InstallerAdapter $parent The class calling this method
*
* @return boolean True on success
*/
function postflight($type, $parent) {
echo Text::_('MOD_FOO_INSTALLERSCRIPT_POSTFLIGHT');
return true;
}
}
Editing language/en-GB/en-GB.mod_foo.sys.ini¶
There is not much to explain here. Write the text for the translation into this file.
Completed language/en-GB/en-GB.mod_foo.sys.ini file¶
The complete language/en-GB/en-GB.mod_foo.sys.ini
file is as follows:
MOD_FOO="[PROJECT_NAME]"
MOD_FOO_XML_DESCRIPTION="Foo Module"
MOD_FOO_INSTALLERSCRIPT_PREFLIGHT="Anything here happens before the installation/update/uninstallation of the module"
MOD_FOO_INSTALLERSCRIPT_UPDATE="The module has been updated"
MOD_FOO_INSTALLERSCRIPT_UNINSTALL="The module has been uninstalled"
MOD_FOO_INSTALLERSCRIPT_INSTALL="The module has been installed"
MOD_FOO_INSTALLERSCRIPT_POSTFLIGHT="Anything here happens after the installation/update/uninstallation of the module"
Editing mod_foo.xml¶
You have to add a line, so that the script is called automatically in Joomla.
<scriptfile>script.php</scriptfile>
Completed mod_foo.xml¶
The complete mod_foo.xml
file is as follows:
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="4.0" client="site" method="upgrade">
<name>MOD_FOO</name>
<creationDate>[DATE]</creationDate>
<author>[AUTHOR]</author>
<authorEmail>[AUTHOR_EMAIL]</authorEmail>
<authorUrl>[AUTHOR_URL]</authorUrl>
<copyright>[COPYRIGHT]</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<version>1.0</version>
<description>MOD_FOO_XML_DESCRIPTION</description>
<namespace>Joomla\Module\Foo</namespace>
<scriptfile>script.php</scriptfile>
<files>
<filename module="mod_foo">mod_foo.php</filename>
<folder>tmpl</folder>
<folder>Helper</folder>
<folder>language</folder>
<filename>mod_foo.xml</filename>
</files>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="domain"
type="url"
label="MOD_FOO_FIELD_URL_LABEL"
filter="url"
/>
</fieldset>
<fieldset name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="custom-select"
/>
<field
name="moduleclass_sfx"
type="textarea"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
rows="3"
/>
<field
name="cache"
type="list"
label="COM_MODULES_FIELD_CACHING_LABEL"
default="0"
>
<option value="1">JGLOBAL_USE_GLOBAL</option>
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="number"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
default="0"
/>
<field
name="cachemode"
type="hidden"
default="itemid"
>
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>
Test your module¶
Now you can zip all files and install them via the Joomla Extension Manager. Immediately after the installation, you will see the following information. This you had entered in the script so.
Conclusion¶
As you can see, Joomla offers you a lot to make your extension easy to use - right from the start.
You can find boilerplates hereː
The sample files for this Tutorial can be found hereː
Use Joomla Updaterː Adding Auto Update - Part 5¶
Requirements¶
You need Joomla! 4.x for this tutorial (as of writing currently Joomla! 4.0.0-alpha6-dev)
Joomla Updater¶
The first thing to do is to read the Managing Component Upgrades with Joomla 2.5 - Part 1 tutorial to give an idea of how the upgrade process works in Joomlaǃ. Whilst written for 2.5 the process hasn't changed. Also read Deploying an update server - this is what we'll be implementing in this tutorial.
File Structure¶
We will create/change the following files:
-
mod_foo.xml
- The only way to update our existing module is to add in a update server - for examplehttp://www.example.com/foo_update.xml
- into the xml file. -
foo_update.xml
- Then we have to create the XML file for the update server athttp://www.example.com/foo_update.xml
to let Joomla know an update is available.
Editing mod_foo.xml¶
To add our update server, we need to insert the following lines in your XML-Fileː
<updateservers>
<server type="extension" priority="1" name="[PROJECT_NAME]">https://www.example.com/mod_foo.xml</server>
</updateservers>
Completed mod_foo.xml¶
The complete mod_foo.xml
file is as follows:
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="4.0" client="site" method="upgrade">
<name>MOD_FOO</name>
<creationDate>[DATE]</creationDate>
<author>[AUTHOR]</author>
<authorEmail>[AUTHOR_EMAIL]</authorEmail>
<authorUrl>[AUTHOR_URL]</authorUrl>
<copyright>[COPYRIGHT]</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<version>1.0</version>
<description>MOD_FOO_XML_DESCRIPTION</description>
<namespace>Joomla\Module\Foo</namespace>
<files>
<filename module="mod_foo">mod_foo.php</filename>
<folder>tmpl</folder>
<folder>Helper</folder>
<folder>language</folder>
<filename>mod_foo.xml</filename>
</files>
<updateservers>
<server type="extension" priority="1" name="[PROJECT_NAME]">https://www.example.com/mod_foo.xml</server>
</updateservers>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="domain"
type="url"
label="MOD_FOO_FIELD_URL_LABEL"
filter="url"
/>
</fieldset>
<fieldset name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="custom-select"
/>
<field
name="moduleclass_sfx"
type="textarea"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
rows="3"
/>
<field
name="cache"
type="list"
label="COM_MODULES_FIELD_CACHING_LABEL"
default="0"
>
<option value="1">JGLOBAL_USE_GLOBAL</option>
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="number"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
default="0"
/>
<field
name="cachemode"
type="hidden"
default="itemid"
>
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>
So now that Joomlaǃ is searching for updates to our extension - let's
create one to test out our process. But first we need to create the file
foo_update.xml
. So far we have only described the update server. We do
not know yet if there is an update. In the file foo_update.xml
we
indicate when a new version is published and where it can be downloaded.
Creating foo_update.xml¶
Now we have to create the XML file at
http://www.example.com/foo_update.xml
to let Joomla know an update is
available.
Completed foo_update.xml¶
The complete foo_update.xml
file is as follows:
<?xml version="1.0" ?>
<updates>
<update>
<name>Foo</name>
<description>This is mod_foo 1.0.1</description>
<element>mod_foo</element>
<type>module</type>
<version>1.0.1</version>
<downloads>
<downloadurl type="full" format="zip">http://www.example.com/mod_foo_101.zip</downloadurl>
</downloads>
<maintainer>Joomla</maintainer>
<maintainerurl>http://www.example.com</maintainerurl>
<targetplatform name="joomla" version="4.0"/>
<client>site</client>
</update>
</updates>
After uploading this file to the address
https://www.example.com/mod_foo.xml
the update will be displayed in
the Joomla backend.
Test your module update¶
Create a copy of the module as it is now. Then let's update the version
number to 1.0.1. Now you can zip all files. After that you should load
your zip to the URL http://www.example.com/mod_foo_101.zip
. Now you
can update your module via the Joomla Updater.
Commercial Modules¶
Note that in our files we have linked to the extensions updates xml file. And from that xml file we have a location for the zip of the module. This means that if someone was to track this backwards they could find the physical source of your modules zip file. If you don't do like this, you can find a solution in this PRː https://github.com/joomla/joomla-cms/pull/15185.
Conclusion¶
With the Joomlaǃ updater, you can easily reach all users and tell them that there is a new version. Even the update itself is easy.
Each extension should use an update server. Especially for security reasons.
You can find boilerplates hereː
The sample files for this Tutorial can be found hereː
In this Article
- Introduction
- Creating a simple module/Developing a Basic Module - Part 1
- Test your module
- Conclusion
- Add a helper class using namespaces - Part 2
- Namespaces
- Test your module
- Conclusion
- Customizationː Add parameters via form fields - Part 3
- Customization with form fields and parameters
- Test your module
- Conclusion
- Use Install, Update and Uninstall script - Part 4
- Test your module
- Conclusion
- Use Joomla Updaterː Adding Auto Update - Part 5