Illustration by wei/Shutterstock.

Urban’s Drupal 9 Upgrade Path

Data@Urban
9 min readJul 2, 2020

At the Urban Institute, Drupal is our primary digital content management system. From our main website to all our partner projects and legacy sites, we have more than a dozen projects in both Drupal 7 and 8.

Five years ago, Drupal 8 was released with a new codebase completely separate from 7. It started with this new codebase and relied on various front-end and back-end libraries that weren’t included in Drupal 7. Consequently, the upgrade process from Drupal 7 to 8 was complex and required content and site configuration migration that, unfortunately, we don’t cover in this post.

With the Drupal 8 release, the development cycle started using semantic versioning with a three-number system to assign major, minor, and patch releases.

Drupal 9’s development, on the other hand, started with the Drupal 8 codebase, and some of the front- and back-end libraries, known as third-party dependencies, have been updated to their new versions. Drupal 9 is the same as the last minor release of Drupal 8 (Drupal 8.9), and no new features and functionalities have been added to Drupal 9 core upon its initial release. With that, upgrading from Drupal 8 to 9 should be fairly easy. It does not need migration, but additional steps are required to perform a smooth and successful upgrade. At Urban, we will be upgrading all our Drupal 8 sites to 9, and in this blog post, I will cover how.

With no new features in Drupal 9, why we are upgrading?

Code cleanup is the primary reason for the release of Drupal 9. Through each Drupal 8 minor release every six months, new and improved features and APIs (application programming interfaces) have been added. The old APIs still live in the codebase that was needed for backward compatibility and are marked as deprecated.

On the major release, the core breaks the API. In other words, there is no backward compatibility with an older API. The old code needs to be removed. This is exciting for developers because it makes the codebase smaller and faster.

The secondary reason is the major dependency updates. As I’ve already mentioned, Drupal core has adopted several third-party libraries, including the Symfony framework from the PHP community and Twig as the template engine, and it needs to follow their best practices in the security support cycle. For example, Drupal 8 depended on Symfony 3, which will no longer receive security support from maintainers toward the end of 2021. This will also mark the end of life for Drupal 8. Drupal 9’s end of life is November 2023, as Symfony 4.4 security support will end around the same time.

Drupal 7 is a bit different. Because of the financial impact of COVID-19, community support will end November 28, 2022. But for an additional cost, vendor support for security patches extends until November 2025.

What Urban’s upgrade will look like

The Drupal 8 to 9 upgrade differs across our various projects. Some Drupal 8 Urban projects are hosted in an Acquia Lightning instance, such as Housing Matters. The upgrade requires a few extra steps for updating, but generally Urban approaches the upgrade in five steps:

1. Update contributed projects

We update all contributed modules and themes to the latest stable release through the administrative interface on a Drupal 8 site by navigating to reports > available updates > update.

Because our Drupal 8 projects are all using Composer to manage dependencies, including our modules, an alternative is to use Composer to run the update. I take this step as a good opportunity to uninstall and remove modules from the composer.json file that aren’t being used. For our Housing Matters project, there is a custom module for WordPress to Drupal 8 migration (more information about this custom module is available on Data@Urban). We have already completed the migration on the Housing Matters project won’t be using this custom module moving forward. Therefore, I uninstalled the module.

2. Check platform requirements

Drupal core system requirements usually remain stable during a major version life cycle.

Though Drupal 8.8 works on any web server with a PHP version of 7.0 or greater, Drupal 9 requires a minimum of PHP 7.3 to run and operate. We also need to meet the minimum version requirements for the database, web server, and Drush. See the list of server requirements on Drupal’s official website for more information.

Next, we’d navigate to the status report administrative interface (/admin/reports/status), and check the site’s system information.

In the image below from the status report, the PHP version needs to be updated to at least PHP 7.3. Pantheon is our hosting platform for most of our Drupal sites. Configuring the PHP version can be done by modifying the pantheon.yml file. Details on how to upgrade the PHP version can be found on Pantheon documentation.

For the database, at the time of writing, the Pantheon community announced they are working on the MariaDB 10.4 upgrade on their Slack channel. Therefore, on this requirement, we will wait until the database server upgrade is ready.

Drush, a Drupal command-line shell, is not required for Drupal core. However, all our Drupal projects use Drush to manage our sites and perform common administrative tasks in the command-line interface. With Drush commands, we can clear caches, update the database, import and export site configuration, install or uninstall modules, backup, restore our sites, and much more.

Upgrading to Drush 10 is necessary as our development dependency and is intended only for local development and should not be deployed to production servers. To upgrade Drush on our projects, I use require-dev. Composer, the PHP dependency management for our Drupal 8, tracks the dev dependencies by require-dev.

3. Identify deprecated code

In the major release with no backward compatibility, there is an opportunity to clean up and remove deprecated code. Let’s go through this part with an example to clarify what deprecated code is and why it is deprecated. Then, I will walk you through my approach to identifying deprecated code in your own projects.

Drupal provides an easy way to display a status or warning message to users.

The function takes two arguments, a message and a type for the severity of the message.

The above example displays the message in a red box.

Currently, using the drupal_set_message function in the code triggers a silent error and provides a backward-incompatible implementation of this function by calling the messenger service to display the message.

Drupal core comes with a lot of useful objects, called services, that are generally accessed via the service container to ensure the decoupled nature of these systems is respected. Using services makes our code reusable, readable, and testable.

As of Drupal 8.5, the drupal_set_message function calls the messenger service that comes with more flexibility. The messenger service has methods for retrieving or deleting all messages or selected messages by message type. The drupal_set_message is a deprecated method and will not be included in Drupal 9 codebase. The function will be removed and the addMessage method using the messenger service is a replacement code.

Here’s how you can identify the deprecated code in your project. There are various tools from IDEs (integrated development environments), such as PhpStorm, to automated testing tools, a command-line tool called Drupal check. At Urban, I have been using the Upgrade Status module to assess our projects’ Drupal 9 readiness.

One reason that I chose Upgrade Status over other tools is that I really find it helpful and efficient to select and scan all contributed and/or custom projects at once. The scanning process may take some time, depending on how many modules are installed on your site.

The Upgrade Status dashboard prints out helpful information about all the installed modules or themes in the project with the file path and the line number for the deprecated code, information to the change record, and the Drupal 9 porting info if the module is ready for Drupal 9 release. The image below is the Upgrade Status report for one of our installed contributed modules.

4. Remove deprecated code

Based on the information provided by the Upgrade Status, if there is a module in the project that is not yet compatible with Drupal 9, I will check the issue queue page of that module for issues related to Drupal 9 compatibilities report. If an issue is identified with a community-approved patch, then I will apply the patch to our Drupal 8 site. If there is no approved patch or no issue has been created yet, I will create an issue and propose a patch and wait for the Drupal community to review it. To learn more about contributing to an issue queue, please read on Drupal official website.

On the other hand, the deprecated code should be removed and replaced for each custom modules and themes individually.

The screenshot below is an example of calling drupal_set_message on one of our custom contact form modules to display a message when the form is submitted. I’d go to the code of the custom contact form module and replace the deprecated method based on the change record provided by Upgrade Status accordingly.

5. Upgrade when ready

I know that’s a lot to take in, but once we applied any patches found on the previous step, and our custom modules are clean from any deprecated code, then our site is ready for the upgrade.

Once the upgrade is complete, update the database and clear caches (drush updatedb && drush cache-rebuild). Be sure to check this page for any database issues. In my case, the drush updatedb reports that the field_reditection module is missing. I noticed that the composer during the Drush update, removed this module, while it existed in my configuration files, so I had to reinstall the module by running composer require ‘drupal/field_redirection:².0’.

Conclusion

The Drupal 8 to 9 upgrade is straightforward as long as your Drupal 8 site is clear of deprecated APIs and updated to the latest stable release of Drupal core (8.8 or 8.9). This may be the easiest upgrade in more than a decade.

Although I didn’t cover the Drupal 7 to 9 upgrade, it is worth mentioning that the upgrade is a big jump. The good news for those on Drupal 7 is this is hopefully the last big migration. The continuous innovation cycle in Drupal 9 ensures future major upgrades are easy. If you are still on Drupal 7, it’s time to plan and rebuild your site one last time.

Going forward with the release of Drupal 9, I believe the third quarter of 2020 would be the best time to upgrade. I hope the process that we have taken at Urban to evaluate and plan our Drupal 8 sites is helpful for you and your organization.

-Farnoosh Johnson

-Want to learn more? Sign-up for the Data@Urban newsletter.

--

--

Data@Urban

Data@Urban is a place to explore the code, data, products, and processes that bring Urban Institute research to life.