1

I have Drupal 9.4.5 site. I've been hunting a problem where translations in the wrong language show up for guest users, after each release.

  • Default language: English
  • Interface Language Detection: Only method "Selected language" (Language based on a selected language) is checked with value: German

The intention is that this site uses only German as language. We use English as default language, a) because that seems to work better for Drupal and b) because we have some English-speaking developers on the team. Everything gets translated to German. This only concerns texts translated via t() in the templates.

The problem: After a new release is deployed to the platform.sh installation, some blocks show English translations. This only happens for guest users, everything is correctly translated for logged-in users. So it's not a problem of a missing translation. Mainly it happens with a combination of blocks and views. One is a block generated by a view, the other custom block uses a view internally.

Remedy so far: The English texts go away on cache clear. I'm not sure why this helps, as the last step of installing the release is already a "drush cr".

So far, I haven't been able to reproduce it locally and I'm not aware of the probem showing up without a release happening first. I tried to disable the platform.sh cache for a specific route, but after the next release this route showed English texts again.

So this seems to be a cache issue in some way. I'm looking for an idea why Drupal would ever render an English text on a German page in the first place!? There is no language switch available and no language part of the URL. Any idea is welcome.

Update 29.09.: By now I have added debug output to the template and I really think this is a problem of Drupal outputting English translations when it should output the German text.

My current test case:

  • A block bundle using an entity reference field to allow the user to pick entities to be displayed.
  • The block's display settings is set to "referenced entity" with the display mode "teaser".
  • There is no class for the block.
  • There is a template in the theme for the entities being displayed. It contains this code:
    {% trans %}
      {{ comment_count }} comment
    {% plural comment_count %}
      {{ comment_count }} comments
    {% endtrans %}

In the preprocess function for the entity, I added this:

  $variables['current_language_content'] = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
  $variables['current_language_interface'] = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_INTERFACE)->getId();

And this in the template, directly beneath the comment count output:

<!-- current language content: {{ current_language_content }}, current language interface: {{ current_language_interface }} -->
<!-- just as is: {{ "Join now!"|t }} -->
<!-- explicitly de: {{ "Join now!"|t({'langcode': 'de'}) }} -->

Now I have a page with four German teasers and one English teaser, and all of them show this in the source code: <!-- current language content: de, current language interface: de -->

The two extra translated Strings show the correct German translation for the first four teasers and then for the fifth:

<!-- current language content: de, current language interface: de -->
<!-- just as is: Join now! -->
<!-- explicitly de: Join now! -->

This test String is shown to be correctly translated in the UI interface and is not part of any config file.

There might be caching issues involved, but this seems to be broken on a level beneath the cache. Also, we had one instance yesterday were it needed multiple cache clears and some hours before the texts turned German again.

Sooo... Is there any other language setting that I can check? Are there known bugs of the translation method?

4
  • "I'm looking for an idea why Drupal would ever render an English text on a German page in the first place!?" If English is the default language, Drupal isn't "rendering English on a German page", it's "rendering the default language because it didn't get the set language for some reason." Commented Sep 6, 2022 at 9:58
  • Although this won't solve the problem, one workaround is to run a script after the build that rebuilds the cache again and then parses your sitemap and visits all the URLs (which also has the benefit of priming the cache). You could also have it check for known English strings that might appear to ensure the pages are displaying properly. Commented Sep 6, 2022 at 9:59
  • 1
    I am not so sure if the current language is set as cache context by default in Drupal. Especially when these are custom blocks - maybe you need to set the cache context "language" in your code? It sounds as if your developers may render the page with the block first and then the English rendered block is used again in the German version of your project because drupal does not realize that the block needs another version in German? Commented Sep 7, 2022 at 14:12
  • Thanks for the replies. I just added some more findings from my recent debugging attempts. To me it seems the language is correctly set for the translations, and this happens even if I explicitly tell the t() function to use German. So -- any other ideas what I could try? Commented Sep 29, 2022 at 9:42

1 Answer 1

0

So this seems to be a cache issue in some way.

That is the most likely reason. The internal page cache module, which is enabled by default, caches pages for anonymous users.

Blocks are modular components of your pages. They can be reused on multiple pages/across multiple language versions of your site. Implementing the CachableDependencyInterface, they are having their own render cache configuration. After clearing the render caches, the first occurrence of a block that meets the caching configuration will be cached and reused for each subsequent page that meets the same cache configuration.

Assuming that:

  • the current URL/language aren't part of the block cache context,
  • the sites' releasing process clears the render caches,
  • the sites' releasing process or your releasing developer afterwards opens a page of your site in English that contains such a block,

the English version of the block will get cached and reused for any later occurrence of the same block on other pages, even though subsequently visited pages may be in German or are having a different URL. - You'll see exactly your described results. (If you clear your caches and visit the site in its German version, the block will be cached in German, and the English version of the pages will show a German block for guest visitors.)

To overcome this issue, you may want to either disable caching for those blocks alltogether (recommended only for highly dynamic block content), or - the more reasonable approach - add correct cache contexts/tags.

E.g., by adding the 'url' or 'route' cache context, different versions of the same block instance will be cached for each different URL/route visited. Using the 'languages:language_content' cache context, a different version for each visit using a different content translation language will be cached.

If the blocks have been provided by Drupal core/contributed modules, you may wish to ask the maintainers of those modules to add correct caching contexts.

If those blocks have been provided by a custom module, use the following examples to extend your block classes:

(1) Override getCacheMaxAge() to disable caching of a block by setting its maximum caching time to 0 :

use Drupal\Core\Block\BlockBase;

class MyCustomBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    return 0;
  }

}

(2) Override getCacheContexts() to add custom cache contexts:

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;

class MyCustomBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts() {
    return Cache::mergeContexts(parent::getCacheContexts(), [
      // Your applicable cache tags.
      'url',
      'languages:language_content',
    ]);
  }

}
1
  • Thanks for your reply and outlining the basics cache contexts. I just updated my post with more information and I really don't think this is just an issue of Drupal legitimatly rendering something in English and then by mistake caching it for German pages. On a test page I get four times the German text and one time the English, even if I provide the current language as a parameter for the t function. Commented Sep 29, 2022 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.