Profile picture for user admin
Daniel Sipos
24 May 2023

In this article we are looking at how we can override (or extend rather) configuration schema that is already defined by a core or a contributed module.

I’ve been working with configuration schema for a long time. I have many examples in my book that talk about how we need to and can define our configuration schema. For example, when we create a field type with some configuration options, we just create a schema.yml file and define the settings there. You can read more about it on this Drupal.org documentation page.

However, I ran into something new. I had to override some field type classes (such as StringItem and AddressItem) with the purpose of adding an extra storage configuration; a simple checkbox/boolean value. Easy. Then I opened the schema.yml file and suddenly stopped because I had no clue what to write. After all, I did not make a new field plugin right? These field plugins might already have a configuration schema defined for their storage settings. And sure enough, we do have for StringItem:

field.storage_settings.string:
  type: mapping
  label: 'String settings'
  mapping:
    max_length:
      type: integer
      label: 'Maximum length'
    case_sensitive:
      type: boolean
      label: 'Case sensitive'
    is_ascii:
      type: boolean
      label: 'Contains US ASCII characters only'

For AddressItem, on the other hand, we don’t have one.

An option is to override the field.storage_settings.string schema and define a new one for field.storage_settings.address. Sure. But then, if core alters the schema for StringItem, we lose those changes because our override would take over.

Then I discovered hook_config_schema_info_alter(). Using this hook, we can dynamically alter existing schema. For example, something like this:

/**
 * Implements hook_config_schema_info_alter().
 */
function my_module_config_schema_info_alter(&$definitions) {
  $definitions['field.storage_settings.string']['mapping']['extra_option'] = [
    'type' => 'boolean',
    'label' => 'Extra option',
  ];
}

So this is pretty cool and it works. Now, even if core changes the schema for these field storage settings, we are fine. But then, problem: AddressItem doesn’t have one and this hook doesn’t allow us to define brand new schema in them. It will throw an exception. We can alter but cannot add to or remove entries from the list. So, in this case, I had to create it in the schema.yml file myself:

field.storage_settings.address:
  type: mapping
  label: 'Address storage settings'
  mapping:
    extra_option:
      type: boolean
      label: Extra option

This works. To be honest, however, I’m not very happy. Because if the Address module decides to add some storage settings, and consequently a schema entry for them, my schema definition would override it. So I will need to pay attention. Probably Address should define the storage settings with no values as core does for all its fields. Do you have any better ideas on how to be a bit more future-proof with this?

Profile picture for user admin

Daniel Sipos

CEO @ Web Omelette

Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.

Contact us

Comments

Add new comment