Creating a Module in Drupal 8

22/02/2016
Crear un módulo en Drupal 8

The first step to creating a module is to choose a short name or ¨machine name.¨ This name will be critical later for the definition of files and functions within the module.  Additionally, it will be used by the core of Drupal to identify the unambiguous form of the module.

The machine name must meet all of the following conditions

·         It must begin with a letter

·         It must contain only lowercase letters and underscores

·         It must be unique; it cannot coincide with another module, theme, or profile

·         It must not contain any of the following reserve words: src, lib, vendor, assets, css, files, images, js, misc, templates, includes, fixtures, Drupal

For this first module, we will select the machine name, “hello_world”.

Once the name is selected, it is time to create the folder in modules/custom/hello_world or /sites/all/modules/custom/hello_world.  However, you should use the first route because the second route will disappear in future versions and is only compatible with previous versions.

NOTA: It is not necessary to utilize the machine name as the name in the folder, although it is recommended to maintain the uniformity and structure of the code.

 

Once we have created our folder, we should create our first file .info.yml inside it.  This file is necessary to:

·         Notify Drupal of the existence of the module, theme, or installation profile

·         Provide information about the administrative pages of Drupal

·         Provide a control system for the activation/deactivation of the module

·         Internally manage diverse aspects

Knowing this, we create our file hello_world.info.yml with the following content:

name: Hello World Module
description: Creates a page showing "Hello World".
package: Custom

type: module
core: 8.x

Let´s take a moment to describe the content of the file:

·         The first three lines are used by the Drupal modules administration for the activation/deactivation of the module.

·         The name and description (both required) provide additional information and the ‘package’ allows it to create logical packages within the list of Drupal modules.

·         The end type is new in the version and indicates what type of extension is creating a module, theme, or profile.

·         The end ‘core’ indicates the version so that it will be available in this module.  It is a field required by Drupal.

Although these are required fields, we should be able to include many other parameters within this configuration file.

name: Hello World Module
description: Creates a page showing "Hello World".
package: Custom

type: module
core: 8.x

dependencies:
  - datetime
  - link
  - views

configure: hello_world.settings

hidden: true

# Note: do not add the 'version'  property yourself!
# It will be added automatically by the packager on drupal.org.
version: 1.0

 

Let’s take a moment to describe the new parameters.

·         dependencies: indicates the necessity for other modules to exist in order to activate our module.

·         configure: if the module has a configuration page, there we can establish the route of said page.  This route will appear as a link in the list of Drupal´s modules with our module.

·         hidden: allows us to hide our module from the list of modules.  It is useful if we are working on a development module that should not appear in the list of modules.  Nonetheless, we are able to make it so that all the modules appear by adding the line $settings['extension_discovery_scan_tests'] = TRUE to our settings.php

To continue, we will spend some time creating a basic controller.  It is important to keep in mind that we should follow standard PSR-4 for the structure of the folders, thus our controller ought to be in /src/Controller/HelloController.php, and it should contain the following:

<?php
/**
 * @file
 * Contains \Drupal\hello_world\Controller\HelloController.
 */

namespace Drupal\hello_world\Controller;

use Drupal\Core\Controller\ControllerBase;

class HelloController extends ControllerBase {
  public function content() {
	return array(
    	'#type' => 'markup',
    	'#markup' => $this->t('Hello, World!'),
	);
  }
}
?>

In reality, this code by itself does not do anything.   It needs to be initiated by a routing file but, following the philosophy of the Drupal community, we should always proceed to: “Build a tool, then wire it up.”

Returning to the root of our module's folder, we create our routing file hello_world.routing.yml: 

hello_world.content:
  path: '/hello'
  defaults:
	_controller: '\Drupal\hello_world\Controller\HelloController::content'
	_title: 'Hello World'
  requirements:
	_permission: 'access content'

We emphasize several points in this regard:

·         The term ‘hello_world’ indicated in the first line must not necessarily coincide with the machine name of our module. However, it is considered good practice to do so.  The complete beginning ‘hello_world.content’ will be used later to add a link to the menu.

·         If we already have activated our module in Drupal, it will be necessary to clean the cache before we can run the path /hello and see our first module functioning.  Otherwise, it will be enough to go to /admin/modules to activate our module and run the path/hello.

Once we have confirmed that our module functions correctly, we will add a link to the menu.  To do that, we will create the file hello_world.links.menu.yml in the root folder of our module with the following content.

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

 

Some observations:

·         The first line is our reserved space, which should be the same as our routing file.

·         The fifth line makes use of the name of the defined route in the previous file.

This will add a link to the reference route in hello_world.content (hello_world.routing.yml in this case) within the page administration of our site below the settings tab (admin/config).

In order to see the resulting changes, we should clean the cache once again.

Interesting links:

·         The skeleton of a module in Drupal 8: http://cgit.drupalcode.org/sandbox-sidharrell-2466449/

·         Understanding the hooks system in Drupal https://www.drupal.org/node/292

·         Understanding yml files: https://www.drupal.org/node/2000204

·         Coding standards: https://www.drupal.org/node/318

·         What is PSR-4: http://www.php-fig.org/psr/psr-4/