0

Is there any way we can change configuration items when we switch to a specific theme?

Our (simplified) situation:

  • Using Drupal 10.2
  • Our customers can choose between different themes
  • Every theme uses content-type 'Page'
  • One theme has a background-picture, differing from page to page, uploaded by the editors. So if this theme is chosen, 'Page' needs to have a field 'background-image' (media).

How can I add a field to a content-type when setting this theme as default theme without manual changes in the admin-backend?

What I already tried:

  • Using hook_install() => This hook only works on modules and not on themes. (https://www.drupal.org/node/2652542). And even if: It would be executed on theme installation and not when it is set as default.

  • Using config/install (as mentioned in Is there a theme equivalent of hook_install()?) => This allows me to install field.storage.node.field_background_picture and field.field.node.page.field_background_picture, but not to add the field_background_picture to the already existing core.entity_form_display.node.page.default and similar configs - I now have the field, but neither in the form nor in the display.

  • Using config/optional => The same as above. Additions or changes to existing config do not lead to errors, but the changes to the form and view are silently ignored. And even if: It would be executed on theme installation and not when it is set as default.

Thanks in advance and greetings from Switzerland mullzk

2
  • 2
    You could maybe always have the field set on the content type and then do a form alter on the node creation/edit form to add/remove the field depending on the default theme? Commented Mar 20 at 14:10
  • 1
    Two problems - 1. Themes are just presentation, they shouldn't try to alter the structure of the site (even though they technically can, as you've found out). Field creation belongs in a module, or standard site-wide config. 2. Config creation isn't optional, or at least not dynamically so. Syncing config, to make sure the site structure is the same as the intended state, is where fields get created/removed, not in response to a theme being changed, or some other update to the active configuration. Creating the field unconditionally, then manipulating with hook_form_alter, is your best bet
    – Clive
    Commented Mar 20 at 16:50

1 Answer 1

0

Thanks a lot both @Clive & @unusedspoon, this makes sense.

hook_form_alter has its problem as well though: We use the administration theme when editing or creating content - so hook_form_alter is not called on our theme, but on claro.

I now created hooks in the module, where we define our page-content-type:

function pagemodule_form_alter(array &$form) {
  $theme_name = \Drupal::config('system.theme')?->get('default');
  if ($theme_name != 'background_image_theme') {
    $form['field_background_image']['#access']=false;
  }
}
function pagemodule_preprocess_node__page(array &$variables) {
  if (isset($variables['elements']['field_background_image'])) {
    $theme_name = \Drupal::config('system.theme')?->get('default');
    if ($theme_name != 'background_image_theme') {
      hide($variables['content']['field_background_image']);
    }
  }
}

I understand the approach that themes are presentation only.
But I also think that putting this logic outside the themes can get a bit messy, if we have have >10 themes with different fields each.

Perhaps, I will add the theme-specific fields in a list in the theme.info.yml and then query this list (via theme.manager-service) in the module-hooks above...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.