MOD_SERVICESGRIDSanjeev Kumar1.0.0 MOD_SERVICESGRID_DESC mod_servicesgrid.php tmpl forms media language language/en-GB/en-GB.mod_servicesgrid.ini language/en-GB/en-GB.mod_servicesgrid.sys.ini

How to Create a Custom Module in Joomla 5 and Joomla 6 (Step-by-Step Tutorial)

Last Updated on June 10, 2026

Are you looking to create a custom Joomla module for your website? In this tutorial, you’ll learn how to develop a Joomla 5 and Joomla 6 module from scratch using modern Joomla development standards.

By the end of this guide, you’ll understand how to create a custom module, organise files correctly, add module parameters, retrieve data from the database, and display dynamic content on the frontend.

This tutorial is designed for beginners as well as Joomla developers who want to build custom extensions using the latest Joomla framework architecture.

What Is a Joomla Module?

A Joomla module is a lightweight extension used to display content or functionality in predefined template positions.

Examples of Joomla modules include:

  • Login Form
  • Latest Articles
  • Popular Articles
  • Custom HTML Content
  • Search Module
  • Image Sliders
  • Menus
  • Tags Module

Unlike components, which control the main content area, modules can appear in various locations such as sidebars, headers, footers, and custom template positions.

Joomla Module vs Component vs Plugin

Extension TypePurpose
ComponentControls the main content area of a page.
ModuleDisplays content in template positions.
PluginExecutes code when Joomla events are triggered.

Before learning module development, you may also want to read:

Requirements

Before creating your first Joomla module, make sure you have:

  • Joomla 5.x or Joomla 6.x installed
  • PHP 8.1 or higher
  • Administrator access to Joomla
  • Basic PHP knowledge
  • A code editor such as VS Code or PhpStorm

Module We Will Build

In this tutorial, we will create a custom Joomla 6 module called mod_servicesgrid.

The module will:

  • Display a responsive grid of services on the frontend
  • Allow administrators to add and manage service items through the module settings
  • Support service titles, descriptions, icons, images, and links
  • Use Joomla 6 coding standards and PSR-4 autoloading
  • Support language files for multilingual websites
  • Use a Helper class for data processing and business logic
  • Use layout files for clean separation of logic and presentation
  • Support template overrides for easy customization
  • Be fully installable as a standard Joomla extension
  • Follow Joomla 6 extension development best practices

By the end of this tutorial, you will have a modern, reusable Services Grid module that can be easily customized and deployed on any Joomla 6 website.

Step 1: Create the Module Folder Structure

Create a new folder named mod_latestposts.

Your module directory should look like this:

mod_servicesgrid/
│
├── mod_servicesgrid.php
├── mod_servicesgrid.xml
│
├── forms/
│ └── service.xml
│
├── tmpl/
│ └── default.php
│
├── media/
│ └── css/
│ └── style.css
│
└── language/
└── en-GB/
├── en-GB.mod_servicesgrid.ini
└── en-GB.mod_servicesgrid.sys.ini

Directory Explanation

Directory/FilePurpose
mod_servicesgrid.phpMain entry point of the module. Loads the helper, retrieves module data, and renders the layout.
mod_servicesgrid.xmlAn installation manifest file that defines module metadata, files, folders, and configuration parameters.
tmplContains frontend layout files used to render the services grid output.
languageStores language and translation files for multilingual support.
services/provider.phpRegisters the module with Joomla’s Dependency Injection (DI) container and service provider system.
mediaOptional directory for module-specific CSS, JavaScript, images, and other frontend assets.

Step 2: Create the XML Manifest File

Create a file named: mod_servicesgrid.xml

This file tells Joomla how to install and configure the module. It provides the following information about the module:

  • Module name
  • Version
  • Author information
  • Files to install
  • Language files
  • Module parameters

Without this file, Joomla cannot install the module.

Add the following code: 

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" client="site" method="upgrade">
 <name>MOD_SERVICESGRID</name>
 <author>Sanjeev Kumar</author>
 <version>1.0.0</version>
 <description>MOD_SERVICESGRID_DESC</description>

 <files>
 <filename module="mod_servicesgrid">mod_servicesgrid.php</filename>
 <folder>tmpl</folder>
 <folder>forms</folder>
 <folder>media</folder>
 <folder>language</folder>
 </files>

 <languages>
 <language tag="en-GB">language/en-GB/en-GB.mod_servicesgrid.ini</language>
 <language tag="en-GB">language/en-GB/en-GB.mod_servicesgrid.sys.ini</language>
 </languages>

 <config>
    <fields name="params">
     <fieldset name="basic" label="MOD_SERVICESGRID_SERVICES">
       <field name="services" type="subform" multiple="true" formsource="service.xml" label="MOD_SERVICESGRID_SERVICES" />
    </fieldset>
 </fields>
 </config>
</extension>

What Does the Manifest File Do?

  • Defines module metadata.
  • Registers files and folders.
  • Registers language files.
  • Creates module parameters.
  • Controls installation and updates.

In the next section, we’ll create the main module file (mod_servicesgrid.php) and build the helper class that retrieves articles from the Joomla database.

Step 3: Create the Main Module File

The main module file serves as the module’s entry point. Joomla executes this file whenever the module is rendered on the frontend.

file name is mod_servicesgrid.php, and add the following code:

<?php
defined("_JEXEC") or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ModuleHelper;

$wa = Factory::getApplication()
    ->getDocument()
    ->getWebAssetManager();

$wa->registerAndUseStyle(
    'mod_servicesgrid',
    'modules/mod_servicesgrid/media/css/style.css'
);

$services = (array) $params->get('services');

require ModuleHelper::getLayoutPath(
    'mod_servicesgrid',
    $params->get("layout", 'default')
);

Responsibilities:

  • Prevent direct access.
  • Retrieve module parameters.
  • Load required assets.
  • Load the layout file.

Example workflow:

  1. Joomla loads module.
  2. Parameters are retrieved.
  3. CSS file is loaded.
  4. Layout file is rendered.

This file should remain lightweight.

Step 4: Create the Service Subform

File:forms/service.xml

Instead of creating fixed service fields, we’ll use a Joomla Subform.

Benefits:

  • Add unlimited services.
  • No code changes required.
  • Easy administration.

Each service can contain:

  • Title
  • Description
  • Icon
  • Link

The administrator can click “Add Service” to create additional service entries.

This makes the module highly flexible.

Add the following code: you can see after the first line, there are added comments that are standard but not required.

<?xml version="1.0" encoding="utf-8"?>
<!--
/**
 * Service Subform Definition
 *
 * @package     Joomla.Site
 * @subpackage  mod_servicesgrid
 * @since       1.0.0
 */
-->
<form>


    <fields name="item">


        <field
            name="title"
            type="text"
            label="MOD_SERVICESGRID_TITLE"
            required="true"
        />


        <field
            name="image"
            type="media"
            label="MOD_SERVICESGRID_IMAGE"
        />


        <field
            name="description"
            type="textarea"
            label="MOD_SERVICESGRID_DESCRIPTION"
        />


        <field
            name="link"
            type="url"
            label="MOD_SERVICESGRID_LINK"
        />


    </fields>


</form>

Step 5: Add Module Parameters

Inside the manifest file create a subform field.

Example configuration:

  • Services Field
  • Multiple = true
  • Form source = service.xml

When the module settings are opened, Joomla automatically loads the subform and displays repeatable service fields.

The entered data is stored in the module parameters JSON.

Example: This code is already added in the main file mod_servicesgrid.xml.

<config> <fields name="params"> 
<fieldset name="basic" label="MOD_SERVICESGRID_SERVICES"> 
<field name="services" type="subform" multiple="true" formsource="service.xml" label="MOD_SERVICESGRID_SERVICES" /> 
</fieldset> </fields> </config>

Step 6: Create Language Files

Files:

language/en-GB/en-GB.mod_servicesgrid.ini
language/en-GB/en-GB.mod_servicesgrid.sys.ini

en-GB.mod_servicesgrid.ini

Contains:

  • Field labels
  • Descriptions
  • Frontend text

Example:

MOD_SERVICESGRID=”Services Grid”
MOD_SERVICESGRID_SERVICES=”Services”
en-GB.mod_servicesgrid.sys.ini

Contains:

Module name
Module description

Example:

MOD_SERVICESGRID=”Services Grid”
MOD_SERVICESGRID_XML_DESCRIPTION=”Displays services in a responsive grid.”

Using language files makes your extension multilingual and Joomla-standard compliant.

Step 7: Create the Frontend Layout

File:

tmpl/default.php

This file controls the HTML output.

Responsibilities:

Read services data.
Loop through service items.
Generate grid markup.
Display titles and descriptions.

Typical process:

Read module parameters.
Decode subform data.
Loop through services.
Display service cards.

This keeps presentation separate from business logic.

Step 8: Add CSS Styling

File:

media/css/style.css

This file controls the appearance of the services grid.

You can style:

Grid layout
Card spacing
Hover effects
Typography
Mobile responsiveness

Recommended design:

3 columns on desktop
2 columns on tablet
1 column on mobile

Keeping styles in a separate CSS file makes future customization easier.

Step 9: Load CSS Assets

Register the stylesheet from the module entry file.

Purpose:

Ensure CSS loads only when the module is used.
Improve maintainability.
Follow Joomla 5/6 best practices.

The CSS file should be loaded using Joomla’s Web Asset Manager whenever possible.

Step 10: Package the Module

Before installation, verify:

Required Files
mod_servicesgrid.php
mod_servicesgrid.xml
forms/service.xml
tmpl/default.php
media/css/style.css
language files
Create ZIP Package

The ZIP root must contain:

mod_servicesgrid.xml
mod_servicesgrid.php
forms/
tmpl/
media/
language/

Do not place everything inside an extra folder when creating the ZIP.

Step 11: Install the Module

Navigate to:

System → Extensions → Install

Upload:

mod_servicesgrid.zip

If installation succeeds:

  • Create a new module instance.
  • Select a module position.
  • Assign menu items.
  • Publish the module.

Step 12: Add Services

Open the module settings.

You will see the Services Subform field.

Click:

Add Service

Fill in:

Service Title
Description
Icon
Link

Add as many services as needed.

Save the module.

Step 13: Test the Frontend

Visit the frontend.

Verify:

Services display correctly.
Grid layout is responsive.
Language strings load correctly.
Styling is applied.

Also test on mobile devices.

Step 14: Troubleshooting Common Errors

Language File Missing

Cause:

Incorrect language path.
Missing language files.

Solution:

Verify language folder structure.

Class “JText” Not Found

Cause:

Using Joomla 3 code.

Solution:

Use:

use Joomla\CMS\Language\Text;
Form::getInstance() Could Not Load File

Cause:

Subform XML file missing.

Solution:

Verify:

forms/service.xml

exists and is included in the manifest.

Module Not Displaying

Cause:

Module unpublished.
Wrong position.
Menu assignment issue.

Solution:

Check module settings and template positions.

Conclusion

You have successfully created a Joomla 5/6 Services Grid Module using:

Custom module architecture
Joomla Subforms
Language files
Responsive CSS
Joomla best practices

This foundation can easily be expanded to include icons, images, animations, AJAX loading, or custom field types for more advanced projects.

Index
Scroll to Top