Skip to content

43 · "Featured recipe", "View recipe", "Recipe" and "Directions" stay English on a translated site

Project Dashi (theme dashi_theme)
Component Code
Category Bug report
Priority Normal
Status Reported upstream as #1

Problem/Motivation

Four texts of the Dashi theme cannot be translated. On a German site with the complete German translation of Dashi, they stay English:

Text Where Template
Featured recipe Label above the featured recipe on the front page components/featured-recipe/featured-recipe.twig
View recipe Button of the featured recipe and of the recipe cards featured-recipe.twig, components/card/card.twig
Recipe Label of the recipe cards components/card/card.twig
Directions Heading of the directions on every recipe page components/directions/directions.twig

The templates translate them with t(), e.g. {{ 'Featured recipe'|t }} and heading_text|default('Directions'|t). But the same strings are also configuration of Canvas:

  • "Featured recipe" and "Directions" are labels of the Canvas components (canvas.component.sdc.dashi_theme.featured-recipe, ….directions). Drupal CMS keeps configuration in the site language (Config Language Lock), so the English labels are stored as German configuration. As soon as Canvas saves a component again after the installation, locale takes the English label as a changed translation and stores "Featured recipe" as the customized German translation of "Featured recipe" (LocaleConfigSubscriber::saveCustomizedTranslation(); during the installation it skips this). Customized translations are never overwritten by imports, so the German translation of the theme text is lost.
  • "View recipe" and "Recipe" are default values of the card component's props, which are part of its versioned settings. Translating these strings changes the components' versions (report 02): after an installation where t('View recipe') returned German, every page failed with OutOfRangeException: The requested version … is not available (VersionedConfigEntityBase::assertVersionExists()).

So the interface texts of the theme share their source strings with configuration that must stay as it is.

Steps to reproduce

  1. Install Drupal CMS 2.2.1 with Dashi in German, with a German translation of the Dashi strings (e.g. dcle and the German installer dcgi).
  2. Clear the caches once (drush cr).
  3. The front page shows "Featured recipe", "View recipe" and "Recipe", every recipe page the heading "Directions". Interface translation shows "Featured recipe" and "Directions" with themselves as customized translation.

Proposed resolution

Give the interface texts of the theme a translation context, so they are separate from the configuration strings, e.g.

{{ 'Featured recipe'|t({}, {'context': 'Dashi'}) }}
{% set link_text = link_text|default('View recipe'|t({}, {'context': 'Dashi'})) %}
{{ heading_text|default('Directions'|t({}, {'context': 'Dashi'})) }}

Alternatively, set the texts explicitly as inputs in the content templates instead of relying on the defaults.

Additional information

Found with Dashi 1.x (theme 1.0.0), Canvas 1.12.0, Config Language Lock 1.0.2, Drupal core 11.4.8 and Drupal CMS 2.2.1 (October 2026). All other texts of Dashi can be translated; dcle ships a German translation of the content and configuration.

Copy to drupal.org

Issue title:

"Featured recipe", "View recipe", "Recipe" and "Directions" stay English on a translated site

Issue summary (paste it into the "Issue summary" field; project, component, category and priority are in the table above):

<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>Four texts of the Dashi theme cannot be translated. On a German site with the complete German translation of Dashi, they stay English:</p>
<table>
<thead>
<tr>
<th>Text</th>
<th>Where</th>
<th>Template</th>
</tr>
</thead>
<tbody>
<tr>
<td>Featured recipe</td>
<td>Label above the featured recipe on the front page</td>
<td><code>components/featured-recipe/featured-recipe.twig</code></td>
</tr>
<tr>
<td>View recipe</td>
<td>Button of the featured recipe and of the recipe cards</td>
<td><code>featured-recipe.twig</code>, <code>components/card/card.twig</code></td>
</tr>
<tr>
<td>Recipe</td>
<td>Label of the recipe cards</td>
<td><code>components/card/card.twig</code></td>
</tr>
<tr>
<td>Directions</td>
<td>Heading of the directions on every recipe page</td>
<td><code>components/directions/directions.twig</code></td>
</tr>
</tbody>
</table>
<p>The templates translate them with <code>t()</code>, e.g. <code>{{ 'Featured recipe'|t }}</code> and <code>heading_text|default('Directions'|t)</code>. But the same strings are also configuration of Canvas:</p>
<ul>
<li>"Featured recipe" and "Directions" are labels of the Canvas components (<code>canvas.component.sdc.dashi_theme.featured-recipe</code>, <code>….directions</code>). Drupal CMS keeps configuration in the site language (Config Language Lock), so the English labels are stored as German configuration. As soon as Canvas saves a component again after the installation, locale takes the English label as a changed translation and stores "Featured recipe" as the customized German translation of "Featured recipe" (<code>LocaleConfigSubscriber::saveCustomizedTranslation()</code>; during the installation it skips this). Customized translations are never overwritten by imports, so the German translation of the theme text is lost.</li>
<li>"View recipe" and "Recipe" are default values of the card component's props, which are part of its versioned settings. Translating these strings changes the components' versions (<a href="https://project.pages.drupalcode.org/dcle/issues/02-canvas-translation-changes-component-version/">report 02</a>): after an installation where <code>t('View recipe')</code> returned German, every page failed with <code>OutOfRangeException: The requested version … is not available</code> (<code>VersionedConfigEntityBase::assertVersionExists()</code>).</li>
</ul>
<p>So the interface texts of the theme share their source strings with configuration that must stay as it is.</p>
<h3 id="summary-steps-reproduce">Steps to reproduce</h3>
<ol>
<li>Install Drupal CMS 2.2.1 with Dashi in German, with a German translation of the Dashi strings (e.g. <a href="https://www.drupal.org/project/dcle">dcle</a> and the German installer <a href="https://www.drupal.org/project/dcgi">dcgi</a>).</li>
<li>Clear the caches once (<code>drush cr</code>).</li>
<li>The front page shows "Featured recipe", "View recipe" and "Recipe", every recipe page the heading "Directions". Interface translation shows "Featured recipe" and "Directions" with themselves as customized translation.</li>
</ol>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>Give the interface texts of the theme a translation context, so they are separate from the configuration strings, e.g.</p>
<code>{{ 'Featured recipe'|t({}, {'context': 'Dashi'}) }}
{% set link_text = link_text|default('View recipe'|t({}, {'context': 'Dashi'})) %}
{{ heading_text|default('Directions'|t({}, {'context': 'Dashi'})) }}</code>
<p>Alternatively, set the texts explicitly as inputs in the content templates instead of relying on the defaults.</p>
<h3>Additional information</h3>
<p>Found with Dashi 1.x (theme 1.0.0), Canvas 1.12.0, Config Language Lock 1.0.2, Drupal core 11.4.8 and Drupal CMS 2.2.1 (October 2026). All other texts of Dashi can be translated; dcle ships a German translation of the content and configuration.</p>