Home / Tutorials / Build a Drupal 8 Module: Routing, Controllers and Menu Links

Build a Drupal 8 Module: Routing, Controllers and Menu Links

Please be aware that due to the development process Drupal 8 has been undergoing at the time of writing, some parts of the code might be outdated. Take a look at this repository in which I try to update the example code and make it work with the latest Drupal 8 release.

Drupal 8 brings about a lot of changes that seek to enroll it in the same club other modern PHP frameworks belong to. This means the old PHP 4 style procedural programming is heavily replaced with an object oriented architecture. To achieve this, under the initiative of Proudly Found Elsewhere, Drupal 8 includes code not developed specifically for Drupal.

One of the most important additions to Drupal are Symfony components, with 2 major implications for Drupal developers. First, it has the potential to greatly increase the number of devs that will now want to develop for Drupal. And second, it gives quite a scare to some of the current Drupal 7 developers who do not have much experience with modern PHP practices. But that’s ok, we all learn, and lessons taken from frameworks like Symfony (and hopefully Drupal 8), will be easily extensible and applicable to other PHP frameworks out there.

In the meantime, Drupal 8 is in a late stage of its release cycle, the current version at the time of writing being alpha11. We will use this version to show some of the basic changes to module development Drupal 7 devs will first encounter and should get familiar with. I set up a Git repo where you can find the code I write in this series so you can follow along like that if you want.

How do I create a module?

The first thing we are going to look at is defining the necessary files and folder structure to tell Drupal 8 about our new module. In Drupal 7 we had to create at least 2 files (.info and .module), but in Drupal 8, the YAML version of the former is enough. And yes, .info files are now replaced with .info.yml files and contain similar data but structured differently.

Another major change is that custom and contrib module folders now go straight into the root modules/ folder. This is because all of the core code has been moved into a separate core/ folder of its own. Of course, within the modules/ directory, you are encouraged to separate modules between custom and contrib like in Drupal 7.

Let’s go ahead and create a module called demo (very original) and place it in the modules/custom/ directory. And as I mentioned, inside of this newly created demo/ folder, all we need to begin with is a demo.info.yml file with the following required content:

 

Three out of four you should be familiar with (name, description and core). The type is now also a requirement as you can have yml files for themes as well. Another important thing to keep in mind is that white spaces in yml files mean something and proper indentation is used to organize data in array-like structures.

You can check out this documentation page for other key|value pairs that can go into a module .info.yml file and the change notice that announced the switch to this format.

And that’s it, one file. You can now navigate to the Extend page, find the Demo module and enable it.

As I mentioned, we are no longer required to create a .module file before we can enable the module. And architecturally speaking, the .module files will be significantly reduced in size due to most of the business logic moving to service classes, controllers and plugins, but we’ll see some of that later.

What is ‘routing’ and what happened to hook_menu() and its callbacks?

In Drupal 7, hook_menu() was probably the most implemented hook because it was used to define paths to Drupal and connect these paths with callback functions. It was also responsible for creating menu links and a bunch of other stuff.

In Drupal 8 we won’t need hook_menu() anymore as we make heavy use of the Symfony2 components to handle the routing. This involves defining the routes as configuration and handling the callback in a controller (the method of a Controller class). Let’s see how that works by creating a simple page that outputs the classic Hello world!.

First, we need to create a routing file for our module called demo.routing.yml. This file goes in the module root folder (next to demo.info.yml). Inside this file, we can have the following (simple) route definition:

 

The first line marks the beginning of a new route called demo for the module demo (the first is the module name and the second the route name). Under path, we specify the path we want this route to register. Under defaults, we have two things: the default page title (_title) and the _content which references a method on the DemoController class. Under requirements, we specify the permission the accessing user needs to have to be able to view the page. You should consult this documentation page for more options you can have for this routing file.

Now, let’s create our first controller called DemoController that will have a method named demo() getting called when a user requests this page.

Inside the module directory, create a folder called src/ and one called Controller/ inside of it. This will be the place to store the controller classes. Go ahead and create the first one: DemoController.php.

The placement of the Controllers and, as we will see, other classes, into the src/ folder is part of the adoption of the PSR-4 standard. Initially, there was a bigger folder structure we had to create (PSR-0 standard) but now there is a transition phase in which both will work. So if you still see code placed in a folder called lib/, that’s PSR-0.

Inside of our DemoController.php file, we can now declare our class:

 

This is the simplest and minimum we need to do in order to get something to display on the page. At the top, we specify the class namespace and below we declare the class.

Inside the DemoController class, we only have the demo() method that returns a Drupal 7-like renderable array. Nothing big. All we have to do now is clear the caches and navigate to http://example.com/demo and we should see a Drupal page with Hello World printed on it.

In Drupal 7, when we implement hook_menu(), we can also add the registered paths to menus in order to have menu links showing up on the site. This is again no longer handled with this hook but we use a yml file to declare the menu links as configuration.

Let’s see how we can create a menu link that shows up under the Structure menu of the administration. First, we need to create a file called demo.menu_links.yml in the root of our module. Inside this yml file we will define menu links and their position in existing menus on the site. To achieve what we set out to do, we need the following:

 

Again we have a yml structure based on indentation in which we first define the machine name of the menu link (demo) for the module demo (like we did with the routing). Next, we have the link title and description followed by the parent of this link (where it should be placed) and what route it should use.

The value of parent is the parent menu link (appended by its module) and to find it you need to do a bit of digging in *.menu_links.yml files. I know that the Structure link is defined in the core System module so by looking into the system.menu_links.yml file I could determine the name of this link.

The route_name is the machine name of the route we want to use for this link. We defined ours earlier. And with this in place, you can clear the cache and navigate to http://example.com/admin/structure where you should now see a brand new menu link with the right title and description and that links to the demo/ path. Not bad.

Conclusion

In this article we began exploring module development in Drupal 8. At this stage, it is time to start learning how to work with the new APIs and port contrib modules. To this end, I am putting in writing my exploration of this new and exiting framework that will be Drupal 8 so that we can all learn the changes and hit the ground running when release day comes.

For starters, we looked at some basics: how you start a Drupal 8 module (files, folder structure etc), all compared with Drupal 7. We’ve also seen how to define routes and a Controller class with a method to be called by this route. And finally, we’ve seen how to create a menu link that uses the route we defined.

In the next tutorial, we will continue building this module and look at some other cool new things Drupal 8 works with. We will see how we can create blocks and how to work with forms and the configuration system.

 

About cmadmin

Web Developer & Designer | Android App Developer

Check Also

Symfony in Drupal 8

If you are a Drupaler, you must be aware that Drupal 8 is on the …

Building a Drupal 8 Module – EntityFieldQuery

Even though Drupal 7 core fell short of a proper way of handling its brand …

Leave a Reply

Your email address will not be published. Required fields are marked *

Login


Username
Create an Account!
Password
Forgot Password? (close)

Sign Up


Username
Email
Password
Confirm Password
Want to Login? (close)

Forget Password?


Username or Email
(close)
%d bloggers like this:
SHARE
OR
SUBSCRIBE
To get latest new / tutorial / technology / development information subscribe with us.
ARE YOU READY? GET IT NOW!
Lets Get Updated with latest trends & tutorials!
Your Information will never be shared with any third party.
Ready for latest tutorials & tools !
OR SUBSCRIBE WITH