Decoupling In Drupal 8 Based on a Proven Model

Matt D.
Lead Drupal Architect
May
09
2016

Decoupling In Drupal 8 Based on a Proven Model

Introducing Decoupled Blocks Module

In an ongoing web project with Weather Underground, the Mediacurrent development team is breaking new ground with decoupled Drupal and Angular 2. The endeavor has required refactoring the Presentation Framework originally built for Weather.com from dependent on Angular 1 to being javascript framework agnostic. This blog series explores how Mediacurrent, in collaboration with the Angular team at Google, has solved for several architectural challenges.

This post will be a departure of sorts from my previous series. Instead, I’d like to examine how a proven model of a Panels-based, javascript-framework-agnostic, progressively decoupled solution might guide Drupal’s path forward. In previous writing about the Presentation Framework, we have seen how this system empowers both: javascript developers to create innovative user experiences without knowing Drupal, and editorial teams to create new pages and layouts independently of developer teams.

But this all took place in a Drupal 7 world, and the question I would like to pose today is, what does such a model look like in Drupal 8?

The answer, I’m happy to say, is already in development. I call it “Decoupled Blocks,” and an initial proof of concept version of the code exists as a Drupal sandbox project and github repository today that you can install on your Drupal 8 site and try. I have been talking about this idea around the country for the last few months, first at San Francisco Drupal User’s Group (recording here), then Sand Camp, Florida Drupal Camp (recording here), and most recently in an Acquia webinar (recording here). The reception to the idea so far has been overwhelming, but getting more community buy in and architectural help will ensure it is built in a way that accommodates as many use cases as possible. So at its root, this post aims to be a request for help.

But before I get into the specifics of what this module aims to be, let’s take a step back. "Progressive Decoupling” has been a much-discussed and hotly debated topic in the Drupal community of late. After Dries’ blog post and a subsequent d.o issue suggesting active evaluation of a new javascript framework for inclusion in core Drupal 8, some were understandably concerned. After all, backbone.js was added to core Drupal 8 almost two years before it was even released, and is so tightly coupled to major pieces of core that the level of effort to remove it and replace it with something else would be substantial. It is even possible that by the time the effort to rip out backbone.js and replace it with a new framework is complete, the new framework’s value in a rapidly evolving javascript world will have diminished to the point where we will just want to begin the same process again.

So the concerns of the community to such an approach are understandable, in my view, even if they must be balanced against our need to deliver the strongest editorial experience possible to our users. But this post is not an attempt to weigh in directly on the core issue. Instead, my intention is to offer a proven model of progressive decoupling, one that can be javascript framework agnostic and therefore live independently of that ever-changing world, and to give some initial guidance as to what such a module living in the contrib space will look like.

First and foremost, the original Presentation Framework was built on top of the Panels module, for many reasons that have been discussed at length previously, but most importantly because of the editorial benefits it provides. However, due to the Plugin API in core, Drupal 8 Panels has ditched the confusingly named CTools content types, and is using core Drupal blocks instead. Blocks have come a long way since Drupal 7, and are now exportable, reusable, and can even have their own custom bundles! Using blocks means that our module can still work in Panels, but our javascript components can just as easily be placed on pages using the core block UI, or any other block placement UI that comes along.

There are other exciting ways Drupal 8 improves on the Presentation Framework model. Instead of the JSON-formatted .info files used in the original Presentation Framework to declare a component's’ existence to Drupal, in Drupal 8 we will naturally leverage the YAML formatting and extension discovery classes already included in core. Also, a vastly superior library API will ease how we define javascript frameworks to Drupal. Dynamic asset inclusion allows us to be very specific about only including the assets we need on any particular page while still preserving scalability and caching.

Two weeks ago, Acquia and Mediacurrent sponsored a joint sprint at Acquia headquarters to push this module forward for showcasing at DrupalCon New Orleans. We sprinted with members of both the Office of the CTO and the Acquia Lightning distribution. I was also privileged to get to speak directly with Dries about the progress we made and the roadmap leading us forward.

Aside from code cleanup and major improvements to our overall architecture, we also made exciting feature progress like:

  • Instance configuration for components can now be written into the info.yml file as form fields that will be converted to FAPI and available during block placement. These configuration values are then automatically passed through drupalSettings to the client for use by the component.

  • Components can add contextual requirements for display (currently only entities), and the context object is similarly passed to the client via drupalSettings automatically for use.

  • A separate DrupalVM repository for the project has been created so you can clone the repo, vagrant up, and jump into helping the development efforts immediately from your local machine.

  • Discovery began on abstracting out a Component API module, so the same components could also be used for other things like static page generation for rapid prototyping and living style guides.

There are numerous possibilities for extending the main progressive blocks module. As it stands in its sandbox state, basic Angular 2 and React submodules already exist. They need to be built out and improved upon, and more javascript frameworks need their own submodules to allow javascript developers to create decoupled blocks using them. We also need to create services in vanilla javascript that solve more common problems across frameworks so they can all leverage them.

I’m extremely interested in integration with the GraphQL module, which could allow us to throw away dozens of REST API endpoints and instead let the client request exactly the data they want on a component-by-component basis. This could offer us a valuable third way for components to access Drupal’s data, aside from RESTful API’s and drupalSettings.

It’s tempting to think that this type of solution only caters to enterprise-level projects, where large javascript and editorial teams need to be moving rapidly and independently. It has certainly proven its ability to pay dividends in such scenarios. But imagine this: you are a small Drupal shop, working on a site where most pieces of content can be rendered by Drupal in a traditional way. However, the client has one specific page where they want to offer a richer experience.

Ordinarily, you’d need to find a front end developer familiar enough with Drupal to know a proper way to get their functionality onto the page by writing a custom module, or you’d need both a front end and back end developer working together to make this possible. Instead of that, the decoupled blocks module will let you simply hire a javascript developer with no previous Drupal experience, who can use the framework of their choice (assuming its support has already been written in the module) to make a standalone piece of functionality. Then, just by writing a simple YAML file to live alongside it, Drupal will recognize it as a decoupled block and offer it as a choice for your site builder to drop on the page.

If it is not obvious, I am very excited about the possibilities this type of a solution opens up to the Drupal world. But there are many hard problems still to be solved before it can used in the wild (see the issue queue in the repo for some of them, and please speak up about others). I need help, both from seasoned Drupal developers who want to improve the Drupal 8 architecture and roadmap, and from javascript developers who have expertise in a particular framework and would like to see support for it exist in this module.

I will be speaking about this module again at DrupalCon New Orleans, and also have a brainstorming BOF and Friday sprint scheduled. If you will not be in New Orleans and would like to help, please do reach out and let’s make Drupal deliver both the cutting edge user experiences and robust editorial tools we all know it can!

comments powered by Disqus