Porting Drupal 7 Modules to Backdrop

Note: this article assumes some experience working with Drupal modules and doesn't profess to be a general introduction to writing a Drupal or Backdrop module from scratch.

Now that an official release of Backdrop CMS is available, we have the opportunity to examine this fork of Drupal more closely, and evaluate its appropriateness for projects. It’s impossible to evaluate Backdrop’s feasibility without having an understanding of the level of effort involved in porting modules.

Like a major Drupal release, Backdrop CMS brings changes that break compatibility with existing Drupal modules. Nevertheless, it needs contributed modules in order to be useful and to foster adoption. Drupal 7 has thousands of contributed modules out there just itching to be converted, so how hard is migrating modules to Backdrop CMS? It’s time to find out.

I decided to port a popular module: Email Field, which is also included in Drupal 8 core. In this article I will share my experience migrating this module, and offer it as an example of what needs to be done to port Drupal 7 modules to Backdrop CMS.

Dragon Drop, Backdrop’s friendly mascot
Dragon Drop, Backdrop’s friendly mascot

Clone the Drupal 7 repository and rename the branch to 1.x-1.x

In order to maintain all the history from the original project, we start by cloning the git repository from drupal.org and checking the Drupal 7 branch. Then, we rename the branch to 1.x-1.x for Backdrop 1.x.

If you are not the maintainer of the module you are willing to port, I recommend communicating with the maintainer(s) first. Create an issue in the drupal.org queue for that module, and politely offer to help port and co-maintain the module if they are interested in supporting a Backdrop version. By tagging the issue with ‘backdrop-port’, other people working on Backdrop CMS will know that you are working on this module, avoiding duplication of effort and inviting collaboration.

Make the module compatible with Backdrop 1.x

Start by making the module’s metadata compatible with Backdrop CMS. Edit the module .info file and replace “core = 7.x” with “backdrop = 1.x”. This will allow us to enable the module in Backdrop and see what’s broken.

Review the functionality and debug what is not working

This is the tricky part, finding out what is not working and why. The first principle in Backdrop CMS is “keep change to a minimum”, but there are changes, and the module may not work due to these differences. We must review all the functionality, and debug the code when we find errors.

Backdrop CMS documentation provides the Change Records, which explains the significant modifications and features that have been introduced replacing the original code. This is a good place to look for more information when something goes wrong.

These were the problems I found with email module:

Saving Email field settings throws a fatal error

Email module uses the deprecated _element_validate_integer_positive() function in order to validate the “Size of textfield” property. This function has been removed in Backdrop so we need a different way to handle this validation. Backdrop's Form API has been updated to include better support for HTML5, so in this case we can simply use the '#type', and '#min' Form API properties in order to set the value of those attributes. Fatal error averted.

Some warnings appeared when accessing and using Email Contact Form

Not all errors will be so…well fatal. Sometimes, everything will work, but it’s important to check the logs to see if warnings are being thrown.

  • Using deprecated drupal_get_form() instead of the new backdrop_get_form() throws a warning message. Backdrop is complaining about missing parameters. In general, Backdrop maintains the Drupal-based names in functions for compatibility, but there can be idiosyncracies.
  • The language key object within the $message array parameter in hook_mail(), now has a langcode property instead of language property, so changing it solved the problem.

That’s all! The module is working in Backdrop CMS! Despite the fact that we have finished our migration and everything is working, we should not consider it done. We are using our module as it was in Drupal 7, but this is Backdrop CMS and we have Configuration Management! We can separate our configuration from the database to files and export/import it. Let’s do it!

Use Configuration Management instead of database variables

Drupal 7 modules commonly use system_settings_form() and variable_get() to set and retrieve the configuration settings in the administration interface. In Backdrop, we must:

  • Explicitly provide the submit button and the submit handler to store our configuration in files.
  • Use the config() object and its get and set methods, or config_get() and config_set() functions, in order to set or retrieve the values of each variable, replacing all occurrences of variable_get() and variable_set() does the trick.
  • Implement hook_config_info() to expose the configuration files in the UI for exporting.
  • Create a .settings.json file to set the initial values in a config subdirectory within the module. The easiest way is copying it from the files/config_xxx/active directory where it’s auto created once the module settings are using config_set().

You can see all these changes for the email module at this commit in GitHub.

Make the module work with Drupal compatibility disabled

Finally we must replace ‘drupal’ with ‘backdrop’ in all the files of the module, and again ‘Drupal’ with ‘Backdrop’. With this very easy step we avoid using deprecated functions which as we have seen before, could also be the cause of warnings or errors.

There are a huge number of references to the word ‘drupal’ throughout Drupal’s core and contrib codebases. Backdrop CMS is a separate project from Drupal and over time it’s going to diverge significantly. Using the same functions names and objects for totally different implementations would be confusing in the future. These ‘drupal’ references have been changed in core from the beginning, to consistently use the word ‘backdrop’ as the name of the project.

Nevertheless Backdrop provides wrappers for the ‘drupal’ word based functions or the JavaScript Drupal global object to maintain compatibility and to facilitate the migration. That is why the module worked previous to this step.

This compatibility is enabled by default in the variable ‘backdrop_drupal_compatibility’, within settings.php. The last step to completely port the module to Backdrop CMS, is to check that it works well with the Drupal compatibility disabled.

Contribute the module to Backdrop

Backdrop CMS contributed projects is the GitHub organization where you can place and find contributed modules, themes, etc. This organization facilitates collaboration and sharing between Backdrop contrib developers and also provides official security procedures for keeping the code healthy.

If you want to be part of this community, you can apply to join the contrib group after porting or creating your first Backdrop contrib project. Just create a public repository for it in your personal GitHub account, so it can be reviewed. Once your application is accepted you can create new projects within the contrib group and transfer the repository from your account. The first review ensures that new contrib developers understand the fundamentals of porting or creating modules documented here.

As it is described in the Backdrop Contributed Project Agreement, any project we want to contribute must include the GPL v2 LICENSE.txt file and a README.md with the project documentation, license reference, and current and past maintainers.

Final thoughts

Those steps were all I needed to port Email Field module, and it was pretty straightforward. Nevertheless, not all projects will be so easy to port, and there are many aspects to account for.

For example, Backdrop’s nodes, comments, vocabularies and users all extend the Entity class, which makes working with these objects slightly different. Also, keep in mind that automated tests for Backdrop are defined in your module. Instead of exposing the test class with the static getInfo() method, the test is expected to be referenced in a [module_name].tests.info file. You can find more information about topics like these in the Backdrop documentation for converting modules from Drupal.

I hope you have found my experience interesting and useful. There are lots of amazing Drupal modules that can be easily ported to Backdrop CMS, broadening the options for site building teams and developers. In addition, working in the small, but growing Backdrop community was delightful. My work was instantly appreciated and recognized, and help was easy to come by. Happy contributing!

Published in:

Get in touch with us

Tell us about your project or drop us a line. We'd love to hear from you!