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.
Creating a container set to support Drupal development requires some specialized knowledge. Now that we understand containers, images, how to use Docker Compose (docker-compose), and how to select images on Docker Hub, we're ready to build a container set to support Drupal development.
In this tutorial, we'll:
- Select images of software that we'll need to run Drupal
- Create a new Compose file
- Configure bind volumes and environment variables to support the site
- Test the configuration
See Dockerize an Existing Project if you already have Drupal installed.
Getting Drupal to run in Docker requires a lot of moving parts. After installing Docker and Docker Compose, we need to select a collection of containers from Docker Hub and create a new docker-compose.yml file. Once we have environment variables and volumes configured, this only gives us the capability of running a Drupal site in Docker.
What if we already have a Drupal site we want to develop using Docker? In this tutorial, we'll show how to modify an existing project to minimize the setup time necessary for switching to a Docker-based environment.
In this tutorial, we'll:
- Describe the best practices for project organization.
- Use an environment file to configure containers.
- Add a Docker-specific settings.php file.
As new major versions of Drupal are released, contributed modules need to be updated for compatibility. As of right now (October 2021) there are a lot of contributed modules with a Drupal 8 release and a patch in the queue to make them work with Drupal 9. However, there's no official Drupal 9 compatible release for the module, so the module can't be installed with Composer. This creates a circular problem where you can't composer require the module if you don't patch it, but you can't patch it until after it's been downloaded by Composer.
To help solve this common issue, Drupal.org provides a lenient Composer endpoint that publishes all modules as compatible with Drupal 9 regardless of whether that's true or not. By using it, you can composer require the module and then use cweagans/composer-patches to apply any necessary patches.
In this tutorial we'll:
- Add the lenient Composer endpoint to our project's composer.json file
composer requirea non-Drupal 9 compatible module- Use Composer to download and apply a patch that makes the module Drupal 9 compatible
By the end of this tutorial you should be able to use contributed modules that require a patch to be compatible with Drupal 9.
Upgrade to Drupal 9
FreeThere’s no one-size-fits-all path to upgrade from Drupal 8 to Drupal 9, but there is a set of common tasks that everyone will need to complete.
In this tutorial we’ll:
- Explain the differences between Drupal 8 and Drupal 9 that affect the upgrade path.
- Walk through the high-level steps required to upgrade from Drupal 8 to Drupal 9.
- 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 8 and 9, audit your existing Drupal 8 projects for Drupal 9 readiness, estimate the level of effort involved, and start the process of upgrading.
Local task links are the tabs you see when logged in as an administrator viewing a node on a Drupal site. In this tutorial we'll take a look at how local tasks are added within a custom module. We'll also see how to alter local tasks provided by other modules via hook_menu_local_tasks_alter().
React is a JavaScript library that makes it easy to create interactive user interfaces. Drupal is a content management system with a powerful web services API. React and Drupal can work together in a couple of different ways. This series of tutorials explores some of those options, and the related concepts and terminology.
Our goal is to provide you with some baseline information you can use to get started integrating React and Drupal together. After you've completed these tutorials you should be able to better envision how to use these two technologies to solve some of your own issues. We hope you'll come away from this with enough knowledge to start exploring further on your own. We link to external resources liberally, and encourage you to explore beyond the examples we provide, read the linked resource, and dig in. There's no substitute for exploration and experimenting with real code when it comes to learning these things.
In this series we'll:
- Introduce the technical side of React, terminology, and information about where to find more resources
- Learn about using Drupal, and the JSON:API module, to turn Drupal into a powerful web services API provider
- Learn about the use cases for adding React to a Drupal site
- Walk through increasingly complex code examples that start with a "Hello World!" application, and end with a fully decoupled application that can list, create, update, and delete content in Drupal
- Learn about how to authenticate a Drupal user via an API using React
- Contrast, through example code and use cases, the differences between integrating React into an existing Drupal theme or module and creating a stand-alone React application
- And more!
Before we start writing any React code, let's go over some basic concepts and terminology. Throughout this series we'll assume you're familiar with these things. They'll come up again and again as you work on projects that involve React, so it's worth taking the time to learn them.
In this tutorial we'll cover the following at a high level, and provide links to resources:
- Why choose React?
- What are React components?
- What are hooks, state, and JSX?
- The role of build tools when developing React applications
By the end of this tutorial you should have a firm grasp of the fundamental concepts and terminology necessary to start creating React applications.
React and Drupal can be used together in two different ways: fully decoupled, also known as headless; or progressively decoupled.
In this tutorial we'll talk about the differences between these two approaches, including:
- Defining what each method refers to
- Considerations regarding hosting, performance, and access
Then we'll link to lots of additional reading materials so you can gain a deeper understanding of the subject.
By the end of this tutorial you should be able to define what decoupled and progressively decoupled mean, and how they differ from one another.
Writing a React application requires including the React JavaScript library in the page, writing some React-specific JavaScript, and then binding it to a specific DOM element on the page. You may also want to include existing packages from the npm ecosystem, and use modern JavaScript (ES6+) features, which necessitates setting up a build toolchain for your JavaScript using a tool like Webpack or Parcel.
There are a lot of different ways you could go about setting this all up. Do you add React via a theme or a module? Do you need a build tool? Should you use Webpack, or Babel, or Parcel, or something else? While we can't possibly cover all the different approaches, we can help you figure out what is required, and you can adapt our suggestions to meet your needs.
In this tutorial we'll:
- Create a new custom theme with the required build tools to develop React applications
- Add a DOM element for our React application to bind to
- Create a "Hello, World" React component to verify everything is working
By the end of this tutorial you'll know how to configure everything necessary to start writing React within a Drupal theme.
Components are the fundamental building blocks of any React application. React uses components to represent different elements in the UI. To show this, we'll build a React widget that can query the Drupal.org REST API to retrieve usage statistics for a project and then display them. We'll create buttons that allow us to toggle between two different projects. In doing so we'll learn about creating components and using props and state in React.
In this tutorial we'll:
- Define two new React components
- Learn about using props to pass data to a component
- Learn about using state, and the
useState()hook, to create interactivity
By the end of this tutorial you should have a basic understanding of how to write a React component that uses props and state to display data from a third party API.
React excels at displaying lists of data. But that data needs to come from somewhere. In most cases this happens by making a network request to retrieve data from one or more APIs, processing the response, and then displaying the data. In the context of working with a Drupal site there are two possible options: Drupal core's JSON API module, or the drupalSettings JavaScript API.
In this tutorial we'll focus on the high-level overview and:
- Explain the difference between content and configuration data
- Introduce the JavaScript Fetch API, and where to find information about using it
- Get an overview of the ES6 array functions we'll use to parse the complex data structures returned from an API
In the remaining tutorials in this series we'll provide examples of real world use cases.
By the end of this tutorial you should have a firm understanding of how to get started making API requests using React.
In order for our React code to list content from Drupal we'll need to enable the Drupal core JSON:API module, and then use fetch() in our React component to retrieve the desired data. This technique works for both React code embedded in a Drupal theme or module, and React code that is part of a fully decoupled application. We'll discuss the differences between those styles as well.
In this tutorial we'll:
- Use
fetch()to bring data from Drupal into React - Parse the data using ES6 array functions to find just the bits of data we need
- Combine multiple React components together to render a list of articles retrieved from Drupal
By the end of this tutorial, you should have a better understanding of how data from a Drupal API gets incorporated into a React application.
To perform create, update, and delete (CRUD) operations with Drupal core's JSON:API via React there are a few things you'll need to understand. First, how to format the POST, PATCH, and DELETE requests necessary to add, edit, and delete Drupal entities. Next, how to handle authentication, and cross-site request forgery (CSRF) tokens. Over the next few tutorials we will create a simple but powerful React application that can add, edit, and delete Drupal node content.
This tutorial contains:
- An overview of the application we're building
- Information about making secure authenticated requests to Drupal's JSON:API
- An overview of the API requests we'll use to create, update, and delete nodes
By the end of this tutorial, you should have a picture of the application we're going to build, and know how to make the API requests we'll use in our application.
Using React we can do more than just list content. By using the POST, PATCH, and PUT methods of Drupal core's JSON:API web service we can also add, update, and delete, content entities. To demonstrate how this works we'll create a small React application with a form that lets you add, edit, and delete article nodes.
In this tutorial we'll:
- Learn how to handle user authentication and CSRF tokens in a React application
- Create a single React component that outputs a form to add or edit content
- Create a wrapper around the JavaScript
fetchAPI to assist in dealing with requests to Drupal's JSON:API
By the end of this tutorial you should know how to create, edit, and delete content in a Drupal site using a React application.