Problem/Motivation

#2352949: Deprecate using Classy as the default theme for the 'testing' profile introduced the $defaultTheme property on functional tests and the behavior associated with that. It's proven to work well.

Except in one case: when the theme provides required configuration that depends on a module already being installed. Yes, #474684: Allow themes to declare dependencies on modules hasn't landed yet, but the Seven theme has been doing this for ages, as does https://www.drupal.org/project/claro, which is being added in #3079738: Add Claro administration theme to core.

This causes failures like:

1) Drupal\Tests\claro\Functional\ClaroTest::testRegressionMissingElementsCss
Drupal\Core\Config\Schema\SchemaIncompleteException: Schema errors for claro.settings with the following errors: claro.settings:third_party_settings.shortcut missing schema

/Users/wim.leers/Work/d8/core/lib/Drupal/Core/Config/Development/ConfigSchemaChecker.php:95
/Users/wim.leers/Work/d8/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php:111
/Users/wim.leers/Work/d8/core/lib/Drupal/Core/Config/Config.php:231
/Users/wim.leers/Work/d8/core/lib/Drupal/Core/Config/ConfigInstaller.php:378
/Users/wim.leers/Work/d8/core/lib/Drupal/Core/Config/ConfigInstaller.php:137
/Users/wim.leers/Work/d8/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php:75
/Users/wim.leers/Work/d8/core/lib/Drupal/Core/Extension/ThemeInstaller.php:188
/Users/wim.leers/Work/d8/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:435
/Users/wim.leers/Work/d8/core/tests/Drupal/Tests/BrowserTestBase.php:570
/Users/wim.leers/Work/d8/core/tests/Drupal/Tests/BrowserTestBase.php:398

Discovered this in #3086435: Add automated test coverage for Claro.

Proposed resolution

Install after modules and use the correct container.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Issue fork drupal-3087036

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Status: Active » Needs review
StatusFileSize
new2.88 KB

This allows us to add test coverage and we could have done it this way to start - so I'm not sure we need to add a test here.

wim leers’s picture

Manually tested with #3086435-13: Add automated test coverage for Claro. This core patch makes that patch pass tests. 🥳

so I'm not sure we need to add a test here.

If we commit this, then #3086435-13: Add automated test coverage for Claro can become part of Claro, and then once Claro lands in core via #3079738: Add Claro administration theme to core, we'll have test coverage for this.

The only alternative way to add test coverage for this is to add a new test-only theme with required configuration that depends on a module. That seems excessive?

Tempted to RTBC. Thoughts?

alexpott’s picture

StatusFileSize
new2.42 KB
new2.81 KB

I can write a better comment.

The last submitted patch, 2: 3087036-2.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 5: 3087036-5.patch, failed testing. View results

alexpott’s picture

Yay chickens and eggs...

If we install the theme after modules then test modules which have been able to assume the presence of a theme break.

And if we install the theme before modules... we can’t turn off config schema checking just for whilst installing the default them and we can’t set static::$configSchemaCheckerExclusions[] because that only works when strict config schema is disabled.

Fun.

wim leers’s picture

Issue tags: +Configuration system
alexpott’s picture

Component: phpunit » theme system

Gonna move this to the theme system because the problem is really being caused by theme settings.

Theme's need to ship with config files that define their defaults for theme settings that don't exist yet. Seven (and Claro) are doing this. So seven.settings.yml looks like:

third_party_settings:
  shortcut:
    module_link: true

but it doesn't depend on Shortcut and there's no requirement that shortcut is around when seven is installed.

Also this "third_party_settings" isn't the same as a config entities third party settings - it's doesn't get cleaned up - because seven.settings (and any theme settings config) is not a config entity.

alexpott’s picture

Here are some options:

  • Move shortcut theme settings schema into core config schema (big downside is that contrib can't do this and it feels wrong)
  • Allow themes to listen to the module install hook - then instead of providing this in default config they could determine if shortcut was being installed and set their default
  • Have a new section in the theme.info.yml that populates theme setting defaults for modules that aren't installed
  • Redesign the theme setting configuration so it's not in THEME.settings.yml but in MODULE.THEME.settings.yml and themes can put this in their optional configuration.

Not sure which way to go.

effulgentsia’s picture

I grepped core for theme_get_setting('third_party_settings and Shortcut is the only example using this pattern.

My initial reaction to reading #10 and #11 is that we should do #11.4, except maybe flip the name order to THEME.MODULE.settings.yml, and then maybe introduce either a new function (e.g., theme_get_module_specific_setting()) to read from it, or add an optional $module parameter to the existing theme_get_setting() function.

However, I don't think we can break BC of the existing third_party_settings.shortcut.module_link theme setting. To continue to handle that specific case, I wonder if we should fix shortcut_themes_installed() and shortcut_install() to instead of hard-coding 'seven', to invoke an alter hook for determining which themes to apply that logic to. I'm suggesting an alter instead of some other hook, because we already have ThemeManager::alter().

effulgentsia’s picture

#10 changed the component of this issue, so is the title of this issue still what we want? Or is the issue something more like "third_party_settings in THEME.settings.yml cannot be dependency managed"?

effulgentsia’s picture

Title: The default theme in tests should be installed after modules and with the correct container » third_party_settings in THEME.settings.yml cannot be dependency managed

Actually, just changing the title. Feel free to change it back if we want to rescope the issue to just testing setup fixes.

wim leers’s picture

Let's take a step back.

  1. Why do we even have this problem? Because the Shortcut module wants to have theme-specific settings.
  2. Why does it have theme-specific settings? Because Shortcuts only make sense for the admin theme. A third party setting in a theme's config is one way we can do that.
  3. But there are many other ways we could do this:
    1. make admin themes have a shortcut-integration-supported: true key-value pair in their *.info.yml file
    2. add configuration to shortcut.settings.yml that allows this to be enabled per theme
    3. don't make this configurable at all, and instead make this happen automatically for all admin themes
  4. Are there other modules that have a similar configuration need?

Long story short: let's not spend a lot of time on building somethign complex if it will only ever be used by a single module that is infamous for its weird architecture.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

heddn’s picture

Just tripped on this with the gin admin theme. Its causing config schema errors now on gin admin theme.

berdir’s picture

#15 3.2 sounds like the easiest fix to me for storing such information. I don't think we should hardcode it on admin themes, that's not what this is about. there could be sites where having this in the frontend theme could be useful and it's also not something that the theme can/needs to decide on.

THEME.settings.yml is simple config, and other modules shouldn't mess with simple config of other modules or themes.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

MickeA made their first commit to this issue’s fork.

_utsavsharma’s picture

StatusFileSize
new1.63 KB
new1.63 KB

Patch for 10.1.x.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

hudri’s picture

I think I've got a related problem: My module has theme-specific settings. Previously I just stored my modules config settings in the root of theme.settings.yml. Inspired by the shortcut module, I now wanted to clean this up and move it into third party settings. Basically I wanted to update my config from

third_party_settings:
  shortcut:
    module_link: true
tailwind_jit:
  compile_html_requests: true
  html_input_file: 'foo.css'
  compile_ajax_requests: true
  ajax_input_file: 'bar.css'

to a proper schema

theme_settings.third_party.tailwind_jit:
  type: mapping
  label: 'Tailwind JIT settings'
  mapping:
    compile_html_requests:
      type: boolean
      label: 'Compile HTML requests'
    html_input_file:
      type: path
      label: 'Uncompiled CSS input file for HTML requests'
    compile_ajax_requests:
      type: boolean
      label: 'Compile Ajax requests'
    ajax_input_file:
      type: path
      label: 'Uncompiled CSS input file for Ajax requests'

and proper third party settings

third_party_settings:
  shortcut:
    module_link: true
  tailwind_jit:
    compile_html_requests: true
    html_input_file: 'foo.css'
    compile_ajax_requests: true
    ajax_input_file: 'bar.css'

The form hook is something like

function tailwind_jit_form_system_theme_settings_alter(&$form, FormStateInterface $form_state, $form_id = NULL) {
  $form['third_party_settings']['tailwind_jit'] = [
    '#type' => 'details',
    '#open' => TRUE,
    '#title' => t('Tailwind CSS Just-in-time compilation'),
    '#tree' => TRUE,
    '#parents' => ['third_party_settings', 'tailwind_jit'],
  ];
  $form['third_party_settings']['tailwind_jit']['compile_html_requests'] = [
    '#type' => 'checkbox',
    '#title' => t('Compile HTML requests'),
    '#default_value' => theme_get_setting('third_party_settings.tailwind_jit.compile_html_requests', $themeToBeConfigured),
  ];
  /* ...more form elements here... */
}

This does not work correctly, there are two problems:
1) The schema is not used/validated, the boolean value is still stored as (int) 0 / 1 and not as (bool) true / false
2) When submitting the form, it saves all my values, but wipes the existing config from shortcut module.

Reading @berdir's comment, is shortcut a bad example? Should I avoid third party settings for themes at all?

Update:

Tested the new #config_target instead of #tree and #default_value, but also does not work. It reads the existing values, but on save the schema validation seems to fail ('tailwind_jit' is not a supported key, but do I do have a schema file)

bbrala’s picture

Issue tags: +validation

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.