Problem/Motivation
Drupal\views\Entity\View's #[ConfigEntityType(...)] attribute defines its label, label_collection, label_singular and label_plural properties like this:
label: new TranslatableMarkup('View', ['context' => 'View entity type']),
TranslatableMarkup::__construct() has the signature ($string, array $arguments = [], array $options = [], ...). Passing ['context' => 'View entity type'] as the second argument puts it in $arguments (placeholder replacements), not
$options (where context actually belongs). Because none of these strings contain an @/%/: placeholder, the array is silently unused, and the context is effectively dropped: the string resolves as if it had no context at all.
The correct pattern is used just a few lines further up in the same file (Drupal\Core\Entity\Attribute\ConfigEntityType::$group_label):
public readonly TranslatableMarkup $group_label = new TranslatableMarkup('Configuration', [], ['context' => 'Entity type group']),
Real-world impact
This isn't just a theoretical mismatch. On a site with the Dutch (nl) translation installed, the string "View" already has two separate locales_source rows:
- source "View", context "" → translated "Weergeven" (used as, e.g., the local-task "View" tab label)
- source "View", context "View entity type" → translated "Overzicht"
Because the context is dropped, \Drupal::entityTypeManager()->getDefinitions()['view']->getLabel() resolves to the context-less translation ("Weergeven") instead of the correct, context-scoped one ("Overzicht"). This is visible
directly in the UI: on admin/config/development/configuration/single/export, the "View" entity type shows up mislabeled as "Weergeven" in the config type dropdown instead of "Overzicht" — which reads as if the option for exporting
Views config is simply missing.
(Interestingly, getCollectionLabel() happens to resolve correctly in our testing — worth double-checking during review, since it uses the same broken pattern.)
Steps to reproduce
1. Install Drupal with the Dutch (nl) interface translation.
2. Visit admin/config/development/configuration/single/export.
3. Look at the "Configuration type" select list: the option for Views config is labeled "Weergeven" (the generic translation of "View", also used as a tab label elsewhere) rather than "Overzicht" — easy to miss or mistake for a
missing option entirely.
Also reproducible directly (in Dutch):
\Drupal::entityTypeManager()->getDefinition('view')->getLabel();
// "Weergeven" — expected: "Overzicht"
Proposed resolution
Move the context array to the third constructor argument in all four TranslatableMarkup calls in core/modules/views/src/Entity/View.php:
label: new TranslatableMarkup('View', [], ['context' => 'View entity type']),
label_collection: new TranslatableMarkup('Views', [], ['context' => 'View entity type']),
label_singular: new TranslatableMarkup('view', [], ['context' => 'View entity type']),
label_plural: new TranslatableMarkup('views', [], ['context' => 'View entity type']),
Patch attached.
Remaining tasks
- This specific instance was likely introduced by the annotations-to-PHP-attributes conversion (#3252386 (https://www.drupal.org/project/drupal/issues/3252386)): the old @Translation("View", context = "View entity type") Doctrine annotation syntax takes context as a named annotation property, not a positional constructor argument, so a mechanical/scripted conversion could easily place it in the wrong slot of the new new TranslatableMarkup(...) call.
- I checked the currently installed Drupal 11.4.6 core tree for the same literal pattern (new TranslatableMarkup('...', ['context' => ...]) with the context as the 2nd argument) and found no other matches beyond these four in View.php. That's not a guarantee nothing else was missed elsewhere (other Drupal versions, or subtler variations of the same issue) — a broader audit of entity type / plugin attribute definitions converted under #3252386 for this exact argument-order mistake would be worth doing, ideally as an automated check (e.g. a small PHPStan or grep-based rule) rather than a manual read-through.
User interface changes
None beyond correcting the mislabeled string.
API changes
None — this only fixes the translation context so existing translations resolve as originally intended; it does not change any public API.
| Comment | File | Size | Author |
|---|---|---|---|
| view-entity-type-label-context.patch | 1.89 KB | inascon |
Issue fork drupal-3622503
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 #5
burcu.sogut@drupart.com.tr commentedOpened an MR. It moves the context to the $options argument in all four TranslatableMarkup() calls in View.php.
The conversion also dropped the context from label_count. The old @PluralTranslation annotation had context = "View entity type". The MR adds 'context' => 'View entity type' to label_count.
The conversion happened in #3396166. I compared all files changed in that commit with their old annotations. View.php is the only file with a lost context.
The MR adds testEntityTypeLabelContext() to ViewStorageTest. The test fails without the fix. The views Unit and Kernel tests pass locally.
Comment #6
burcu.sogut@drupart.com.tr commentedComment #7
nisha_j commentedReviewed and tested MR !17359.
Code review:
- In View.php, the 'View entity type' context was passed as the second argument (the placeholder arguments) of TranslatableMarkup, so it was silently ignored. The MR moves it to the third argument ($options) for label, label_collection, label_singular and label_plural.
- label_count gets 'context' => 'View entity type' back, matching the old @PluralTranslation annotation from before the attribute conversion in #3396166. getCountLabel() passes the context through to formatPlural(), so this works.
- I searched View.php and found no other places with the same mistake.
Testing:
- Test-only (fix reverted, new test kept): testEntityTypeLabelContext fails with expected 'View entity type', actual ''. So the test covers the bug.
- With the fix: ViewStorageTest passes (3 tests, 101 assertions).
- phpcs and phpstan report no issues on the changed files.
- Pipeline #991357 passes. The only failures are the two allowed-to-fail PHP 8.6 unit test jobs, which this change doesn't touch.
- Manual check on a Drupal 12.0.0-beta1 site: before the fix, the view entity type label has no context, so a translation added for the "View entity type"
The change is small and focused, and the test the count label. It looks good to me. I'm leaving it at Needs review so another reviewer can confirm.
AI disclosure: I used an AI assistant to draft this comment. I reviewed the code and verified the results myself.
Comment #8
longwaveThe fix looks correct to me, I don't even think this warrants a test but as one has been written let's just ship it.
As this affects translatable strings this is only suitable for a minor release.