I'm maintaining a multilingual website which uses a few custom Display Suite fields defined in a hook_ds_fields_info(). The titles of these fields are often displayed in the wrong language.

After I flush all caches, the field titles are correctly displayed in the current language but when I change the current language these field titles remain in the previous language.

This is caused by the fact that ds_get_fields() caches the field titles in the current language. This is because all hook_ds_fields_info() hooks use the t() function to translate the titles.

When I remove code line "cache_set('ds_fields', $fields_cached, 'cache');" from ds_get_fields(), the field titles are always displayed in the correct language.

The real fix would be to cache untranslated field titles and only translate them when they are displayed. See attached "ds_field_title_translate_on_display.patch".

The problem with this is that many developers may have been using the t() function in their hook_ds_fields_info() hook and applying this change might cause the already-translated title to be fed to the t() function. I also noticed that not only the field titles are translated in the hook_ds_fields_info() hooks; ds.ds_field_info.inc for example contains lines like "'author' => t('Author')," and "'author_linked' => t('Author linked to profile')".

Because of these potential problems it might be safer to simply cache the field information per language? See attached "ds_field_title_cache_each_language.patch".

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joericapens’s picture

By the way, the patch from http://drupal.org/node/1345278 included in 7.x-1.5 causes the title label to never be translated. That's why my "ds_field_title_cache_each_language.patch" adds a t() function.

swentel’s picture

Version: 7.x-1.5 » 7.x-2.x-dev

Need to review this soon

swentel’s picture

Status: Active » Needs work

Instead of caching this in the same cid, it's better to save them in different cid's, similar like entity info or node types does it (and fields as well iirc)

'entity_info:$langcode' or 'node_types:' . $GLOBALS['language']->language; (directly using the GLOBALS also saves us a line)

We'll have more cache entries, but they never become large, especially if you have a lot of languages enabled on the site.

+++ ds.module Locally Modified (Based On LOCAL)
@@ -739,7 +740,7 @@
+      $field['title'] = t($node_type->title_label);

I'm not sure about this one. Node types are cached per language as well, so if the node type is defined in hook_node_info, the label should be wrapped in a t() there, and if it's a custom one, _node_types_build() adds a translatable tag to the query.

Jax’s picture

Status: Needs work » Needs review
FileSize
798 bytes

Here's a patch that caches per language and which solves my issue. I'm not sure what the issue with the title label is so I left that one for a follow up patch. But isn't the title label translated by i18n? At least it is on the form.

I also use LANGUAGE_TYPE_CONTENT instead of LANGUAGE_TYPE_INTERFACE because modules like admin_language switch LANGUAGE_TYPE_INTERFACE to a chosen language and the content should work independently of that. For more discussion about this see #1531002: Use proper content/interface/context language everywhere..

bootstrap.inc:define('LANGUAGE_TYPE_CONTENT', 'language_content');
bootstrap.inc:define('LANGUAGE_TYPE_INTERFACE', 'language');
bootstrap.inc:define('LANGUAGE_TYPE_URL', 'language_url');
swentel’s picture

Status: Needs review » Fixed

Thanks, pushed to both branches!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

swentel’s picture

The use of LANGUAGE_TYPE_CONTENT introduced some annoying caching bugs sometimes, see #1822168: Display suite fields sometimes don't show up - some kind of caching problem occuring - going to revert to using $language->language which is something that entity_info also does.