Problem/Motivation
Rich text content is not processed using the language context and so links (via linkit module) or embedded media are not the correct language.
Steps to reproduce
1. Have a multilingual site setup using content translation.
2. Create a config page, with a rich text field and language context enabled.
3. Add a block for the config page to a page.
3. Add values for the config page in both languages with a link to a node that's translated.
4. Visit the page in both languages - both will link to the default language version of the node, and when visiting in the non-default language will lead to a 404.
Proposed resolution
Not sure on a resolution, the processed text filters pass in the language of the field being rendered, which as config pages aren't translatable, this is set to und. The linkit and drupal media filters both use the language code passed in to load the right target entity.
Remaining tasks
Figure out a solution.
User interface changes
N/A
API changes
N/A
Data model changes
N/A?
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | config_pages-add_missing_translation_context-3500828.patch | 2.19 KB | yoerioptr |
Issue fork config_pages-3500828
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 #3
mjpa commentedI've created a MR with a potential fix that seems to work in our case. The preprocess field changes the
#langcodeproperty on the render arrays where it's set to the value from the language context of the config page that the field belongs to.With the MR applied, links to translated content now link to the language version that matches the language context from the config page, instead of the default language of the site.
Comment #4
yoerioptr commentedI've attached MR as a patch to this ticket.
Comment #6
shumer commentedAfter reviewing the original patch (MR !43) that uses hook_preprocess_field(), we decided to switch to a custom EntityViewBuilder for the following reasons:
Why the approach changed:
1. Render cache compatibility. hook_preprocess_field() runs after the render cache layer. This means on a cache hit the hook never fires, so #langcode isn't set until the cache is rebuilt. EntityViewBuilder::buildComponents() runs before caching, so
the langcode is baked into the cached render array.
2. Covers all rendering paths. Config page fields can be rendered in two ways:
- Entity-level: via EntityViewBuilder::view() → buildComponents() (e.g. block plugin, direct entity rendering).
- Field-level: via FieldItemList::view() → EntityViewBuilder::viewField() (e.g. ConfigPagesLoaderService::getFieldView(), Twig config_pages_field() function).
The preprocess hook only covers the first path. The custom ViewBuilder covers both by overriding buildComponents() and viewField().
3. Idiomatic Drupal pattern. Overriding the view builder is the standard way to customize entity rendering behavior, rather than relying on theme-layer hooks for logic that is entity-specific.
What was done:
Comment #8
shumer commented