Statamic\Entries\Collection::createLabel() and Statamic\Taxonomies\Taxonomy::createLabel() currently support a single translation key per collection/taxonomy, but not per blueprint. In real-world editorial workflows, one collection/taxonomy often contains multiple blueprint types, and a generic "Create Entry" / "Create Term" label is less clear than context-specific labels (e.g., "Create News Release Post", "Create Video Post", etc.).
Problem
- Current behavior only resolves:
- Collection: one key per collection handle
- Taxonomy: one key per taxonomy handle
- Missing behavior: no native blueprint-specific label resolution.
- Result: users see generic create labels when creating entries/terms for specific blueprints, reducing clarity in multi-blueprint setups.
Requested Enhancement
Update createLabel() in both classes to support a blueprint-aware lookup before existing fallbacks:
- If a blueprint context is present (from the current CP request), attempt blueprint-specific key.
- If not found, use existing collection/taxonomy-level key.
- If still not found, use current generic fallback label.
Proposed implementation for both methods
Statamic\Entries\Collection::createLabel()
public function createLabel()
{
// CHANGED: `messages` becomes `statamic::messages` for consistency with `Taxonomy::createLabel()`
$key = "statamic::messages.{$this->handle()}_collection_create_entry";
// NEW: Store the generic fallback once to avoid duplicate translation calls
$fallbackLabel = __('Create Entry');
// NEW: Read optional blueprint context from the CP request
$blueprint = request()->query('blueprint');
// NEW: Attempt blueprint-specific translation before legacy base behavior.
// Check whether a blueprint was requested
if (! empty($blueprint)) {
// Build the blueprint-specific translation key
$blueprintKey = "{$key}.{$blueprint}";
// Resolve the blueprint-specific translation
$blueprintTranslation = __($blueprintKey);
// Check if the blueprint translation exists
if ($blueprintTranslation !== $blueprintKey) {
// Return the blueprint-specific label
return $blueprintTranslation;
}
}
$translation = __($key);
// NEW: Guard non-string translation values before applying original logic
// Check whether the resolved translation value is a string
if (! \is_string($translation)) {
// Return the generic fallback label for non-string configuration values
return $fallbackLabel;
}
if ($translation === $key) {
// CHANGED: Use the variable instead
return $fallbackLabel;
}
return $translation;
}
Statamic\Taxonomies\Taxonomy::createLabel()
public function createLabel()
{
$key = "statamic::messages.{$this->handle()}_taxonomy_create_term";
// NEW: Store the generic fallback once to avoid duplicate translation calls
$fallbackLabel = __('Create Term');
// NEW: Read optional blueprint context from the CP request
$blueprint = request()->query('blueprint');
// NEW: Attempt blueprint-specific translation before legacy base behavior.
// Check whether a blueprint was requested
if (! empty($blueprint)) {
// Build the blueprint-specific translation key
$blueprintKey = "{$key}.{$blueprint}";
// Resolve the blueprint-specific translation
$blueprintTranslation = __($blueprintKey);
// Check if the blueprint translation exists
if ($blueprintTranslation !== $blueprintKey) {
// Return the blueprint-specific label
return $blueprintTranslation;
}
}
$translation = __($key);
// NEW: Guard non-string translation values before applying original logic
// Check whether the resolved translation value is a string
if (! \is_string($translation)) {
// Return the generic fallback label for non-string configuration values
return $fallbackLabel;
}
if ($translation === $key) {
// CHANGED: Use the variable instead
return $fallbackLabel;
}
return $translation;
}
This approach keeps existing behavior, adds blueprint-specific support, and handles array-only translation maps without warnings or invalid return types.
Proposed Translation Key Pattern
-
Collection
- Base:
statamic::messages.{collection}_collection_create_entry
- Blueprint-specific:
statamic::messages.{collection}_collection_create_entry.{blueprint}
-
Taxonomy
- Base:
statamic::messages.{taxonomy}_taxonomy_create_term
- Blueprint-specific:
statamic::messages.{taxonomy}_taxonomy_create_term.{blueprint}
Example
For post collection with news_release blueprint:
statamic::messages.post_collection_create_entry.news_release = "Create News Release Post"
- fallback:
statamic::messages.post_collection_create_entry = "Create Post"
- fallback:
"Create Entry"
For post_tag taxonomy with clinical blueprint:
statamic::messages.post_tag_taxonomy_create_term.clinical = "Create Clinical Tag"
- fallback:
statamic::messages.post_tag_taxonomy_create_term = "Create Tag"
- fallback:
"Create Term"
Concrete language file examples
These are practical examples of how projects currently configure labels for different scenarios.
Scenario A: Collection-level override only
lang/vendor/statamic/en/messages.php
<?php
return [
'post_collection_create_entry' => 'Create Post',
];
Scenario B: Collection + blueprint-specific overrides
lang/vendor/statamic/en/messages.php
<?php
return [
'post_collection_create_entry' => 'Create Post',
'post_collection_create_entry.news_release' => 'Create News Release Post',
'post_collection_create_entry.video' => 'Create Video Post',
];
Scenario C: Collection with no collection-level fallback (array-only blueprint labels)
lang/vendor/statamic/en/messages.php
<?php
return [
'post_collection_create_entry' => [
'news_release' => 'Create News Release Post',
'video' => 'Create Video Post',
],
];
Expected behavior:
blueprint=news_release => Create News Release Post
blueprint=video => Create Video Post
blueprint=post (missing key) => generic fallback Create Entry
- no
blueprint query param => generic fallback Create Entry
Scenario D: Taxonomy-level override only
lang/vendor/statamic/en/messages.php
<?php
return [
'post_tag_taxonomy_create_term' => 'Create Tag',
];
Scenario E: Taxonomy + blueprint-specific overrides
lang/vendor/statamic/en/messages.php
<?php
return [
'post_tag_taxonomy_create_term' => 'Create Tag',
'post_tag_taxonomy_create_term.clinical' => 'Create Clinical Tag',
'post_tag_taxonomy_create_term.research' => 'Create Research Tag',
];
Scenario F: Taxonomy with no taxonomy-level fallback (array-only blueprint labels)
lang/vendor/statamic/en/messages.php
<?php
return [
'post_tag_taxonomy_create_term' => [
'clinical' => 'Create Clinical Tag',
'research' => 'Create Research Tag',
],
];
Expected behavior:
blueprint=clinical => Create Clinical Tag
blueprint=research => Create Research Tag
blueprint=general (missing key) => generic fallback Create Term
- no
blueprint query param => generic fallback Create Term
Expected resolution behavior across scenarios
- If
{base}.{blueprint} exists, return that.
- Else if
{base} exists, return that.
- Else return the generic fallback (
Create Entry / Create Term).
- For array-only setups (no string
{base} value), missing or absent blueprint should also fall back to the generic label.
Benefits
- Better author/editor UX in multi-blueprint structures.
- Backward-compatible fallback behavior.
- Leverages existing translation architecture without requiring UI configuration changes.
Statamic\Entries\Collection::createLabel()andStatamic\Taxonomies\Taxonomy::createLabel()currently support a single translation key per collection/taxonomy, but not per blueprint. In real-world editorial workflows, one collection/taxonomy often contains multiple blueprint types, and a generic "Create Entry" / "Create Term" label is less clear than context-specific labels (e.g., "Create News Release Post", "Create Video Post", etc.).Problem
Requested Enhancement
Update
createLabel()in both classes to support a blueprint-aware lookup before existing fallbacks:Proposed implementation for both methods
Statamic\Entries\Collection::createLabel()Statamic\Taxonomies\Taxonomy::createLabel()This approach keeps existing behavior, adds blueprint-specific support, and handles array-only translation maps without warnings or invalid return types.
Proposed Translation Key Pattern
Collection
statamic::messages.{collection}_collection_create_entrystatamic::messages.{collection}_collection_create_entry.{blueprint}Taxonomy
statamic::messages.{taxonomy}_taxonomy_create_termstatamic::messages.{taxonomy}_taxonomy_create_term.{blueprint}Example
For
postcollection withnews_releaseblueprint:statamic::messages.post_collection_create_entry.news_release = "Create News Release Post"statamic::messages.post_collection_create_entry = "Create Post""Create Entry"For
post_tagtaxonomy withclinicalblueprint:statamic::messages.post_tag_taxonomy_create_term.clinical = "Create Clinical Tag"statamic::messages.post_tag_taxonomy_create_term = "Create Tag""Create Term"Concrete language file examples
These are practical examples of how projects currently configure labels for different scenarios.
Scenario A: Collection-level override only
lang/vendor/statamic/en/messages.phpScenario B: Collection + blueprint-specific overrides
lang/vendor/statamic/en/messages.phpScenario C: Collection with no collection-level fallback (array-only blueprint labels)
lang/vendor/statamic/en/messages.phpExpected behavior:
blueprint=news_release=>Create News Release Postblueprint=video=>Create Video Postblueprint=post(missing key) => generic fallbackCreate Entryblueprintquery param => generic fallbackCreate EntryScenario D: Taxonomy-level override only
lang/vendor/statamic/en/messages.phpScenario E: Taxonomy + blueprint-specific overrides
lang/vendor/statamic/en/messages.phpScenario F: Taxonomy with no taxonomy-level fallback (array-only blueprint labels)
lang/vendor/statamic/en/messages.phpExpected behavior:
blueprint=clinical=>Create Clinical Tagblueprint=research=>Create Research Tagblueprint=general(missing key) => generic fallbackCreate Termblueprintquery param => generic fallbackCreate TermExpected resolution behavior across scenarios
{base}.{blueprint}exists, return that.{base}exists, return that.Create Entry/Create Term).{base}value), missing or absent blueprint should also fall back to the generic label.Benefits