Khanh Hoang - Kenn
Kenn is a user experience designer and front end developer who enjoys creating beautiful and usable web and mobile experiences.
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.
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:
name: Drupal 8 Demo module description: 'Demo module for Drupal 8 alpha11' type: module core: 8.x
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.
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:
demo.demo: path: '/demo' defaults: _content: '\Drupal\demo\Controller\DemoController::demo' _title: 'Demo' requirements: _permission: 'access content'
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:
<?php /** * @file * Contains \Drupal\demo\Controller\DemoController. */ namespace Drupal\demo\Controller; /** * DemoController. */ class DemoController { /** * Generates an example page. */ public function demo() { return array( '#markup' => t('Hello World!'), ); } }
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:
demo.demo: title: Demo Link description: 'This is a demo link' parent: system.admin_structure route_name: demo.demo
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.
In this article we began exploring module development in Drupal 8. At this stage (alpha11 release), 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. See you then.
Bình luận (0)
Add Comment