Often, web applications and frameworks allow developers to customize and extend their functionalities. They differ in approach and nomenclature. Wordpress has plugins. In full stack Symfony, they are referred to as bundles, and in Drupal they are modules.

The module system in Drupal 8 has undergone many changes. Here, we take a brief look at some of the key differences.

Drupal 7

Modules, themes, and profiles are treated the same way. They must have unique machine names without spaces, e.g. "gradebook". For a module, you need:

Info file — gradebook.info

This file contains entries in php.ini format of "key = value", with only name and core being mandatory but description is recommended:

name = Gradebook
description = Allows management of grades for students
core = 7.x

Other optional keys are stylesheets, scripts, files, dependencies, package, php, version (not encouraged), configure, required, hidden, project (not encouraged), and project status url (not common).

The file is parsed whenever information is required on available modules on a site. You may check the usage of drupal_parse_info_file() which parses this Drupal-specific format into an array.

Module file — gradebook.module

This is where the PHP code is written. It must be present, even if it is empty. For example, a simple Gradebook content type feature module will only have something like this:


  include_once 'gradebook_ct.features.inc';

Sometimes, the size of a module file becomes unmanageable. Then, the code may be logically organized in *.inc files, which are included when necessary, e.g. gradebook.admin.inc, gradebook.pages.inc, gradebook.tokens.inc, etc. Often, the filename indicates the function it serves.

Include files may be loaded automatically, for example in a hook_menu implementation with the file and file path keys. Otherwise, they are loaded with module_load_include() function, which accepts 3 arguments — $type (the file extension), $module (the name of the module), and optional $name (the base file name of the include file), e.g.

module_load_include('inc', 'gradebook', 'gradebook.pages');

Drupal 8

This is a complete departure from earlier versions, and the module system has been revamped.

Info file — gradebook.info.yml

The info file is the only requirement for a module. The naming convention follows a familiar pattern of MODULE_MACHINE_NAME.info.yml, and its content must be in YAML format. Required keys are name, type, and core. For example:

  name: Gradebook
  type: module
  description: 'Allows management of grades for students.'
  core: 8.x

Optional keys are description, package, dependencies, test_dependencies, configure, and hidden.

The YAML Component is one of the Symfony components used in Drupal 8. This component is used to parse YAML strings and convert them to PHP arrays. Also, it can convert PHP arrays back to YAML strings.

YAML is a standardized way of representing data structures for all programming languages. Having a YAML component that implements features defined in the YAML specification boosts confidence in the format.

The full specification of .info files page gives detailed syntax changes from Drupal 7 to 8 with examples.

Configuration files

General site configuration files are in YAML format under config\install. The data structures in those files are described in separate YAML files stored in the config\schema folder.

Other *.yml files are placed in the main module folder. For example, gradebook.links.menu.yml, gradebook.links.task.yml, gradebook.permissions.yml, gradebook.routing.yml, and gradebook.services.yml. Their names usually follow a pattern of MODULE_MACHINE_NAME.FUNCTION.yml.

Module files

Even though there is a *.module file, it is optional. Most code is written in classes that are placed in a structured file directory prescribed by the PSR-0 and PSR-4 autoloading specification. Entities are stored in src\Entity, controllers in src\Controller, forms in src\Form, plugins in src\Plugin, etc.

Other files may be present. For example, Twig template files go in the templates folder. There may be separate folders for Javascript files, images, or CSS stylesheets.

Here is a sample structure:

├── config
│   ├── install
│   │   └── gradebook.settings.yml
│   └── schema
│       └── gradebook.schema.yml
├── gradebook.info.yml
├── gradebook.install
├── gradebook.libraries.yml
├── gradebook.links.action.yml
├── gradebook.links.menu.yml
├── gradebook.links.task.yml
├── gradebook.module
├── gradebook.permissions.yml
├── gradebook.routing.yml
├── gradebook.services.yml
├── src
│   ├── Controller
│   ├── Entity
│   ├── Form
│   └── Plugin
└── templates


Drupal 8 has changed the direction of the entire project. It follows the Object Oriented Programming (OOP) paradigm and uses existing components from other open source projects. However, vestiges of the old Drupal remain, as we have seen in this brief look at the module system.

Recommended reading

  1. Directory Structure
  2. A practical guide to building basic Drupal 8 modules
  3. Creating custom modules