I recently worked with translating a site and deploying the translations, and was finding that translating block titles and field names ("configuration") required too many manual steps, as opposed to interface translation, which automatically registers all t()-wrapped (PHP) or |trans-ending (Twig) strings, and can become part of deploy process, all contained in a single po-file.
So I checked out the options, and initially planned to use https://www.drupal.org/project/config_translation_po/. But it still wasn't great to add another slightly working step. So I instead experimented with adding |trans in the relevant Twig templates.
This turned out to work really well, and 99% percent of all translations are in a single .po file, one for each language. Only Site slogan, and some meta tags are still in language specific configuration files.
Translation Bliss
For a complete solution, check out the Translation Bliss contrib module, which solves the challenge of translating everything in Drupal very elegantly. The minimum of relevant strings are made available in a file for immediate translation and import, and all strings are made User Interface translatable, also otherwise "difficult" configuration elements such as these:
- A Metatag description
- A custom Views Block title
- The Site name
Problem/Motivation
Currently, translating Drupal is a combination of Interface Translation and Configuration Translation which is confusing.
- Interface Translation
Translate strings marked up witht(), i.e.$this->t('Reset your password'). - Configuration Translation
Translate strings in Views block titles, custom menu titles, etc.
The challenge is that some strings, such as Views block titles and custom menu titles are considered configuration elements, and not translatable via Interface Translation.
Steps to reproduce
Create multilingual Drupal site, and find the translation process difficult.
Proposed resolution
Ideally, all text strings should be translatable via a single method Interface Translation, and not using two different methods.
We could do this by making Views block titles and custom menu titles translatable, for example by adding |trans in the template files, or maybe some other way.
The MR shows an example, where Views block titles and custom menu items are made translatable in Olivero:
- Install Drupal 11 with Olivero as theme
- Install Language modules:
drush in language content_translation locale - Allow relevant elements to be translatable, and translate a standard block and menu item ("Log in")
- Create a Views block with a displayed title, and a custom menu item
- See that they are not translatable under "User interface translation" (
/admin/config/regional/translate) - Apply the MR
- See that they are now picked up, and available under "User interface translation"
Workaround
Until or of this happens, here are the steps to do it:
Alternative solution: Make configuration elements translatable
Some strings, such as Views block titles and custom menu titles are considered configuration elements, and are not translatable via Interface Translation.
As an alternative to dealing with their translations through configuration, you can instead make the relevant strings translatable, by adding the Twig
|transfunction to labels and titles in Twig templates files.For example, to make Views generated block titles and menu titles translatable, copy the template files to your custom theme (see below), and override the original mark up. Use Twig debug to check for the right file, and possible file names in the source.
There are two great benefits:
- Configuration translation can be replaced with interface translation
- All translations can be deployed from a
.pofile, using the method in How-to deploy Drupal interface translations.Views block labels and menu titles will now automatically pick up any translations. Olivero theme files are used for examples.
Views block titles via
web/core/themes/olivero/templates/block/block.html.twig, line 47:<h2{{ title_attributes.addClass('block__title') }}>{{ label|render|striptags|trans }}</h2>Custom menu titles via
/core/themes/olivero/templates/navigation/menu--primary-menu.html.twigline 87:<span class="primary-nav__menu-link-inner primary-nav__menu-link-inner--level-{{ menu_level + 1 }}">{{ item.title|trans }}</span>
From Translating configuration > Alternative solution: Make configuration elements translatable
https://www.drupal.org/docs/administering-a-drupal-site/multilingual-gui...
Contrib modules like Field Group and Facets
Also contrib modules such as Field Group and Facets could be made more easily translatable, here are some examples:
Field Group
Field group labels, via field_group/templates/field-group-html-element.html.twig:
<{{ title_element }}{{ title_attributes }}>{{ title|render|striptags|trans }}</{{ title_element }}>
See also #3114825: Document how to translate field group labels and descriptions.
Facets
Facets items, via facets/templates/facets-result-item.html.twig:
<span class="facet-item__value">{{ value|trans }}</span>
Facets Summary items, via facets/modules/facets_summary/templates/facets-summary-facet.html.twig:
{{ label|trans }}: {{ items|map(items => items|trans)|join(', ') }}
Views Flipped Table
Views Flipped Table headers via views-view-flipped-table.html.twig:
{{- header_column.content|trans }}{{ header_column.sort_indicator }}
Remaining tasks
User interface changes
API changes
Data model changes
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-3549927
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 #2
ressaComment #3
ressaUpdate "Alternative solution: Make configuration elements translatable" after clarifying which elements are considered configuration.
Comment #4
ressaRemove Field labels in edit form via
form-element-label.html.twigsince that seems to work fine. Update to use Oliver template files as examples.Comment #6
ressaRemove mention of field names, add steps to reproduce.
Comment #7
ressaUpdate title, update example to
$this->t('Reset your password').Comment #8
ressaComment #9
ressaAdd Contrib module Field Group labels example from #3114825-30: Document how to translate field group labels and descriptions.
Comment #10
ressaMove Facets and Field Group contrib modules examples to their own section.
Comment #11
geek-merlin@ressa: Your train of thought in the IS was exactly mine.
And i guess you also experienced that Drupal gatekeepers have their beliefs, und usually are extremely conservative on that.
Whether this is good for diversity and the future of Drupal is a discussion beyond this one.
That said, i had the same vision and now there is a module for that: https://www.drupal.org/project/translation_bliss
I'd love to have you and your agency in the club of pioneers. Feel free to PM me.
Comment #12
geek-merlinComment #13
ressaThanks for the encouraging words @geek-merlin. It means a lot to me, to get my thoughts confirmed by an experienced Drupal developer, since I am more of a Drupal Site Builder. And thanks for working on great modules that I use and love, like Entity Prepopulate, Asset Injector, etc.
I do understand how some changes can take time (for different reasons) but this issue is only a few weeks old, so let's see :)
Your idea looks very interesting, and I'll surely check it out, and contact you for further discussion.
PS. Adding intro text and Views Flipped Table example.
Comment #14
ressaFixing line breaks.
Comment #15
ressaAdd Translation Bliss in the Issue Summary and fix title.
Comment #17
ressaUpdate to use
label|render|striptags|transfor block labels, see https://gist.github.com/raphaellarrinaga/c1d71f69873c967ff74f8ec09cbdf9e... and #2728915-12: twig string filters dont work..