Are you ready to learn how to extend and customize Drupal sites in code? The Drupal Module Developer Guide will introduce you to extending Drupal with modules. You will learn foundational concepts and get hands-on practice with a variety of APIs used in Drupal coding and development. We'll be extending the site we built in the Drupal User Guide. If you're new to Drupal site building, we recommend that you walk through the Drupal User Guide first.
Drupal offers module developers several methods for creating different types of links, all defined by module configuration. This tutorial explores these types of links, how they relate to each other, and when to use them.
In this tutorial, we'll learn:
- The nature of menu items, action links, and local task links.
- Examples of each link type in Drupal's UI and their application in our scenario.
- Criteria for selecting the appropriate link type for adding the weather page to site navigation.
By the end of this tutorial, you'll understand the different types of links in Drupal and how they apply to adding navigational elements for custom module pages.
Permissions in Drupal control access to features and functions. Modules define permissions, which allow site administrators to grant or restrict access based on user roles. As a module developer, you'll create new permissions to restrict access to your module's custom features, independent of existing permissions defined by other modules.
In this tutorial, we'll:
- Explore how and where permissions are defined within a module.
- Discuss the concept of static and dynamic permissions in Drupal.
By the end of this tutorial, you'll have a clear understanding of how permissions function in Drupal and their implementation in modules.
Modules can define custom permissions to restrict access to specific routes or page sections. This control allows module developers to provide granular access while enabling site administrators to manage user privileges. We'll add a view weekly weather
permission via the anytown module to limit access to the weather page.
In this tutorial, we'll:
- Create an MODULE_NAME.permissions.yml file.
- Define a new permission.
- Use the new permission to restrict access to a route.
By the end of this tutorial, you should be able to define a new permission in a module and use it to control access to a route.
Custom services in Drupal modules encapsulate specific business logic or functionality. In our example, we'll demonstrate moving code required to access a weather forecast API from a controller into a service. This will help make our controller thin and our module code more reusable, testable, and maintainable.
In this tutorial, we'll:
- Explore the advantages of custom services for managing business logic.
- Define the components of a custom service.
By the end of this tutorial, you'll understand why creating custom services is a beneficial practice in Drupal module development.
To access services in Drupal through the service container, you'll need to know the unique machine name of the service. We'll use the example of making HTTP requests to a weather forecast API in the anytown module to demonstrate several methods you can use to identify an existing service's ID.
In this tutorial, we'll:
- Discover existing services and their machine names.
- Take a look at an example service definition.
By the end of this tutorial, you should be able to locate and use existing services in your Drupal module.
Concept: Testing
FreeTesting ensures that code remains reliable and functional. This tutorial introduces the primary types of tests in Drupal: Unit, Kernel, Functional, and FunctionalJavascript -- all executed via PHPUnit. We'll clarify the differences between each type of test and appropriate use cases. As module developers, understanding what to test and how to write tests is vital for robust and maintainable code.
In this tutorial, we'll:
- Identify the primary test types in Drupal and their use cases.
- Emphasize the importance of functional tests in custom module development.
- Introduce the basics of authoring tests in a custom module.
By the end of this tutorial, you should recognize the different types of tests Drupal uses and when and how to use each kind.
Before you can run tests, you'll need to configure your local environment. This setup involves Drupal-specific configuration for PHPUnit and ensuring your environment supports Functional JavaScript tests with a WebDriver client and a compatible browser. The setup process varies based on the development environment. In this tutorial, we're using DDEV as the local environment.
In this tutorial, we'll:
- Install all required dependencies.
- Configure PHPUnit specific to our environment.
- Validate the setup by running a Drupal core test.
By the end of this tutorial, you'll be equipped to run Drupal's PHPUnit tests locally using DDEV.
Functional tests simulate user interactions with Drupal applications, which enables us to test user interfaces and complex workflows. This tutorial guides you through writing functional tests for the anytown module, focusing on custom user registration workflow enhancements.
In this tutorial, we'll:
- Examine functional test structure.
- Test
anytown_form_user_register_form_alter()
customizations. - Discuss the functional test execution environment.
By the end of this tutorial, you'll know how to write functional tests that emulate browser interactions with your Drupal application.
Kernel tests in Drupal enable module integration testing with Drupal core systems in a bootstrapped environment. Kernel tests bridge the gap between unit and functional tests. This tutorial focuses on writing kernel tests for the anytown module, specifically to test the ForecastClient
service's caching logic and custom username validation.
In this tutorial, we'll:
- Explore the parts of a kernel test.
- Write kernel tests for anytown module features.
- Use mocks and the Drupal container in kernel tests.
By the end of this tutorial, you should be able to get started writing kernel tests to verify your module's integration with Drupal core.
Unit tests are the simplest among Drupal's test types, ideal for verifying code that performs computations. This tutorial guides through writing unit tests for the anytown module, focusing on the ForecastClient
service, and illustrates how to use mocks for dependencies.
In this tutorial, we'll:
- List potential unit tests for the anytown module.
- Write tests for
ForecastClient
service logic. - Demonstrate how to mock services in unit tests.
By the end of this tutorial you should be able to write PHPUnit Unit tests for logic in the anytown module.
As of Drupal 10.2, most plugin types use PHP attributes for discovery and metadata.
In this tutorial, we'll:
- Provide a recipe for implementing PHP attribute-based plugins.
- Demonstrate how to figure out where the code and metadata should live for PHP attribute-based plugins.
By the end of this tutorial you should have a recipe for getting started with implementing PHP attribute-based plugins, and a better understanding of how to figure out the details required to implement a given plugin type.
PHP attributes are a native PHP language feature, introduced in PHP 8.0, that provide a way to add metadata to classes, methods, properties, and functions in PHP code.
In Drupal, this metadata is used by the plugin system to aid in the discovery and configuration of plugin instances. As a Drupal developer, it's important to understand how to recognize, read, and write PHP attributes, as you'll encounter them when working with plugins.
In this tutorial we'll look at:
- What PHP attributes are
- The use case for attributes in Drupal
- An overview of the attribute syntax
By the end of this tutorial, you should understand how attributes are used in Drupal and how to write them in your own code.
Prior to Drupal 10.2 most plugin implementations required the use of annotations alongside a PHP class. Now Drupal supports and recommends the use of PHP attributes instead. During the transition, most developers will still need to know how to recognize and implement annotation-based plugins.
In this tutorial we'll:
- Provide a recipe for implementing annotation-based plugins.
- Demonstrate how to figure out where the code and metadata should live for annotation-based plugins.
By the end of this tutorial you should have a recipe for getting started with implementing annotation-based plugins, and a better understanding of how to figure out the details required to implement a given plugin type.
Many of Drupal's APIs that look like a bunch of configuration in a YAML file (migrations, menu links, etc.) are actually plugins in disguise. The YAML from these files is used as arguments to a generic PHP plugin class which then behaves differently depending on the provided values. As a developer, you probably don't need to know that menu links are plugins, but it can be helpful when debugging or just trying to get a better understanding of the big picture.
In this tutorial, we'll:
- Learn about how YAML-based plugins work
- Discuss how to find the implementation details for YAML-based plugins
- Walk through an example of implementing a YAML-based plugin
By the end of this tutorial, you should be able to recognize a YAML-based plugin definition, and author your own.
Upgrade to Drupal 11
FreeThere’s no one-size-fits-all path to upgrade from Drupal 10 to Drupal 11, but there is a set of common tasks that everyone will need to complete.
In this tutorial we’ll:
- Explain the differences between Drupal 10 and Drupal 11 that affect the upgrade path.
- Walk through the high-level steps required to upgrade from Drupal 10 to Drupal 11.
- Provide resources to help you create an upgrade checklist and start checking items off the list.
By the end of this tutorial you should be able to:
- Explain the major differences between Drupal 10 and 11.
- Audit your existing Drupal 10 projects for Drupal 11 readiness, and estimate the level of effort involved.
- Start the process of upgrading your site from Drupal 10 to Drupal 11.
We have half of our editorial process in place. Existing editorial groups can now edit content they are responsible for, and only that content. However, to enable editors to effectively manage the flow of articles coming in, we need something else: an editorial workflow system that allows them to easily determine when an article is ready for review, and to either send it back to the reporter when it needs more work, or to publish it on the site when it’s good to go.
Out of the box, Drupal allows a piece of content to be either published or unpublished. When the “published” checkbox is unchecked on the node editing form, only users with the “administer nodes” permission are allowed to view the content. That’s enough for some sites, but it doesn’t give our reporters and editors as much control as they need. For example, there’s no way for a reporter to mark an article as an in-progress draft and come back to it later. In addition, there’s no easy way for an editor to tell a reporter that an article needs more work—the editor must contact the author manually.
In this lesson, we'll get an overview of how the Workbench Moderation module can do this for us. We'll look at Workbench states and transitions, and how we use these to moderate our content.
Additional resources
The final step to complete our site for Our Media is to get the editorial workflow in place. In this lesson, we'll add moderation to the Article content type, create the correct States and Transitions we need, and then finish up by setting permissions so it all works the way we expect.
Additional resources
We now have our new editorial system in place and the Our Media site is ready to go. We’ve met the needs of our client, but there are some other modules that are also worth checking out:
We have more detailed instruction in another video on using the Views Bulk Operations (VBO) module.
Additional resources
Congratulations! The Our Media website now includes all the major features that the staff wanted. We’ve used the Workflow Access module to create a distributed system for content management, preventing collisions when editors review content they are responsible for. We’ve also provided the team with an editorial workflow, which makes it easy for them to track changes to content as it moves through the editorial process. On top of that, all of this is done in a consistent, easy-to-use interface, so editors quickly find the content they need. In this summary, we'll take a tour of the completed Our Media site, discuss our implementation points, and review the modules we used and discussed throughout the series.