Happy eighteenth birthday, Drupal

Eighteen years ago today, I released Drupal 1.0.0. What started from humble beginnings has grown into one of the largest Open Source communities in the world. Today, Drupal exists because of its people and the collective effort of thousands of community members. Thank you to everyone who has been and continues to contribute to Drupal.

Eighteen years is also the voting age in the US, and the legal drinking age in Europe. I'm not sure which one is better. :) Joking aside, welcome to adulthood, Drupal. May your day be bug free and filled with fresh patches!

Refreshing the Drupal administration UI

Last year, I talked to nearly one hundred Drupal agency owners to understand what is preventing them from selling Drupal. One of the most common responses raised is that Drupal's administration UI looks outdated.

This critique is not wrong. Drupal's current administration UI was originally designed almost ten years ago when we were working on Drupal 7. In the last ten years, the world did not stand still; design trends changed, user interfaces became more dynamic and end-user expectations have changed with that.

To be fair, Drupal's administration UI has received numerous improvements in the past ten years; Drupal 8 shipped with a new toolbar, an updated content creation experience, more WYSIWYG functionality, and even some design updates.

A visual comparison of Drupal 7 and Drupal 8's administration UI
A comparison of the Drupal 7 and Drupal 8 content creation screen to highlight some of the improvements in Drupal 8.

While we made important improvements between Drupal 7 and Drupal 8, the feedback from the Drupal agency owners doesn't lie: we have not done enough to keep Drupal's administration UI modern and up-to-date.

This is something we need to address.

We are introducing a new design system that defines a complete set of principles, patterns, and tools for updating Drupal's administration UI.

In the short term, we plan on updating the existing administration UI with the new design system. Longer term, we are working on creating a completely new JavaScript-based administration UI.

A screenshot of the content administration using Drupal 8's Carlo theme
The content administration screen with the new design system.

As you can see on Drupal.org, community feedback on the proposal is overwhelmingly positive with comments like Wow! Such an improvement! and Well done! High contrast and modern look..

A screenshot of the spacing guidelines of Drupal 8's Carlo theme
Sample space sizing guidelines from the new design system.

I also ran the new design system by a few people who spend their days selling Drupal and they described it as "clean" with "good use of space" and a design they would be confident showing to prospective customers.

Whether you are a Drupal end-user, or in the business of selling Drupal, I recommend you check out the new design system and provide your feedback on Drupal.org.

Special thanks to Cristina Chumillas, Sascha Eggenberger, Roy Scholten, Archita Arora, Dennis Cohn, Ricardo Marcelino, Balazs Kantor, Lewis Nyman,and Antonella Severo for all the work on the new design system so far!

We have started implementing the new design system as a contributed theme with the name Claro. We are aiming to release a beta version for testing in the spring of 2019 and to include it in Drupal core as an experimental theme by Drupal 8.8.0 in December 2019. With more help, we might be able to get it done faster.

Throughout the development of the refreshed administration theme, we will run usability studies to ensure that the new theme indeed is an improvement over the current experience, and we can iteratively improve it along the way.

Administration themes must meet large and varied use cases. For example, accessibility is critical for the administration experience, and I'm happy to see that this initiative connected with and have taken feedback into account from the accessibility team.

Acquia has committed to being an early adopter of the theme through the Acquia Lightning distribution, broadening the potential base of projects that can test and provide feedback on the refresh. Hopefully other organizations and projects will do the same.

How can I help?

The team is looking for more designers and frontend developers to get involved. You can attend the weekly meetings on #javascript on Drupal Slack Mondays at 16:30 UTC and on #admin-ui on Drupal Slack Wednesdays at 14:30 UTC.

Thanks to Lauri Eskola, Gábor Hojtsy and Jeff Beeman for their help with this post.

Tidelift, which provides organizations with commercial-grade support for Open Source software and pays part of the proceeds to software maintainers, raises a $25 million Series B. I hadn't heard about Tidelift before, but it turns out their office is 300 meters from Acquia's. I reached out and we're going to grab a coffee soon.

Soft-launching your new Drupal theme

Have you ever wanted to preview your new Drupal theme in a production environment without making it the default yet?

I did when I was working on my redesign of dri.es earlier in the year. I wanted the ability to add ?preview to the end of any URL on dri.es and have that URL render in my upcoming theme.

It allowed me to easily preview my new design with a few friends and ask for their feedback. I would send them a quick message like this: Hi Matt, check out an early preview of my site's upcoming redesign: https://dri.es?preview. Please let me know what you think!.

Because I use Drupal for my site, I created a custom Drupal 8 module to add this functionality.

Like all Drupal modules, my module has a *.info.yml file. The purpose of the *.info.yml file is to let Drupal know about the existence of my module and to share some basic information about the module. My theme preview module is called Previewer so it has a *.info.yml file called previewer.info.yml:

name: Previewer
description: Allows previewing of a theme by adding ?preview to URLs.
package: Custom
type: module
core: 8.x

The module has only one PHP class, Previewer, that implements Drupal's ThemeNegotiatorInterface interface:

<?php

namespace Drupal\previewer\Theme;

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Theme\ThemeNegotiatorInterface;

class Previewer implements ThemeNegotiatorInterface {

  /**
   * The function applies() determines if it wants to set the 
   * active theme. If the ?preview query string is part of the
   * URL, return TRUE to denote that Previewer wants to set
   * the theme. determineActiveTheme() will be called to
   * ask for the theme's name.
   */
  public function applies(RouteMatchInterface $route_match) {
    if (isset($_GET['preview'])) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * The function determineActiveTheme() is responsible
   * for returning the name of the theme that is to be used.
   */
  public function determineActiveTheme(RouteMatchInterface $route_match) {
    return 'dries'; // Yes, the name of my theme is 'dries'.
  }
}

?>

The function applies() checks if ?preview is set as part of the current URL. If so, applies() returns TRUE to tell Drupal that it would like to specify what theme to use. If Previewer is allowed to specify the theme, its determineActiveTheme() function will be called. determineActiveTheme() returns the name of the theme. Drupal uses the specified theme to render the current page request.

For this to work, we have to tell Drupal about our theme negotiator class Previewer. This is done by registering it a service in previewer.services.yml:

services:
  theme.negotiator.previewer:
    class: Drupal\previewer\Theme\Previewer
    tags:
      - { name: theme_negotiator, priority: 10 }

previewer.services.yml tells Drupal to call our class Drupal\previewer\Theme\Previewer when it has to decide what theme to load.

A service is a common concept in Drupal (inherited from Symfony). Many of Drupal's features are separated into a service. Each service does just one job. Structuring your application around a set of independent and reusable service classes is an object-oriented programming best-practice. To some it might feel unnecessarily complex, but it actually promotes reusable, configurable and decoupled code.

Note that Drupal 8 adheres to PSR-4 namespaces and autoloading. This means that files must be named in specific ways and placed in specific directories in order to be recognized and loaded. Here is what my directory structure looks like:

$ tree previewer
previewer
├── previewer.info.yml
├── previewer.services.yml
└── src
    └── Theme
        └── Previewer.php

And that's it!