Drupal JavaScript Initiative: The Road to a Modern Administration UI

by Sally Young

It's now been over 10 years since Drupal started shipping jQuery as part of core, and although a lot of Drupal's JavaScript has evolved since then it's still based on the premise of progressive enhancement of server-side generated pages. Meanwhile, developing sites with JavaScript has made huge strides thanks to popular rendering frameworks such as React, Angular, and Vue. With some of the web's largest sites relying on client-side only JavaScript, and search engines able to effectively crawl them, it's no longer imperative that a site provides fallback for no JavaScript, particularly for specialised uses such as editorial tasks in a content management system.

At DrupalCon Vienna, the core JavaScript team members decided to adopt a more modern approach to using JavaScript in Drupal to build administrative interfaces, with efforts centred around the React framework from Facebook. To try this out, we decided to build a prototype of the Database Logging page in React, and integrate it into Drupal.

Why Not Vue or Angular?

We chose React because of its popularity, stability, and maturity. Many client projects built with Drupal have successfully leveraged the model of annotating Drupal templates with Angular or Vue directives for quite some time now, but we were wary of building something so tightly coupled with the Drupal rendering monolith. We're very aligned with the API-first initiative and hope that through this work we can create something which is reusable with other projects such as Vue or Angular. The choice of library which renders HTML to the browser is the easiest part of the work ahead, with the hard problems being on the bridge between Drupal and the front-end framework.

What We Learned From The Prototype

prototype database log built with React

As we anticipated, rendering something in React was the easy part— our early challenges arose as we realized there were several missing exposed APIs from Drupal, which we addressed with help from the API-first initiative. Having completed this, we identified a number of major disadvantages to our approach:

  • Although we were creating a component library that could be re-used, essentially we were embedding individual JavaScript applications into different pages of a Drupal theme
  • Our legacy JavaScript was mixed in on the page alongside the new things we were building
  • The build process we currently have for JavaScript can be frustrating to work with because Drupal doesn't have a hard dependency on Node.js (and this is unlikely to change for the time being)
  • A developer coming from the JavaScript ecosystem would find it very unfamiliar

The last point in particular touches on one of the biggest tensions that we need to resolve with this initiative. We don't want to force Drupal's PHP developers also to have to know the ins-and-outs of the JavaScript ecosystem to build module administration forms, but we also don't want developers coming from the world of JavaScript—with promises of "We use React now, so this will be familiar to you!"—to then have to learn PHP and Drupal's internals as well. Having discussed this at length during our weekly initiative meetings, we decided to build an administration interface that is completely separate from Drupal itself, and would only consume it's APIs (aka decoupled). The application would also attempt to generate administration forms for some configuration scenarios.

Hello, world!

We began building our decoupled administration application based on the Create React App starter-kit from Facebook. This is an extremely popular project that handles a lot of the complexities of modern JavaScript tooling and creates a very familiar starting point for developers from the JavaScript ecosystem. So far we haven't needed to eject from this project, and we're enjoying not having to maintain our Webpack configurations, so fingers crossed we can continue with this approach indefinitely.

The first page we decided to build in our new application was the user permissions screen so we could experiment with editing configuration entities. One of the challenges we faced in the implementation of this was the inability to get a list of all possible permissions, as the data we had available from Drupal's API only gave us permissions which had been enabled. We created an Admin UI Support module to start providing us with these missing APIs, with the intention to contribute these endpoints back to Drupal once we have stable implementations.

A demo of the decoupled administration UI for Drupal

We chose to use GitHub as our primary development platform for this initiative, again because we wanted to be in a place familiar to as many developers as possible, as well as to use a set of workflows and tools that are common across the greatest number of open source projects and communities. Using GitHub and CircleCI, we've created an automated build process which allows Drupal developers to import and try out the project with Composer, without requiring them to install and run a build process with Node.js. Over the long-term, we would love to keep this project on GitHub and have it live as a Composer dependency, however, there are logistical questions around that which we'll need to work through in conjunction with the core team.

A New Design

Having got the architectural foundations in place for our application, we then turned to the team working on redesigning the admin UI to collaborate more closely. One of the features we had already built into our application was the ability to fall-back to a regular Drupal theme if the user tried to access a route that hadn't been implemented yet. Using this feature, and trying to keep in mind realistic timelines for launching a fully decoupled admin theme, the team decided that our current path forward will involve several parallel efforts:

  • Create new designs for a refreshed Seven-like theme
  • Adapt the new designs to a regular Drupal theme, so the fallback isn't jarring for the user
  • Build sections of the administration interface in the new React application as designs become available, hopefully starting with the content modeling UI
Updated designs for the Drupal administration interface
Admin UI redesign explorations

Hard Problems

We still have a lot of issues to discuss around how the administration application will interact with Drupal, how extensible it can be, and what the developer experience will be like for both module authors and front-end developers. Some of the major questions we're trying to answer are:

  • How and what is a Drupal module able to do to extend the administration UI
  • We're not looking to deprecate the current Drupal theming system, so how can modules indicate which "mode" they support
  • If a module wants to provide its own React component, do we want to include this in our compiled JavaScript bundle, and if so how do we build it when Drupal has no requirement to include Node.js
  • How can modules provide routes in the administration UI, or should they become auto-generated
  • How do we handle and integrate site building tools such as Views, or do we replace this with the ability to swap in custom React components

Forms

How we're going to handle forms has been a big point of discussion, as currently Drupal tightly couples a form's schema, data, validation, and UI. Initially, we took a lot of inspiration from Mozilla's react-jsonschema-form project, which builds HTML forms from JSON schema and separated out these concepts. Nevertheless, a major issue we found with this was it still required a lot of form creation and handling to happen in Drupal code, instead of creating good API endpoints for the data we want to fetch and manipulate.

Code showing a form split into different data models and updating a Bootstrap-based form in real-time
react-jsonschema-form in action

The approach we're currently looking at is auto-generating forms from configuration entities and allowing a module to provide a custom React component if it wants to do something more complex than what auto-generation would provide. Here's a working (unstyled!) example of the site information form, which has been auto-generated from an API endpoint.

Auto-generated version of the Drupal site information form

We're now looking to augment configuration entities with metadata to optionally guide the form display (for example, whether a group of options should be a select dropdown or radio buttons).

Try It Out and Get Involved

We have a Composer project available if you want to check out our progress and try the administration interface out (no previous Drupal installation required!). If you're looking to get involved we have weekly meetings in Slack, a number of issues on GitHub, our initiative plan on drupal.org, and lots of API work. You can also join us in-person at our next sprint at Frontend United in June.

A very special thank you to my initiative co-coordinators Matt Grill and Angie Byron, as well as Daniel Wehner, Ted Bowman, Alex Pott, Cristina Chumillas, Lauri Eskola, the API-First initiative, and all our other contributors for everyone's stellar work on this initiative so far!

⬅️✌️➡️  

newsletter-bot