Problem/Motivation
Strictly speaking, this is not a bug in SDC. But … I just lost an hour over something SDC could've easily warned against:
LOLOL an hour worth of debugging only to find out that SDC prop names may contain dashes but Twig variable names must not: https://github.com/twigphp/Twig/issues/1967 — for example
{{ test-REQUIRED-string }}is compiled by Twig to:
// line 5 yield $this->extensions['Drupal\Core\Template\TwigExtension']->escapeFilter($this->env, ((($context["test"] ?? null) - ($context["REQUIRED"] ?? null)) - ($context["string"] ?? null)), "html", null, true);… which means that the DX of SDC is leaving a lot to be desired: if Twig doesn't support this, and SDC supports only Twig, then I expect SDC to not allow this either.
— #3463583-15: Use the `all-props` component for testing form backend + frontend integration
Proposed resolution
- Restrict prop and slot names to identifiers Twig can actually use: start with a letter or underscore, followed by letters, digits, or underscores.
- Use JSON Schema's
allOfto enforce prop name validation also at the JSON Schema level.
BC concerns: We are more restrictive than before in theory. In practice those props/slots could have never worked with twig.
Remaining tasks
- Review.
- Change record.
User interface changes
None.
Introduced terminology
None.
API changes
Validation is tightened to actual valid props/slots.
Data model changes
JSON Schema changes are more restrictive, but we were restricting on validation anyway.
Release notes snippet
Single-directory component prop and slot names are now restricted to valid Twig identifiers (letters, digits, and underscores; must start with a letter or underscore).
| Comment | File | Size | Author |
|---|
Issue fork drupal-3465228
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:
- 3465228-twig-disallows-dashes
changes, plain diff MR !15697
Comments
Comment #2
quietone commentedComment #3
pdureau commentedHi Wim,
Thanks for this valuable feedback. It makes sense for props (and also slots) machine names to follow
machine_namedata type: https://www.drupal.org/node/2954832With:
So:
We can enforce it to
patternPropertiesin JSON Schema.Comment #4
cosmicdreams commentedI started looking into making this. On the surface this seems to be the responsibility of Drupal/Core/Theme/ComponentPluginManager.php. That would be a place where we could alter the schema validation logic of a Component definitition.
But the configuration shown above seems to be a solution that can be applied to each individual component schema definition. As in, it would be the responsibility of the developer to include the schema constraint per property.
Are you saying it's possible to modify the schema of a component, through the same config-based fix, that would impact the default definition of any property the component might have?
Comment #5
wim leers#3++ … except … that
#4: No, @pdureau is proposing to update https://git.drupalcode.org/project/sdc/-/raw/1.x/src/metadata.schema.json … which interestingly lives outside Drupal core 😱😅 (Is there an issue to change that? Was that a conscious choice? I cannot find docs covering that. 🤔)
Comment #6
pdureau commented@wim-leers the schema lives here now: https://git.drupalcode.org/project/drupal/-/tree/11.x/core/assets/schema...
Comment #7
kristen polThanks for that... added an XB issue as a result:
#3470003: Update components to use core metadata.schema.json instead of old SDC module one
Comment #9
vensires@pdureau, I am not so familiar with the *.schema.json syntax etc but we currently have the following:
"props": { "$ref": "http://json-schema.org/draft-04/schema#" }, "slots": { "$ref": "#/$defs/slotDefinition" },So, where could these constraints be added in the schema.json file?
Comment #10
pdureau commentedHello Panagiotis,
This would be my (non tested) proposal for slots. Remove the
-from/"$defs"/slotDefinition/patternProperties/"^[a-zA-Z0-9_-]$". So:/"$defs"/slotDefinition/patternProperties/"^[a-zA-Z0-9_]$"Unfortunately, I don't think it is possible to enforce it for props because we are delegating the schema to
http://json-schema.org/draft-04/schema#Comment #11
mradcliffeI performed Novice Triage on this issue. I added the Novice issue tag and the Needs issue summary update issue tag so that the notes provided by @pdureau can be added to the issue summary to clarify the scope of the issue.
Comment #12
lirak commentedDuring DrupalCon Atlanta Kwiseman helped me update the proposed resolution.
Comment #14
pdureau commented@lirak : can you do a MR please?
Comment #15
penyaskitoAdded #3519917: Disable additionalProperties in slots in SDC json schema as related.
The
patternPropertiesregexp means that properties that match that regexp will require those validation rules. But not that properties MUST match that regexp.Comment #16
gengo_kI am removing the Novice tag from this issue because it does not have clear steps at this point.
I’m using this documentation as a source: https://www.drupal.org/community/contributor-guide/task/triage-novice-is...
Comment #17
gengo_kComment #19
penyaskitoI'm working on this.
Comment #20
penyaskitoExpanded issue title to slots too (still needing IS update).
Variants are not affected, those don't convert to Twig variables. Adding a explicit positive test for that here too.
Comment #22
penyaskito@pdureau #10: Apparently it's possible!
Tested this and it worked.
I went a bit further and constrained to:
^[a-zA-Z_][a-zA-Z0-9_]*$, AKA the php valid variable validator, which in absence of more concrete twig docs, it's what twig supports: start with letter or underscore, contain letters, digits, underscores. The only difference is that php allows non-ASCII characters. I think we are fine being more restrictive, because we weren't allowing that before anyway.Expanded test coverage covering these, both for props and slots.
We were already using
additionalProperties: false, so are enforcing all of them.For
variantswe don't need this, they don't convert to php/twig variables. Leftmeta:enumuntouched too.I used
$commentfor documenting this too. This is hard to maintain, so any help should be welcome. But happy to remove that if you don't agree.Comment #23
penyaskitoDisclosure: I used AI (Claude - Opus 4.7) for validating my assumptions with variants and meta:enums not affected, and for comparing our new regex with the one at https://www.php.net/manual/en/language.variables.basics.php and explaining the differences.
Comment #24
penyaskitoUpdated IS update.
Comment #25
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #26
pdureau commentedWow! That sounds great. I am a bit surprised with a schema without a
typeat the root level, my JSON schema knowledge is still expanding.Indeed, they are variable values, not variables names.
Comment #27
penyaskitoComment #28
penyaskitodraft-06 is supported by
justinrainbow, and that would have support forpropertyNames.Comment #29
smustgrave commentedSeems there's 1 open thread from @penyaskito and 1 comment about a follow up.
Comment #30
smustgrave commentedThanks for responding to it. Believe all feedback has been addressed for this one.
Comment #34
longwaveDebated whether to add a change record but as far as I can see if you tried to do this before it never would have worked properly anyway.
As this is a minor behaviour change let's just ship it in 11.5 and 12.0 only.
Committed and pushed 7dd6a4c9d48 to main and ea8be0f9dc3 to 12.0.x and 29fac2e9834 to 11.x. Thanks!
Comment #37
gábor hojtsyCanvas has
test-slot,test-slot-only-required,new-slotand0-slot, which is how I came here :) While that indeed would not have worked, this fails Canvas tests on what will become 11.5. Opened https://git.drupalcode.org/project/canvas/-/work_items/3592273 for this.This may or may not indicate a change record is needed since dashes only worked in a limited way in tests, not in actual rendering, even in Canvas.