Skip to main content
Ungathered Thoughts

Let's get cooking: Drupal Recipes

This blog post has images of the slides and my notes. The format isn't perfect but I hope it's helpful to follow along or catch up later!

Tena koutou, thanks Kelvin for that presentation, thanks everyone for bringing yourselves along. I hope you’re all enjoying a great first day of DrupalSouth 2024!

Kia ora, I’ve come from Ōtepoti Dunedin, in the south of Te Waipounamu, Aotearoa New Zealand where I live. That’s my family in the top right - Saira, Hunter and Rowan.
I’m really grateful to be here today and part of this community, Drupal’s made a big difference to us.

I love data, and I think a lot about how we care for our own data. I also love throwing balls, and drawing, and learning music at the moment.

I’m a Senior Developer at Catalyst, where I enjoy some interesting and challenging projects in publishing, education and government as part of my work.

My name is Chris Burgess and you’ll find me online as @xurizaemon.

First up - some caveats.

I think the Recipes project work is really exciting! It’s an opportunity to expand what Drupal is to a broader pool of people.

Recipes is unfinished, not incomplete, things may change. And it’s open source, so things may change.

Recipes also does not try to deliver everything you can do with a Profile. That’s intentional.

I am just learning about Recipes myself, and I don’t want you to get the impression I think I’m an expert. Let me know.

Recipes is a way to apply composable configurations (and eventually content) to Drupal sites.

Drupal has twenty years of - a long history of success and lessons in empowering creators to re-use functionality with tools such as distributions, profiles, modules, and more.

Recipes are a new take on that, based on what we’ve learned so far.

Recipes promise to introduce less complexity to a site, and to be a less significant investment.

What was before Recipes? Lots, especially Profiles.

Profiles have been a cornerstone of Distributions, a great tool, a really valuable contribution to Drupal. Profiles are not the only method to deliver configuration to a suite of sites, but they are one of the leading solutions.

One challenge of Profiles in Drupal was they turned out to be a significant commitment for site operators - and profile maintainers - in lots of ways.

Profiles can be effective but their design locks derived sites and the profile together. They can require additional maintenance and affect decisions on both the site operator and maintainer sides, and generally complicate site operation.

So - Recipes are a response to that experience of wanting to deliver configuration to sites, usually a set of sites, without the commitment of tying them together.

How do Recipes offer this? They do less, and they do things differently.

Recipes are declarative: they say “do these things”, without reference to the current state of the system. By design, a Recipe is not informed of the state of the site.

Recipes can do several things.

Recipes may install modules and themes.

This implies they can add requirements for Drupal modules or themes they will install.

Recipes may apply a module’s default configuration, selectively, which means you can opt into some or all of the module’s out of the box config.

Recipes also can provide their own configuration.

And, Recipes can perform config actions. We’ll touch on that shortly.

All this configuration functionality brings new possibilities.

Most of those are features you know from earlier implementations.

What’s most different about Recipes is what it chooses not to do.

There’s no provision for code in a Recipe. It’s declarative, it won’t respond differently if module X is or isn’t installed.

It’s not dynamic at install time, and it can’t deliver behaviour changes at runtime except through the modules and configuration it applies. No hooks.

You can limit the configuration applied - you can opt into some, all or none of an installed module’s config. The Recipe - and the person using it - is responsible for a valid result!

And the killer feature is that after the Recipe is applied, it’s gone. The changes are in the site’s configuration and the Recipe can be forgotten.

At its core, a Recipe is a yaml file to define the recipe. There may also be a composer json file, and a directory of provided configuration.

Here’s a recipe configuration. This is our recipe dot yaml.

At the top we can see the recipe metadata - the name is required, the type (that can be “Site” for a distribution-tier Recipe), a description.

This recipe is a small example, showing an example of a small component which you might combine with others into a more fully featured recipe.

“Install” defines which modules to install; in this Recipe we’re installing Autologout module.

“Config” defines which configuration to apply.

The “import autologout star” means we’re opting to install all available configuration that Autologout module provides. That would also include config in a config/optional directory, if the module has it.
Instead of a single “star” value, we could explicitly provide an array of specific config items to import from that module. So we might say autologout dot settings there.
If we omitted that autologout module from the config entries, we should expect only the simple configuration items from autologout to be added, by default omitting configuration entities and optional configuration.

Then we’re using a config action - via the new Config Actions API - to apply a simple config update that changes the autologout timeout from the module’s default half hour to a full hour.

This recipe uses the module defaults as a start point, and changes the single value we want changed. Tidier.

A Recipe may also contain a directory of configuration to be imported.

If you want to replace or preconfigure an entire configuration, this is the way to do it.

If you aren’t changing much, I suggest using simple config update action to set only the values required, and accept the defaults elsewhere.

Let’s look at the recipe’s composer.json next.

After unpacking this - using a composer unpack command - into the project, the project’s composer.json takes responsibility for these requirements and the recipe can be removed.

We see a type of drupal-recipe here, similar to drupal-module and friends, this tells Composer where the recipe should be placed in the project.

We’ve added a requirement on Drupal Autologout module here as that’s the module we enable. I’ve specified a version constraint because I want to know the config I apply will be valid for the installed version.

That’s a single recipe, kept intentionally small. But I think that’s the right size for that component.

Then you can use these in higher level recipes by stacking them. This tree shows a recipe with components depending on components.

In this way you can build out your preferred start point, and own the lower level details too, and mix and match as appropriate.

One of several ways we’ll use this is to make the initial configuration of a Drupal site much quicker and easier. This puts the options - currently a choice between Minimal, Standard or a distribution - into the hands of the site owner.

It’s nice to save a few hours of clicking, but having a consistent start point will be a bigger benefit for agencies using this than just saving that setup time.

And Recipes can be applied later in the piece too. The pitch there is, if your blog takes off and you need to sell merch, you’ll apply a merch shop recipe.

Recipes is still in development. You can try it out today!

More complete instructions are in that link on the slide.

You’ll want a site to start with. It’s simplest to start with a minimal install, or you can test on an existing site.

The version-specific core patches from the project will make your site Recipes capable.

Composer configuration is required to install Recipes with patches.

When your site is patched and you have a recipe to test, the drupal CLI is used to apply recipes.

After applying a recipe, the changes can be captured from Composer and config export.

With some confidence in juggling config changes, this can be used on a local copy of a real site.

Remember that Recipes are applied, so the core patch and Composer changes don’t need to be retained once you’ve finished applying them.

Recipes does less, and allows Drupal to do more, together with other new functionality.

The Project Browser will be a big part of this. It’ll allow ambitious site builders to discover and build with community provided recipes.

Automated Updates I think is also a big part of what can allow Drupal to be managed by the broad pool of ambitious builders I’d like to see.

And I think that persona of the Ambitious Site Builder is something Recipes fits so well with.