
In addition to using one of the existing generators, developers can write their own Drush generator commands. This can help speed up repetitive tasks and reduce the use of boilerplate code that is prone to human error.
Generators are provided through Drush's integration with the Drupal Code Generator project. Writing new generators isn't specific to Drush, though if you're creating generators for Drupal it is definitely easiest with Drush as a wrapper.
Similar to Drush commands, generators can be supplied by a Drupal module or declared globally. If you have a feature-specific functionality, it's best to ship your custom generator within the custom module. Otherwise, a global generator can be declared and used.
In this tutorial we'll:
- Explain the anatomy of a Drush generator
- Write a custom Drush generator for handling a site's development.services.yml file, and use it in a project
By the end of this tutorial you should understand how to create, or customize, a Drush code generator and use it in your project.
One of the problems that Drush solves for developers is the automation and optimization of routine tasks. Drush commands attempt to speed up workflows and tasks that developers and site maintainers would otherwise have to do manually through the UI, or run one-by-one via the command line. One of those tasks is the process of deploying changes to a Drupal application from one environment to another.
The typical Drupal deployment process consists of repeatable steps such as importing configuration changes, applying database updates, and clearing the cache. Drush comes with the handy drush deploy
command that allows you to automate the execution of all of these tasks post code deployment.
In this tutorial we'll:
- Learn about the
drush deploy
command - Discuss when you would use the
deploy
command
By the end of this tutorial you'll know how to use the drush deploy
command in conjunction with other useful deployment-related commands to help automate the task of deploying changes to a Drupal site's configuration and code.
Code generators are great productivity boosters that allow generating scaffolds for common development tasks in Drupal. One of the most common use cases for generators is scaffolding the code required for a custom entity type. Custom entities require many files and complicated annotations in order to function properly. There is a lot of boilerplate code that is more-or-less the same for every entity type. Creating all the files is repetitive, time-consuming, and prone to human error. Generators can help automate this task and make creating your own custom entity types quicker.
In this tutorial we'll:
- Learn how to generate the code for a custom entity with Drush
- Learn about the options that generators provide for custom entities
By the end of this tutorial you should know how to generate custom entities with Drush.
Some Drush commands return a lot of information -- lists of modules, generators, and status reports, for example. It might be hard to find a property you need in the small command window output. Luckily, the output of Drush commands can be piped to other commands, used as a source for imports, settings for CI, and other DevOps tasks.
In order to accommodate all these different use cases, Drush comes with a formatting system that allows you to format and filter output to meet your needs. This system allows to you specify what fields you want returned when the output contains more than one field. It also allows Drush command output to be formatted as JSON, XML, raw PHP, a table, and more.
In this tutorial we'll:
- Learn how to specify the output format -- and what formats are available
- Limit the fields that are returned in a report
- Learn to filter the output to only the data we're interested in
By the end of this tutorial you'll know how to format a Drush command's output to fit your needs.
If you want to change the way an existing Drush command works, you use hooks. Hooks are useful for altering command parameters, options, attributes data, and adding custom logic during particular stages of the command execution process. Drush hooks are conceptually similar to Drupal hooks.
Hooks are methods on a Drush command class with an attribute indicating what hook is being implemented, and thus when the code should be invoked. The code in the methods is executed during specific stages of the command cycle. Developers can use core hooks -- predefined methods that come with Drush core -- or declare a custom hook that other commands can use.
In this tutorial we'll:
- Explore the different core Drush hooks
- Learn which hooks are called at what stage of the command cycle
- View example hook attributes and method implementations
By the end of this tutorial you'll know what types of core hooks are available to you and when they are called.
Adding logging and error handling are an important part of authoring Drush commands. Logs allow developers to get timely feedback from a command and inform users about potential alterations and flags, events to monitor, and the progress of long-running commands. Correct error handling allows for clean exits, meaningful error descriptions, and provides a path forward for developers to fix the errors and accomplish their goals.
In this tutorial we'll:
- Explore the different types of logging messages Drush commands can output
- Learn how to handle errors from within a Drush command
By the end of this tutorial you'll know what types of log messages you can use; how to log success messages, errors, or debug statements from a custom Drush command; and how to handle errors and exceptions.
When the logic of a command depends on user input, it's useful to set up an interactive questionnaire inside the command code. This allows you to provide the user with more context about the input they're providing, and ensure that you collect all the necessary values. This is especially useful when the command uses a pre-defined list of options and the values require memorization. An example of this is the drush cache-clear
command that comes with Drush core. It requires an argument indicating which cache to clear, which you can specify at the command line; however, if you invoke the command with no arguments it will present you with a list of cache bins to choose from and a UI for selecting one.
Drush 9+ can access the Input/Output (I/O) object via the $this->io()
method. This object -- an instance of \Drush\Style\DrushStyle
-- holds information about user-provided input, and utilities for manipulating that input. To ask a user a question, use an io()
object in the command callback method. It can take over the execution flow of the command as needed to stop and gather additional input. The I/O system has various methods for asking confirmation or choice questions such as confirm()
and select()
.
In addition to prompting for input, the I/O object can be used to provide other styling to the command, like progress bars.
In this tutorial we'll:
- Learn how to prompt the user for additional input
- Process the user's answer as part of the command execution flow
By the end of this tutorial you should understand how to prompt a user for additional input for a custom Drush command.
While Drush empowers all Drupal users with its commands, it's even more powerful when used in combination with scripting solutions such as Composer and Bash. Scripts can be used to power post-deployment tasks like importing new configuration or clearing the cache, as part of CI processes to sync a database from one environment to another, to run background processes on the server such as imports and migrations, search indexing, running cron, and much more. If you want to write Bash (or any other scripts) that interact with a Drupal site, then Drush is the tool for you.
In this tutorial we'll:
- Learn how to use Drush commands within Composer and Bash scripts
- Learn how to chain multiple Drush commands together in a script
By the end of this tutorial you'll know how to use Drush as part of a script that automates common or tedious tasks.
When you manage many Drupal websites, you may perform repetitive tasks that are common across all of your sites. In our experience, this usually relates to having a personal preference for how certain tasks are accomplished. For example, maybe you like to make backups of the database and files in a specific way before testing upgrades, or you have a set of scripts for running scans of core web vitals. Although these tasks can be bundled into a custom module, it could be useful to create a site-wide Drush command instead. Site-wide commands can be installed with Composer, managed in a separate Git repository, and act as a project dependency. This way they are easy to maintain through a separate upstream. Changes to this code will be reflected on all the sites where it's used.
In this tutorial we'll:
- Declare a custom site-wide Drush command
- Demonstrate how to use Composer to manage a package that contains a Drush command
By the end of this tutorial you'll be able to create a site-wide Drush command and manage the code with Git and Composer.
The Drupal Entity API makes it easy to define new custom content entity types. And in most cases whenever you want to store custom content in Drupal you should use the Entity API instead of making CRUD queries directly to the database. This ensures your code is more consistent, and allows you to take advantage of all the features of the Entity API like access control, Views module integration, and automatic JSON:API support. As well as making it easier for others to extend your custom content by ensuring all the proper hooks and lifecycle events get invoked when new content items get created, updated, and deleted.
In this tutorial we'll:
- Walk through the process of creating a custom content entity
By the end of this lesson you'll be able to create your own custom content entity contained in a module.
One of Drupal's more powerful features is the fine-grained ability to control permissions and control access to content. The Entity API helps enable this functionality by providing an interface to help define access control.
In this tutorial we'll:
- Look at how access control is handled, using Drupal core as an example.
- Demonstrate how to implement access control in a custom module.
- Learn about the hooks that allow developers to modify access control for entities provided by another module.
By the end of this tutorial you should have a better understanding of the entity access control system and how to work with it.
Entities are the building blocks that make up just about everything on a Drupal site. Regardless of whether entities provide configuration information or content, they are absolutely crucial to Drupal's data model.
In this tutorial we'll:
- Look at the overall class hierarchy between the various entity types to see how they're related.
- Examine differences between configuration and content entities in the code that defines them.
- Look at some of the core code required to create an entity type.
By the end of this lesson you should be able to use an example to create a custom entity type in code.
Often when building a site in Drupal you'll find yourself wanting to display a list of nodes, or find entities created by a particular author, or locate some content based on a particular set of criteria. Rather than querying the database directly, Drupal provides a helper class, EntityQuery
, to make things a bit easier. The EntityQuery
class will probably look very familiar to you if you're familiar with the Database API, or the EntityFieldQuery
class in Drupal 7.
In this tutorial we'll:
- Go through several examples of using
EntityQuery
to find subsets of content. - Demonstrate how to iterate over the results of an
EntityQuery
query.
By the end of this tutorial, you should understand how to use entity queries to create custom sets of data from entities.
Entity API Overview
FreeWhen learning Drupal development, it won't be long before you encounter the word "entity" and the Entity API. But what are entities in Drupal? How can you use them to build your site? When should you use the Entity API?
This tutorial will explain Drupal's Entity system from a high level. We'll look at:
- The main problems the Entity system solves
- Key terms you should know
- Key concepts we'll explore as we dive into Drupal's Entity API
By the end of this tutorial you should be able to explain the problems that the Entity API solves, and when you should use it in your own code.
Drupal includes the Symfony Validator component, and provides an Entity Validation API to assist in validating the values of fields on an entity. By using the Entity Validation API you can ensure that you're validation logic is applied to Entity CRUD operations regardless of how they are triggered. Whether editing an Entity via a Form API form, or creating a new Entity via the REST API, the same validation code will be used.
Using the Entity Validation API in order to validate the value of a field on an entity requires:
- Defining (or choosing) a constraint plugin
- Defining (or choosing) a validation plugin
- Adding the constraint to the field definition
In this tutorial, we'll look at how this Validation API works and how it can be used in custom code to ensure our entities have properly constructed values. We'll look at how this validation works in Drupal core and how we can add our own additional constraints. We'll also see how to work with the error messages returned from the validator when our entity doesn't pass validation.
What Is Docker?
FreeDocker often seems like an impenetrable product. Is it a VM system? A suite of development tools? A clustering product? A software distribution facility? When the answer is "yes" to each of these, it only becomes more confusing. For the Drupal developer, Docker is a way to provide a local development environment to run web server software.
In this tutorial, we'll:
- Define the terms hypervisor, virtual machine (VM), and containers
- List the advantages of containers over VMs
- List the advantages of Docker for Drupal developers
Install Docker
FreeInstalling Docker is easy, but there are some details you may want to consider before you download and run the installer.
In this tutorial, we'll focus on:
- Why Linux is Docker’s native environment
- The difference between Docker edge vs. Docker stable
- Why Docker for non-Linux requires a VM
Now that we know what Docker is, what containers are, and how to install Docker, just how do we use containers? While graphical user interfaces (GUI) exist for Docker, the primary way to interact with it is via the command line.
In this tutorial, we'll:
- Start Docker for Mac or Docker for Windows
- Use the
docker run
command to run a container interactively - Break down the arguments of the
docker run
command
Containers are sandboxed applications that can be run anywhere, no matter the underlying host OS. Docker containers are quite different from VMs in a number of ways that need to be understood before we can use them to develop Drupal sites.
In this tutorial, we'll:
- Define a container
- Explain how a container is a more limited environment than a VM
When we use docker run
to start a container, we download a compressed, ready-to-use container called an image. Images make containers easy to share via a registry like Docker Hub, but also affect how file storage works when using containers.
In this tutorial, we'll:
- Discuss how file storage works in Docker containers
- Describe images, base images, and the scratch image
- Identify layers and show how layers make up Docker's filesystem