Custom Modules
Goal: Demonstrate ability to develop custom modules using Drupal API for extending Drupal functionality.
To illustrate the module creation process, you can follow along with the instructions on this page to create a custom module called hello_world
(adapted from Creating Custom Modules).
Create Module Skeleton
Naming Your Module
From Naming and placing your Drupal 8 module:
There are some important rules to follow when selecting a machine name:
- It must start with a letter.
- It must contain only lower-case letters and underscores.
- It must not contain any spaces.
- It must be unique. Your module may not have the same short name as any other module, theme, or installation profile you will be using on the site.
- It may not be any of the reserved terms :
src
,lib
,vendor
,assets
,css
,files
,images
,js
,misc
,templates
,includes
,fixtures
,Drupal
.
For example: hello_world
Once you've selected a machine name, create a new directory for your module inside /modules/
. It is recommended to use your machine name.
For example: /modules/hello_world
{modulename}.info.yml
By creating a {modulename}.info.yml
inside your module, you notify Drupal that your module exists.
For example - hello_world.info.yml
:
name: Hello World Module
description: Creates a page showing "Hello World".
package: Custom
type: module
core_version_requirement: ^10
Module Keys
The following keys are available for modules:
- name (required) - The human-readable name. This will appear on the "Extend" page where the module is activated.
- type (required) - Indicates the type of extension, i.e., "module", "theme", or "profile". For modules this should always be set to "module".
- description (optional) - The description, displayed on the "Extend" page.
- package (optional) - Specifies a "package" that allows you to group modules together.
- core_version_requirement (required) - Specifies the version of Drupal core that the theme/module is compatible with. Usually ^10 || ^11 indicating Drupal 10 or 11.
- php (optional) - The minimum version of PHP required. Defaults to value of
DRUPAL_MINIMUM_PHP
constant. - version (optional) - Specifies a version. For modules hosted on drupal.org, the version number will be filled in by the packaging script. Do not specify it manually, but leave out the version line entirely.
- dependencies (optional) - List of other modules a module is dependent upon e.g. drupal:views.
- test_dependencies (optional) - List of other modules a module is dependent upon for testing purposes. Test dependencies should be added and committed to your repo prior to writing tests that rely on those dependencies so that testbot can properly download them.
- hidden (optional) - Indicates whether or not to hide the module from the "Extend" page so that it cannot be enabled/disabled via the UI.
- required (optional) - Boolean value which means your module must be enabled and cannot be uninstalled.
More at Let Drupal know about your module with an .info.yml file
Adding a Controller
Module controllers should live inside src/Controller
directory inside your module.
For example - src/Controller/HelloController.php
:
<?php
namespace Drupal\hello_world\Controller;
use Drupal\Core\Controller\ControllerBase;
class HelloController extends ControllerBase {
/**
* Display the markup.
*
* @return array
*/
public function content() {
return [
'#type' => 'markup',
'#markup' => $this->t('Hello, World!'),
];
}
}
This example controller simply returns a render array containing the translatable string 'Hello, World!'
.
Adding a Route
Next you can add a route, exposing the controller's content via URL.
For example - hello_world.routing.yml
:
hello_world.content:
path: '/hello'
defaults:
_controller: '\Drupal\hello_world\Controller\HelloController::content'
_title: 'Hello World'
requirements:
_permission: 'access content'
After adding this route, clear your cache and then navigate to /hello
in your browser to see the controller's returned content.
See Essential APIs: Routing System for more details about the Drupal routing system.
Adding a Menu Link
Next you can add a link for this module page under Configuration
-> Development
in the admin panel.
For example - hello_world.links.menu.yml
:
hello_world.admin:
title: 'Hello module settings'
description: 'example of how to make an admin settings page link'
parent: system.admin_config_development
route_name: hello_world.content
weight: 100
See Essential APIs: Menu API for more details about the Menu API.
Additional Resources
- Creating Modules on drupal.org
- Naming and placing your Drupal modules on drupal.org - updated Feb 2023
Questions
What is the purpose of a custom module in Drupal?
A custom module in Drupal is a set of PHP, JavaScript, and CSS files used to extend the functionality of a Drupal website. Custom modules allow developers to add new features or modify existing ones to meet specific requirements.
How to create module skeleton in Drupal?
The first step in creating a module is to choose a "short name", or machine name (Naming Your Module) and creating a {modulename}.info.yml
, and adding a Controller > Module controllers should live inside src/Controller
, adding a Route > add a route, exposing the controller's content via URL and adding a Menu Link > add a link for this module page under Configuration -> Development
in the admin panel.
What are Module Keys in Drupal?
name (required)
- human-readable name
type (required)
- indicates the type of extension, i.e., "module", "theme", or "profile"
description (optional)
- displayed on the "Extend" page
package (optional)
- specifies a "package" that allows you to group modules together
core_version_requirement (required)
specifies the version of Drupal core that the theme/module is compatible with. Usually ^10 || ^11
indicating Drupal 10 or 11
php (optional)
The minimum version of PHP required. Defaults to value of DRUPAL_MINIMUM_PHP
constant
version (optional)
version of your module
dependencies (optional)
- list of other modules a module is dependent upon e.g. drupal:views