If you're reading this, then you must find yourself in one of the following Drupal 8 module development scenarios:
- you've migrated your website from Drupal 7 to Drupal 8 and... surprise, surprise: one of the D7 modules needs to be developed from scratch now
- you've found a contributed module that's almost a perfect match for that custom functionality that you need for your project, so you need to tweak it a bit
- you need to implement a particular functionality and... there's no core or contributed module that you could use; so, you need to create a whole new Drupal 8 module
Now, you know how to configure a Drupal website.
And you know that Drupal's reputed for being conveniently extensible and flexible.
Extending Drupal 8 with a custom functionality, all while sticking to its coding standards and ensuring that your new module fits perfectly into the Drupal architecture, does pose quite some challenges.
And this is where a set of proven best practices for Drupal 8 custom module development comes in handy.
To give you a hand, I've interviewed 27 Drupal developers, of different levels, asking them to share the “golden rules” that they stick to when creating new modules in Drupal 8.
Here are the 18 recommendations that appeared most often in their answers:
#1 Best Practice: Debug Your Module with Xdebug
Use it with either Zend Studio or Eclipse.
Debugging your code, making sure that:
- there are no PHP code bottlenecks lingering in there
- you're using only the latest code
… is one of the golden rules to follow when you develop a Drupal custom module.
#2 Best Practice: Create a Dedicated Place for Your Custom Modules
Let's say you've named your module... “E_shop”.
In this case, you should name the new dedicated folder: “/module/custom/E_shop”.
Tip: you might be tempted to skip the “/custom” folder and name your folder “/sites/all/modules/E-shop” instead. Yet, it's better to create a dedicated place this type of modules, so you don't have to rummage all your modules (those downloaded from Drupal.org here included) whenever you need to look for a custom one.
#3 Best Practice: Give Your Module a “Proper” Machine Name
And by a “proper name” I mean one that follows the golden rules for naming a module in Drupal:
- to start with a letter
- to be unique
- to stick to the “lower-case letters + underscores” formula
- not to contain terms that are already taken (e.g. “misc”, “ src”, “Drupal”, “files”, etc.)
- not to contain spaces...
You can find all these rules listed on Github.
Word of caution 1: make sure your module's machine name contains no upper-case letters, otherwise your hook implementations will go unnoticed by Drupal.
Word of caution 2: make sure you don't go for a name that's already used by another core or contributed module that you'll be implementing in your project (for instance, instead of naming your module “views_baz”, you might want to go for... “bazify_views” instead).
#4 Best Practice: Add a “hook_theme” in Your “.module” File
A great practice when you're using Twig templates with custom blocks.
Word of caution: avoid naming the theming function “block_...”, as this won't transfer any variable to your twig templates. As an alternative, use your module's name as a prefix.
#5 Best Practice: Set Drupal to Show All Future Errors
Remember to switch on the PHP error reporting before you plunge into the Drupal 8 module development process.
This way, you'll get alerted about any error sneaking into your code as you're building the module.
Tip: if you're not that excited about the idea of having ALL the errors exposed and instead you want to get alerted only about those generated by your Drupal site, just run:
tail -f /var/log/apache2/error.log
... on your server.
#6 Best Practice: Keep the “Dot-Module” Light
And that because it's your “.module” file that gets loaded on every HTTP request.
#7 Best Practice: Create a “.info.yml.file” to Notify Drupal About Your Module
And this is a recommendation that you'll find in any “How to create a custom module in Drupal 8 step by step” guide.
Basically, this file, that stores metadata about your new custom module, notifies Drupal about your newly uploaded module.
Now, here's how you structure the medatada in your “info.yml.file”:
- name: enter your Drupal 8 module's name
- type: custom
- description: enter a detailed description of your module, one to be published on the module list page
- package: the one where your module should be included (“custom”)
- version: is this the 1st, 2nd, 3rd... version of your module?
#8 Best Practice: Create a New Module Only If (Really) Necessary
Another golden rule that 99% of the developers that I interviewed agreed upon was:
Whenever possible, reuse existing modules instead of jumping to write a whole new one, from the ground up.
That is because the heavier your “load” of custom modules grows, the more challenging it gets to maintain and update your Drupal 8 website later on.
Tip: a good Drupal 8 module development practice is to publish your modules in Github. This way, you'll have reusable code, that already includes the proper configuration, close at hand for your future projects.
#9 Best Practice: Mind You Don't Develop a Module that Already Exists
And this is strongly connected to the previous golden rule.
It's also one of the most common pitfalls that Drupal developers fall into:
Before you rush to create a custom feature for your project, check and... double check whether there isn't already a module for it.
#10 Best Practice: Put Your New Module into the “/modules” Directory
You're no longer restricted to placing your custom modules into the “/sites/all/modules” directory like it was the case in Drupal 7.
In Drupal 8, all the core modules go into the “/core” directory, so there's “room enough” for the contrib and the custom modules to be put in the “/modules” directory.
#11 Best Practice: Use Server-Side Validation for Drupal 8 Module Development
Another good practice that all the interviewed developers agreed upon:
Whenever you're doing client-side validation, remember to validate in the server side, as well.
#12 Best Practice: Go for a Logical Aggregation Hierarchy
This way, you ensure that all the features get included in one single module.
#13 Best Practice: Use Update Hooks
Another “golden rule” that most developers have mentioned when I asked them about their “module development in Drupal 8” routines:
A lot of your custom module's functionality will be in its blocks. Therefore, by using update hooks you'll control their location and visibility.
Which makes them quicker to update and to hardwire.
#14 Best Practice: Use an Automated Code Checking Tool Like Coder
Automation is key when you want to be 100% certain that the code you're writing:
- is clean
- is maintainable
- is readable (by both your teammates and any developer from the Drupal community)
- adheres to Drupal's coding standards
- follows the best practices for the PHP version that you're using
And a module like Coder helps you streamline all these code checking operations on your checklist.
#15 Best Practice: Commit the Vendor Files
It's a “must” practice rather than just “good” practice:
When you're doing Drupal 8 module development and you're implementing a custom feature that depends on vendor components, remember to commit the vendor files.
#16 Best Practice: Include Default Configuration in Your Module
Because it saves you from rewriting code each time you need to make an update.
In other words: you'll simply set the values in the configuration and apply it along with the code, instead of having to hard code a class into a theme.
The main benefits of including configurations in code when you develop custom Drupal 8 modules?
- faster ways to code
- reusable code (aka higher quality software)
- better quality code
- “easier to update” features
- more complex functionality
Here's an example for you:
Your configuration management system will be the one dealing with the content types creation and management process. So, you can add a content type to your new custom module by just setting up a correctly named and structured configuration file.
Tip: in Drupal 8, default configuration like field configuration, views, and content types are stored in plain YAML files, with the configuration system. Unlike in Drupal 7, where you had to use custom PHP code to keep them properly updated.
#17 Best Practice: Remember to Use Cache
Drupal 8 knows what to cache and what to skip.
#18 Best Practice: Use Drupal's Built-in Features
Drupal “spoils” you with plenty of admin functionalities that you should get the most of once you've created your new module.
Use them to store and to display your module settings and data.
And here's how precisely you store the settings:
- use “hook menu” to define your settings page
- use “drupal_get_form” page callback to define and to return the module settings that you need to store
I'm (overly) now:
What's the best practice on top of your own "Drupal 8 module development" list?
That golden rule that you'd never break...
Photo by True Agency on Unsplash