Multilingual sites are more and more common nowadays, at least a requirement in most of the projects we build. That’s why I wanted to create a list of tips for developing a multilingual Drupal 8 site. All the tips are about translations, and yes, this post is going to the technical bits.
Hide untranslated nodes from the menu
When multilingual sites are concerned, we often come across a solution where the main language has the most content and translations cover only certain amount of it. Sometimes the structure might vary too. This makes maintaining the translations and language versions trickier, as everything isn’t exactly the same between the languages.
One solution with Drupal 8 is to create separate menus for all the languages but then you can’t use the node translation - menu parent is a shared field. This means that if you change the menu path in English, all the other nodes get the same change. This approach would also make the ‘Language switcher’ feature – which allows easy switching between the active content (eg. switch between ‘About us’ pages in different languages) – unusable.
Another option would be to use “Content Language Access”. It’s one of the proposed solutions at the moment but I see it having a drawback too: while untranslated menus are not shown to anonymous users, they are still shown when logged in as an editor. You can just imagine the mess this creates for content editors. In worst cases, if there’s no room for links, the whole site could break.
We used it during most of the development period of one project, but then months later I did another research round and found a sandbox module that worked exactly the way we needed. No more untranslated menu items - logged in or not. The module was just recently promoted to full project and it’s called “Menu block current language”. Remember that you still need to replace the core menu blocks with ones that the module offers and there might be minor html changes - block id and class - so you also might need to adjust your css a little bit.
Fixing core bug: translations of field labels are reset to default language
You might have noticed that when you translate field labels, they lose translation after cache rebuild. Also the labels don’t change before the original label translation is re-saved. Translations are still there in the database but the site is displaying original language. Obviously this can be confusing, and take some serious debugging time.
This screenshot is part of a taxonomy term:
We use these field labels in the site footer:
Good news is that it’s actually a core bug which has a solution. You can read more about it from here https://www.drupal.org/node/2650434. For Drupal 8.3.x we’re using https://www.drupal.org/files/issues/2650434-89.patch.
Manage the UI translations yourself
I would recommend this because it’s pretty complicated. You translate your:
- forms from admin/structure/webform/manage/FORM-NAME/translate,
- views from admin/structure/views/view/YOUR-VIEW-NAME/translate,
- taxonomy label from admin/structure/taxonomy/manage/TAX-NAME/overview/fields/FIELD/translate/et/edit
- general translations from admin/config/regional/translate
- and last but not least, your custom code directly from Drupal source.
And this is actually a bigger list if you include all the possible UI strings.
Easy to miss: Drupal can export configuration in wrong langcode
Drupal 8 can now export its configuration to YAML files. That’s awesome! Still one tip: on the second line in these files you can find a variable called langcode. In theory, it should always have the same value in all the configuration files, but in reality Drupal likes to set it based on which language the site had when it was first configured in the admin environment. Although it should be agreed to always configure the site in source language, it’s easy to miss from time to time. To be sure, you should occasionally check the YAML files and always review commits. If you find any mistakes, change them directly from YAML file and re-import the configuration. As a side note – we always use English as the default language (admin/config/regional/language) so then it’s good to check that the langcode variable is “en”.
Translations are a tricky thing, and I haven’t come across a perfect solution yet. However Drupal is doing well with this, considering that Drupal 8 is still quite a new player. Contrib land (read custom modules) is evolving, and core is getting better and better! So all in all I recommend:
- try out “Menu block current language” module
- apply the field label patch to core
- manage the UI translations yourself
- beware of the configuration export
Hopefully you found the tips useful! If you have any comments or other tips, I’m very interested in hearing those. Just send me an email.