Main menu

You are here

The Drupal 8 development cycle has introduced a massive shift in many of the underlying concepts which have traditionally provided the foundations for Drupal development. Chief among these concepts is the move to a Object-Oriented architecture based upon Symfony components rather than proceed with the previous procedural codebase.

While the intention of these moves has been to improve the developer experience (DX) of Drupal 8, these changes have provoked a consequential backlash (and fork) due to the scale of the changes being introduced.

I was myself initially skeptical of the changes incoming in Drupal 8. After spending a week reviewing the changes and helping out with some WSCCI issues, I've come to the conclusion that that changes in D8 are a net benefit for developers, and will go a long way to simplify the writing and maintenance of Drupal code.

At this point, the Drupal 8 learning curve is quite steep; this is due in a large part to the lack of consistent and updated documentation about how to work with the new concepts. This series of blog posts is an attempt to address that in part by covering some of the new module development concepts in D8, and to demonstrate that the changes in D8 aren't that difficult to understand once explained in a logical, progressive fashion.

This first post will cover creating a basic module to display a 'Hello World' page, and will cover the new concepts of menu routes and controller classes. Successive posts will build upon this foundation as we look at other new aspects of Drupal 8 module development.

This post series assumes that you are already familiar with the concepts of Object Oriented programming, and PSR-0 namespacing.

Disclaimer: This blog post series represents the state of Drupal 8 at the time this post was written; D8 is now in the 'API Completion' phase which means that for the most part, the information below should not change drastically. I will attempt to keep this post reasonably up-to-date as new developments or code changes make their way into Drupal.

Starting a module

In Drupal 8, the first step to creating a new module is to create a directory for your module in the /modules directory of your Drupal installation. For this example, we will create /modules/hello.

In Drupal 7, the /modules path contained all the core modules; in Drupal 8, core files have been moved into the core/ subdirectory. Core modules now exist at /core/modules.

In Drupal 8, .info files are no longer used; instead, we now use YAML-formatted .info.yml files. The format is very similar to the Drupal 7 .info files:

Create a hello.info.yml file similar to the above in your module folder.

As in Drupal 7, your next step is to create a hello.module file to hold hook implementations and supporting code.

Creating our menu items and routes

As in Drupal 7, your first step towards creating a new page for your module is to define a hook_menu() implementation. One of the changes introduced along with the Symfony routing system in Drupal 8 is the separation of the 'Menu' and 'Router' concepts.

In Drupal 8, the menu as defined in hook_menu() implementations describes the presentation of the menu. It defines the menu hierarchy/tree, breadcrumbs, and other 'user-visible' aspects of the menu system.

hello.hello_world is the machine name assigned to this route. The best practice is to prefix your routes with the name of your module. The route name (including it's prefix) must match what was specified in the 'route_name' key of your hook_menu() item.

The '_content' key describes the Controller class and method used to return the page content for this callback. By specifying '_content', we are specifying that the output of this controller is for the main content area of the page, and should be returned wrapped in all the other blocks and regions.

The '_permission' key defines a permission (defined in hook_permissions() as per Drupal 7) used to control access to this route.

Menu items which would have been created as menu callbacks in Drupal 7 only need a routing.yml entry in Drupal 8. They can be omitted from the hook_menu() implementation entirely.

Creating our Controller

Our next step is to create the Controller class and method that defines our callback.

In our route declaration, we declared that our controller class is called '\Drupal\hello\Controller\HelloController'. Currently, all module classes provided in Drupal 8 must live in PSR-0 directories under /modules/<module>/lib. This means that our new Controller class must live in /modules/hello/lib/Drupal/hello/Controller/.

Note: There is currently an issue in the Drupal 8 issue queue to use PSR-4 for module classes to remove some of the path redundancy, so a class like our controller class can live at /modules/hello/lib/Controller/HelloController.php. See #1971198: [meta] Drupal and PSR-0/PSR-4 Class Loading.

Create a new file called 'HelloController.php' in /modules/hello/lib/Drupal/hello/Controller/, so the final path of the controller class file is /modules/hello/lib/Drupal/hello/Controller/HelloController.php.