A module is a collection of functions that link into Backdrop, providing additional functionality for your Backdrop installation. Modules are the essential functional building blocks of a Backdrop site. The list of available modules on a site can be viewed /admin/modules/list (Functionality > Modules).

Sample module template

There is a template of a sample module on GitHub. You can use this as a "skeleton" for your own module; just change my_module everywhere to the name of your desired module, then modify the individual functions and/or add your desired additional functionality.

Contents of a module directory

Modules are comprised of a module directory, usually named after the main module it contains, containing files and directories. Core modules are found in the BACKDROP_ROOT/core/modules directory; contributed modules in the BACKDROP_ROOT/modules directory. A module directory may have the following example structure (although not all of these are required, as explained below):

BACKDROP_ROOT/modules
    my_module
        my_module.info
        my_module.module
        my_module.theme.inc
        my_module.admin.inc
        my_module.pages.inc
        css
            my_module.css
            my_module.admin.css
            my_module.theme.css
        js
            my_module.js
            my_other_js.js
        templates
            my_module_display.tpl.php
            another_display.tpl.php
        config
            my_module.settings.json
        libraries
            libname
                libname.php
                libname.css
                libname.js
        includes
            my_module.class.inc
        modules
            submodule
                submodule.info
                submodule.module
        tests
            my_module.tests.info
            my_module.test
        LICENSE.txt
        README.md

About the module file components

The .info file

All modules require an .info file to tell Backdrop about the module. Contents of a module .info file may vary and are explained in greater detail below. The internal name of the module is also derived from this file. For example, if it is named "my_module.info", then Backdrop will see the name of the module as "my_module".

The .module file

The .module file usually contains the code which allows a module to do its magic. 

Module files begin with the opening <?php tag. As per the Coding standards, omit the closing ?> tag. Including the closing tag may cause strange runtime issues on certain server setups. (Note that the examples in documentation will show the closing tag for formatting reasons only and you should not include it in your real code.)

All functions in your module that will be used directly by Backdrop are "hooks" named {modulename}_{functionname}, where "functionname" is a pre-defined function name suffix. Backdrop will call these functions to get specific data, so having these well-defined names means Backdrop knows where to look. We will come to hooks in a while.

Other contents of the module directory.

The .info and .module files are the only required files. Other files may be included to allow the module to work. The sample files shown in My Module above demonstrate the recommended conventions for organizing additional files within the module directory.

.theme.inc, .admin.inc, and.pages.inc files are recommended to be kept in the root of the module folder to allow ease of recognition of the way the module likely works. This makes it more obvious that the module provides theme functions, has an admin page, and probably provides display pages in some way. If there are multiple of these files however, it is reasonable to move these files to an includes folder in the module root.

JavaScript files are always kept in a /js folder, CSS in a /css folder, templates in a /templates folder, and tests in a /tests folder, as demonstrated in My Module above. CSS files follow a particular naming convention, see CSS naming conventions.

 

More about module .info files

The following is a sample .info file:

name = Dragon Builder
description = Provides a list of dragons.
backdrop = 1.x
package = Views
tags[] = Development
tags[] = Layouts
type = module
dependencies[] = views
dependencies[] = panels
configure = admin/config/content/example

The .info file should have the same name as the .module file and reside in the same directory. For example, if your module is named example.module then your .info file should be named example.info.

This file is in standard .ini file format, which defines properties in key/value pairs separated by an equals sign (key = value). You may use quotation marks to wrap the value. Quoted values may contain newlines.

.info files may contain comments. A semi-colon [;] placed at the beginning of a line makes that line a comment, and that line will not be parsed.

Note: Whenever you create or change your .info file, you will need to clear your site's cache for your changes to take effect.

Properties

The .info file can contain the following properties:

name (Required)
name = Really Neat Widget

This displays the name of your module, which will appear on the Modules page. The general rules that apply to module names are:

  • Since module names are proper names, they should be capitalized as such (capitalize all words in the name - including any "helper" words, such as "the", "of", "for" etc.). So it should for example be "Cool Things For Sites"; not "cool things for sites", nor "Cool things for sites", nor "Cool Things for Sites").
  • It should be a human-readable name (not "cool_things_for_sites").
  • If your module name includes an acronym (CSS, WYSIWYG, UI, etc.) or a third-party trade name (jQuery, JavaScript), of course follow the official capitalization for those (the way their owners capitalize them).

description (Recommended)
description = Provides a really neat widget for your site's sidebar.

A short, preferably one-line description that will tell the administrator what this module does on the module administration page. Remember, overly long descriptions can make this page difficult to work with, so please try to be concise. This field is limited to 255 characters.

Descriptions can contain links to documentation and sources. The following example shows a link to the author. It could be a link to a documentation node on Backdropcms.org. This is useful when the online documentation is better than the README.md file, and when you want to read about a module before switching it on.
description = Domain manager by <a href="http://dragonbuilder.com">DragonBuilder.com</a>.

backdrop (Required)
backdrop = 1.x

The version of Backdrop that your module is for. For Backdrop this would be 1.x, etc. Note that modules cannot specify the minor version of a branch of Backdrop. 1.x is correct; 1.2 is not.

type (Required)
type = module

The type of project. For a module, this will always be "module". Other available types are "theme" or "layout". Although this property is not required to enable the module, it is required to properly package the module on BackdropCMS.org and thus should always be included.

stylesheets (Optional)
stylesheets[all][] = node.css

Backdrop allows you to add CSS files in the module's .info file if it should be added on every page, just like theme .info files do. This is an example from the node module's .info file.

scripts (Optional)
scripts[] = somescript.js

You can now add Javascript in the module's .info file if it should be added on every page. This allows Javascript to be aggregated in an optimal way, and is the preferred method of adding Javascript that most visitors will need on a typical site visit.

files (deprecated)

Backdrop does not support loading of Classes from the .info files[] array, but uses the new hook_autoload_info(). See the change record "The class registry has been replaced with a static class map" for further information.

dependencies (Optional)
dependencies[] = taxonomy
dependencies[] = comment

An array of other modules that your module requires. If these modules are not present, your module cannot be enabled. If these modules are present but not enabled, the administrator will be prompted with a list of additional modules to enable and may choose to enable the required modules as well, or cancel at that point.

The string value of each dependency must be the module filename (excluding ".module") and should be written in lowercase. Spaces are not allowed.

If you need to specify that a certain module's version number is required Backdrop provides a way for this in the dependencies[] field. Version numbers are optional and only necessary if the module absolutely requires another module's specific version or branch.

The syntax for the dependencies[] field(s) is:

dependencies[] = modulename (major.minor.bugfix)

Where major is the numeric major version number and minor is the numeric or alphanumeric minor version number. x can be used to denote any minor or bugfix version. Some examples follow.

dependencies[] = exampleapi (1.x)
In the above .info code, the "Example" module requires an "Example API" module with the major version of 1 and any minor version.

dependencies[] = exampleapi (1.0.0)
This means that the module requires the 1.0.0 (and only the 1.0.0) version of the Example API module.

dependencies[] = exampleapi (1.x)
The above module requires any minor version of the module in the 1.x branch (1.0.0, 1.0.1, 1.1.0, 1.2-beta4, etc.)

The dependencies[] property in the .info file can also optionally specify versions:

dependencies[] = exampleapi (>1.0.0)
The above module requires any version greater than version 1.0.0.

You can optionally specify the core version number as well:
dependencies[] = exampleapi (>1.x-1.5.0)

The above module requires a 1.x version compatible version of the module and a version greater than 1.5.

Additionally, multiple version dependencies can be specified as comma-separated values within the parentheses:

dependencies[] = exampleapi (>1.0, <=3.2, !=3.0)

This facility can be used to specify a minimal core version by using system as the module name:

dependencies[] = system (>=1.5.3)
This makes the module require at least Backdrop 1.5.3.

package (Optional)
package = Views

If your module comes with other modules or is meant to be used exclusively with other modules, enter the name of the package here. If left blank, the module will be listed as 'Other'. In general, this property should only be used by large multi-module packages, or by modules meant to extend these packages, such as Fields, Views, Commerce, Organic Groups, and the like. All other modules should leave this blank. As a guideline, four or more modules that depend on each other (or all on a single module) make a good candidate for a package. Fewer probably do not. An exception to this rule is the "Development" package, which should be used for any modules which are code development tool modules.

If present, the package string groups modules together on the module administration page (admin/modules); the string should therefore be the heading you would like your modules to appear under, and it needs to be consistent (in spelling and capitalization) in all .info files in which it appears. It should not use punctuation and it should follow the Backdrop capitalization standard as noted above.

Capitalization is important because package string is case sensitive, and using package = fields in one module and package = Fields in another would yield two different packages on the module administration page. This can be highly confusing as Seven (the default administrative theme) capitalizes fieldset legends, making fields and Fields indistinguishable. Using package = Fields is the correct way.

For a complete list of Packages as provided by Backdrop core, see Module "Packages" and "Tags".

tags (Optional)
tags[] = Development
tags[] = Layouts

Tags are meant to supplement the "package" grouping. They are intended to better suit modules that either have no suitable package, or for those that have many suitable packages.

Choose any number of tags for your contributed module. Core packages may also be used as tags. If there are no suitable tags, feel free to add your own! Note: your module's package will automatically be included as a tag, there is no need to duplicate the Package.

For a complete list of Tags as provided by Backdrop core, see Module "Packages" and "Tags".

php (Optional)
php = 5.3

Modules and themes may specify a minimum PHP version that they require.

That specifies that the module/theme will not work with a version of PHP earlier than 5.3. That is useful if the module makes use of features added in later versions of PHP (improved XML handling, object iterators, JSON, etc.). If no version is specified, it is assumed to be the same as the required PHP version for Backdrop core. Modules should generally not specify a required version unless they specifically need a higher later version of PHP than is required by core. See the PHP Manual for further details on PHP version strings.

version (Optional)
version = 1.0.2

You can give your module whatever version string is appropriate.

configure (Optional)
configure = admin/config/content/example

The path of the module's (main) configuration page.
If a module is enabled, a "Configure" and "Permissions" link appear. This will be the path of the "Configure" link for this particular module on the modules overview page.

required (Optional)
required = TRUE

Modules and themes may specify that they are absolutely required and should never be disabled by adding required = TRUE. These modules will be enabled automatically during install. In most cases it should only be used with the Backdrop core required modules (e.g. Node, User, etc.). Setting this property to TRUE will also automatically hide the module/theme from the module/theme listing pages.

disabled (Optional)
disabled = TRUE

If this property is specified for a module or a theme and its value set to TRUE, then the project will be visible in the list of modules/themes, but the checkbox for enabling/disabling it will be locked. Although this property may not be useful to be set directly in the .info file, it may be altered via a HOOK_system_info_alter() hook implementation to prevent (other) modules/themes from being disabled when certain conditions apply.

hidden (Optional)
hidden = TRUE

Modules and themes may specify that they should not be visible on the modules page by adding hidden = TRUE. This is commonly used with testing modules used with SimpleTest where end-users should never enable the testing modules.

About hooks

Hooks are fundamental to Backdrop modules. They allow you to integrate your module into the actions of Backdrop core.

A Backdrop module is a collection of files containing some functionality and is written in PHP. Because the module code executes within the context of the site, it can use all the functions and access all variables and structures of Backdrop core. In fact, a module is no different from a regular PHP file that can be independently created and tested and then used to drive multiple functionalities.

This approach allows Backdrop core to call at specific places certain functions defined in modules and enhance the functionality of core. The places where code can be executed are called "hooks" and are defined by a fixed interface.

Hooks are how modules can interact with the core code of Backdrop. They make it possible for a module to define new urls and pages within the site (hook_menu), to add content to pages (hook_block), to set up custom database tables (hook_schema), and more. This page lists the hooks provided in the core, but modules can define hooks of their own.

Hooks occur at various points in the thread of execution, where Backdrop seeks contributions from all the enabled modules. For example, when a user visits a help page on a Backdrop site, as Backdrop prepares to save a node it will give each module a chance to alter the $node object. It does this by scanning all the module code for functions that have the name MYMODULE_node_update($node), where MYMODULE is the module's name, e.g., the block module's node update hook is called block_node_update. MYMODULE can then act on the $node object which is being updated.

A hook can be thought of as an event listener in the sense that an event triggers an action. The event in Backdrop, such as deleting a node, would trigger the hook hook_delete. If your module implemented hook_delete, that function would run when a node deletion occurred. As an example, your function might be to decrease the count of the total number of nodes, so when a node was deleted, your function would be called and lower the count by 1.

See also the overview of module hooks, in the Backdrop API Reference.

An example hook

  • hook_menu allows you to define a menu item that Backdrop will respond to at a path
    • If you are writing a module named my_module then you can define some path(s) where the module will provide content, user facing forms, or admin config forms with hook_menu. Here is an example where we want to consume a feed from an external data source:

/**
* Implements hook_menu().
*/
function my_module_menu() {
  $items['my-path'] = array(
    'title' => 'My Feed',
    'description' => 'Get data from another website feed, parse it and display it on our Backdrop site.',
    'page callback' => 'my_module_get_data',
    'access callback' => TRUE,
  );
  return $items;
}

Let's break down the elements here:

  • 'title' => 'My Feed',
    • Sets the title on the page, replace "My Feed" with the title you want for your page.
  • 'description' => 'Get data from another website feed, parse it and display it on our Backdrop site.',
    • Describe the page you are going to display to users.
  • 'page callback' => 'my_module_get_data',
    • This tells backdrop about the callback function to use for the page. When Backdrop receives a request in this case at example.com/my-path the hook my_module_menu will tell that request to use the callback function in this case my_module_get_data.
  • You would then define the function my_module_get_data later in the my_module.module file. That might look something like this:

/**
* Callback function for the path my-path.
* Process the data from the feed and define output markup.
*
* return string $markup
*   The $markup to return for the page request to /my-path
*/
function my_module_get_data() {
  // Make request to external data feed, parse, and store in $markup variable.

  return $markup;
}
  • 'access callback' => TRUE,
    • The access callback to use for this path. In this case TRUE indicates that anyone including anonymous users can see the content at this path.

Enabling modules

To interact with Backdrop, modules need to be first enabled. Click on Functionality > Modules on the Admin Bar in the Backdrop installation and search for the desired module in the list, or find the module by typing into the Fast Search field. Enable the module and click 'Save configuration'.

Testing with SimpleTest

Backdrop includes testing capabilities in core. The Backdrop SimpleTest module is based on the SimpleTest PHP Library. If you are familiar with that framework, you should have no trouble learning its application in Backdrop.

Backdrop testing focuses on functional testing rather than unit testing. Functional tests check the interface as a whole rather than individual functions or finite pieces of code. This approach is more effective for the way Backdrop is written.

Part of the challenge of writing good tests is knowing what you need to test. The information you'll get from these tests won't tell you much about how the module really functions. These tests will expose you to the testing environment and several of the assertions.

Submitting a contrib module

The Backdrop development community uses GitHub to manage contrib modules. If you are not familiar with GitHub, you can read through some excellent documentation available on GitHub and other sites.

To get started, find instructions at https://github.com/backdrop-ops/contrib.