Themes installed by recipes have incorrect/duplicate block config when applied to a site that has an existing theme

Created on 3 July 2023, over 1 year ago
Updated 27 August 2024, 4 months ago

Problem/Motivation

I am building a recipe to for a basic startup of new projects. I want to use "minimal" profile and then enable claro and other modules. When using recipes, it seems because the installation of the extension happens in a separate step as the configuration, Drupal core will duplicate Stark's (minimal's default theme) blocks. Even by specifying the configs in recipe.yml doesn't help because in the end I have both sets of blocks

Steps to reproduce

- Fresh install with minimal profile
- Simple recipe with claro
- Optionally specify config section in recipe.yml to import Claro's config (must skip help because of dependency)

Proposed resolution

Not sure yet, but maybe if I am importing configs provided by the extension, they could be imported during installation?

Note: the code that performs the block duplication runs after any module/theme/profile installation, except during site installation: https://git.drupalcode.org/project/drupal/-/blob/9.5.3/core/modules/bloc...

๐Ÿ› Bug report
Status

Active

Version

11.0

Component

Code

Created by

๐Ÿ‡จ๐Ÿ‡ฆCanada franz Montrรฉal

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @franz
  • ๐Ÿ‡จ๐Ÿ‡ฆCanada franz Montrรฉal
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    Minimal requires Stark, and imports config: https://git.drupalcode.org/project/drupal/-/tree/9.5.3/core/profiles/min...

    Could you require Stark in your recipe, and not import the config?

    If that didn't work, do we need a config:remove option in addition to config:import in the recipe.yml?

  • ๐Ÿ‡จ๐Ÿ‡ฆCanada franz Montrรฉal

    @thejimbirch I'm not sure how requiring stark would help. These block configs are created during site installation. If you look at the link I posted in the description, you'll see that they get duplicated when claro is installed, before its configs are imported. An option to delete configs is certainly useful but in this case it is a workaround. IMO it should be possible to install a theme via recipes with the same outcome as installing manually. Maybe this would require a patch in that code so it doesn't create block copies when installing from recipes? Would certainly be the cleanest way.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States sonfd Portland, ME

    First, I just want to add a more verbose version of what you've stated in the project description.

    Recipe application installs modules and themes and imports their configuration in two steps, see An example drupal recipe in the distirbutions and recipes initiative docs.

    1. The extension is installed and its simple configuration is imported.

      During the install only simple configuration from the new modules is created. This allows the Drupal recipe control over the configuration.

    2. The configuration provided directly by the recipe is installed, along with any configuration entities provided by extensions you installed and allowed in the config section.

      A Drupal recipe can have a config directory. All configuration is this directory will be imported after the modules have been installed. Additionally, the Drupal recipe can install configuration entities provided by the modules it configures. This allows them to not have to maintain or copy this configuration.

    It seems that the block module creates blocks for claro in step 1, via hook_themes_installed(), because the Claro provided blocks are not simple configuration and therefore their configuration is not imported yet). Then the claro blocks get created in step 2, if you've allowed them.

    I suspect your recipe looks something like this:

    # ...
    install:
      - drupal:claro
    # ...
    config:
      import:
        claro: '*'
    # ...
    

    If we don't allow the config entities from Claro to be installed, e.g. by updating your recipe.yml and removing the entry under config, we'll only get one set of blocks, but they'll be the blocks created by the block module in step 1. Though I think we'd really rather get just the set of blocks supplied by the Claro module (if allowed in the recipe.yml), and the block module would never create the set of blocks in step 1 while a recipe is being applied.

    Maybe this would require a patch in that code so it doesn't create block copies when installing from recipes?

    IMO, this is the right approach. I think the block module needs to make an exception for when the theme is installed by a recipe. In the code for hook_themes_installed(), you can already see where they've made a similar exception for installation profiles:

    function block_themes_installed($theme_list) {
      // Disable this functionality prior to install profile installation because
      // block configuration is often optional or provided by the install profile
      // itself. block_theme_initialize() will be called when the install profile is
      // installed.
      if (InstallerKernel::installationAttempted() && \Drupal::config('core.extension')->get('module.' . \Drupal::installProfile()) === NULL) {
        return;
      }
    
      // code to initialize themes with duplicate blocks omitted here... 
    }
    
    
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    Another person reports this in #3436143: Duplicate blocks appear after standard recipe is applied โ†’ .

    The root core issue is ๐Ÿ“Œ Copy block configuration from admin theme when enabling an admin theme Active .

    The issue definitely exists, but you can now use the installer that is in core to install Drupal using a recipe, which bypasses the need for an install profile. This helps the issue if you are starting a new Drupal site, not if you are applying a recipe to an existing site.

    php core/scripts/drupal quick-start path/to/recipe

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia narendraR Jaipur, India
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States phenaproxima Massachusetts
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States thejimbirch Cape Cod, Massachusetts

    Updating title, adding credits from duplicate issue.

  • ๐Ÿ‡ช๐Ÿ‡ธSpain d70rr3s

    Just to shed some light on the matter. I'm facing the same issue in this case with GIn theme but, I don't have a gin: * in my recipe. This is my actual code:

    name: Admin UI
    type: Standard
    description: Sets up a nice administrative theme and navigation.
    install:
      - coffee
      - gin
      - gin_login
      - gin_toolbar
      - navigation
    config:
      import:
        coffee:
          - coffee.settings
        gin:
          - gin.settings
        gin_login:
          - gin_login.settings
        navigation: "*"
      actions:
        system.theme:
          simple_config_update:
            admin: gin
    

    Probably blocks by Gin are getting imported even if you explicitly ask for it. Probably a bug somehow?

  • ๐Ÿ‡ช๐Ÿ‡ธSpain d70rr3s

    Ah, I see. @sonfd explains it in here ๐Ÿ“Œ Copy block configuration from admin theme when enabling an admin theme Active , is how the block module behaves when installing a new theme :/

  • Assigned to bhuvaneshwar
  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia prashant.c Dharamshala

    Adding the related issue.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia bhuvaneshwar

    Agree with #5 in order to omit duplicate blocks while initializing themes we can use:

    // Get the list of themes installed and blocks to assign.
    $themes = system_list('theme_enabled');

    foreach ($themes as $theme => $info) {
    // Get the default blocks for the theme.
    $blocks = theme_get_default_blocks($theme);

    // Filter out duplicates.
    $unique_blocks = array_unique($blocks, SORT_REGULAR);

    // Assign the unique blocks to their regions.
    foreach ($unique_blocks as $block) {
    // Assign the block to the region.
    block_place_block($block);
    }
    }

    As I'm also facing the same issue in this case with GIn theme but, I don't have a gin: * in my recipe too

  • Issue was unassigned.
Production build 0.71.5 2024