Skip to main content

Drupal distributions, blocks, and subthemes

Authors
September 25, 2018
Body paragraph

In Part 4 of a current series on managing shared configuration for Drupal distributions we looked at needs and options for altering configuration provided by extensions (modules, themes, or the site's installation profile). We covered common needs such as altering user roles to add permissions. But when it comes to altering configuration, blocks are a special case--hence this bonus installment!

When you create a site based on a distribution, there may be a requirement to customize the look and feel. The usual solution is to create a custom subtheme for the site; see the drupal.org documentation on subtheming. That way you can get everything the distribution provides but give the site a custom presentation.

Using a custom theme will work fine for most configuration. But it won't work for configuration that includes the theme itself as a dependency--like blocks.

As explained in the drupal.org handbook page Working with Blocks:

Blocks are boxes of content rendered into an area, or region, of a web page (such as "User Login" or "Who's online") that can be displayed in regions (such as footer or sidebar) on your page.

Blocks are configured per theme. Typically a Drupal distribution will ship with a designated default theme--a core theme, a contributed theme, or, most commonly, one written especially for the distribution. Blocks are placed into this theme, ensuring sites get all the expected page elements.

But this approach breaks down on sites using a custom theme. For example, if a site is installed with a distribution, sets a custom theme as the default theme, and then updates to a new version of the distribution and brings in configuration updates including new blocks, those new blocks won't show up on the site. That's because the new blocks were created for the distribution's theme--not the custom theme that's the default theme on the site.

Even if a distribution-provided block did show somehow in a custom theme, it might be in the wrong position. Each Drupal theme supports a designated set of regions--page areas that blocks can be placed in. While in most cases a custom theme will be given a similar set of regions as the distribution's theme, this may not always be the case.

Block Theme Sync

In Drutopia we drafted a module to try to address these problems.

Block Theme Sync allows a site admin to configure a "theme mapping": a relationship between two themes. As well as specifying a source and destination theme, a theme mapping includes a mapping of source to destination regions.

Block Theme Sync uses an approach of cloning and then synchronizing. When a theme mapping is in place, all blocks created for the source theme are automatically cloned and created for the destination one. Any subsequent change to block configuration in the source is applied as well to the destination theme.

Say for example that there's a theme mapping with Bartik selected as the source theme and Mytheme as the destination theme. Whenever a block is added to Bartik, a corresponding block will be added to Mytheme and assigned to the corresponding theme region as specified in the theme mapping.

This approach works, but has tradeoffs. The main one is inherent to cloning. Since we now have two distinct versions of the block configuration, we face the complexity of divergence between the two. For example, if a destination theme's block is edited, how do we handle that customization when the source theme's block is updated? That's a question we covered in the installment on Respecting Customizations and Updating from Extensions. There's a relevant issue open on Block Theme Sync: Use three-way merging when synchronizing.

Better Sub-themes

Not long after our work on Block Theme Sync, Stuart Clark (Deciphered on drupal.org) posted the Better Sub-themes module. While similar in many ways to Block Theme Sync, it takes a different basic approach.

Like Block Theme Sync, Better Sub-themes provides a way to designate a source and destination relationship between themes and also to map regions. Rather than doing so through configuration, Better Sub-themes extends the theme info file format.

But in the implementation, rather than cloning and synchronizing, for every block in the source theme, Better Sub-themes dynamically layers on a block in the destination theme. These destination theme blocks don't exist as separate configuration entities on the site. So they don't show up in the site's block admin screen for the destination theme, or when site configuration is exported. They can't be separately edited. But they show up on the site in their designated theme regions.

If Block Theme Sync implements a cloning and synchronizing pattern, Better Sub-themes uses inheritance. This avoids the problems inherent in cloning. But it introduces challenges of its own. The fact that inherited blocks don't show up in the block administration UI is potentially confusing--how do you edit them? And it makes it difficult to position other blocks in relation to the inherited ones.

Potential enhancements

Both Block Theme Sync and Better Sub-themes are affected by a quirk of Drupal core's theme system.

By default, when you install a theme, if the theme doesn't supply any blocks of its own, Drupal core copies over the blocks that are enabled at that time for the current default theme--see block_theme_initialize(). And a mea culpa: I wrote the first version of Drupal core's theme region system, and included that quirk in the implementation ;)

Here's how this quirk affects each of the modules:

  • With Block Theme Sync, synchronization is done only when a block from the source theme is saved. if the destination theme doesn't provide any blocks, it will get an initial set of blocks created--but won't get any that were created after the theme was installed but before Block Theme Sync was in place. If it does provide blocks, it won't get any from another theme. Relevant issue: Initialize theme blocks on creation of theme mapping.
  • With Better Sub-themes, when we (a) install a distribution site, getting its standard default default theme along with a set of blocks, then (b) switch the default theme to a custom subtheme with Better Sub-themes support, all the source theme blocks will appear twice on the site: first, because they were cloned by Drupal core; second, because they're inherited from the source theme via Better Subthemes. Relevant issue: Prevent or delete duplicate blocks.

Related core issue

Takeaways

  • For distributions that include block placement, subthemes present challenges.
  • There are two different modules available that attempt to address these issues: Block Theme Sync and Better Sub-themes.
  • Both modules are more proofs of concept than polished and proven solutions.
  • Each has its relative merits, and which if either is a fit will depend on the particular distribution use case.

Addendum: since writing this blog post, I wrote the Skins module for Drupal 8/9 to address the issue of blocks and subthemes. See the Skins project page and Skins handbook on drupal.org.