Problem/Motivation
A setting's label and description are often written twice: as label in its config schema, and as #title and #description on its settings form element.
Example: for the page cache's maximum age system.schema.yml reads:
max_age:
type: integer
label: 'Max age'
And PerformanceForm reads:
$form['caching']['page_cache_maximum_age'] = [
'#type' => 'select',
'#title' => $this->t('Browser and proxy cache maximum age'),
'#config_target' => 'system.performance:cache.page.max_age',
'#options' => $period,
'#description' => $this->t('This is used as the value for max-age in Cache-Control headers.'),
];
There a number of challenges with the code above. They often drift (e.g. 'Max age' vs 'Browser and proxy cache maximum age') but perhaps more importantly, the form fields can't be accessed by other users inside or outside of Drupal. This issue was split out of #3635315: [Prototype] Write a setting's rules once, in config schema, and use them for validation, forms and the published JSON Schema where I go into a lot more detail about these challenges.
With the MR, the schema looks as follows:
max_age:
type: integer
label: 'Browser and proxy cache maximum age'
description: 'This is used as the value for max-age in Cache-Control headers.'
And the form element can leave out the title and description:
$form['caching']['page_cache_maximum_age'] = [
'#type' => 'select',
'#config_target' => 'system.performance:cache.page.max_age',
'#options' => $period,
];
The text now lives in one place, so the form and the schema can no longer drift apart. And because the label and description moved out of the form's PHP code and into its schema, other code (e.g.ECA, FlowDrop, Maestro, Tool API, etc) can describe a setting the same way a Drupal form does.
#3477363: Add a way to automatically generate basic config forms goes further: it generates whole form elements from config schema. This issue helps us get a step closer to making #3477363 reality.
In #3477363, joachim and james.williams agreed that a description belongs in config schema (https://www.drupal.org/project/drupal/issues/3477363#comment-16098165).
Issue fork drupal-3636978
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
Comment #4
dries commentedI took the code from the prototype in #3635315 and evolved it.
When a form element in a
ConfigFormBaseform has a#config_targetand no#titleor#description, we now use thelabelanddescriptionspecified in the config schema.If a form element already has a
#titleor#description, the existing ones continue to be used. That way existing forms remain unchanged, and we can convert forms one at a time.The MR adds
TypedConfigManagerInterface::getDefinitionForKey(), which reads the definition straight from the schema. It's faster and more reusable than the prototype I had in #3635315.As a demo,
max_age's title and description moved fromPerformanceFormintosystem.schema.yml. The form renders the same as before, except that we still have to add translation support for descriptions.I'd love feedback on the direction before going further. If people like it, the same pattern can be applied to many other settings forms in follow-ups.
Disclaimer: I built this with the help of an LLM but reviewed everything extensively.
Comment #5
dries commentedComment #6
alexpottWe need an issue open in potx to extract these strings from schema.
Comment #7
dries commentedAgreed, we need a potx issue, and I'm happy to open it. I wanted to know if we were aligned on the idea and approach first.
Comment #8
borisson_I think the direction here looks good, this seems simpler than the min/max issue.