What Developers Need to Know about Multilingual Drupal 7 Sites
When working with Drupal's language / locale components in code, we need to be aware of some issues to ensure that the multilingual subsystem works as we'd expect.
- Hard-coding a language (or assuming no language) is problematic
- Translatable title fields are actually different fields
Hard-coding a language (or assuming no language) is problematic
When working with fields, developers often set or get field data by explicitly providing the undefined language (the standard one set up if the language system isn't, "LANGUAGE_NONE" defined as "und"). This will cause code to fail whenever the Entity Translation module is enabled with actual languages. Wouldn't it be better to have Drupal automatically work with the current language?
Retrieving field values
The fieldgetitems() API call does this for you. If you don't specify a language, it will default to the current language if one isn't specified. So if you really do want to target a specific language, you can.
For example,
$value = $node->field_subtitle[LANGUAGE_NONE][0]['value'];
...should generally be replaced with...
$field_items = field_get_items('node', $node, 'field_subtitle');<br>$value = $field_items[0]['value'];
Setting field values
Unfortunately, there's no field_set_items() function in Drupal 7. We can, however, still specify the current language when setting field data if we're working with translatable fields.
Instead of
$node-&gt;body[LANGUAGE_NONE][0]['format'] = 'full_html';
...you'll probably want to use one of the global variables $language (for the interface language) or $language_content (for the content language) as in ...
$langcode_current = $GLOBALS['language']-&gt;language;<br>$node-&gt;body[$langcode_current][0]['format'] = 'full_html';
Alternatives
Assuming the current language, the Entity API module actually provides both setter and getter methods through its Entity metadata wrappers. However, it's another dependency and extra overhead that you may not want if you're not using it already. It also makes things trickier to debug. See What's best practice when working with the language[und]? for a discussion on this.
Translatable title fields are actually different fields
By default, field translation through the Entity Translation module doesn't allow title fields to be translatable. This is because title fields in Drupal 7 aren't implemented formally as fields using the Field API. To get around this limitation, it's necessary to replace titles with translatable fields using the Title module.
To enable this for specific fields, it's necessary to click on the "replace" button for a title field in the Manage Fields tab for the content type / bundle. This will switch basic use cases over to use the new "field_title" field instead of the default "title" field.
Be aware that you'll have to update any views and custom code to use the new field. If not done, titles will always be presented in the original language, and you'll wonder why translated titles aren't showing up.
If you don't really need translated titles, it's best to leave the original titles as-is. Otherwise, it gets complicated with multiple title fields.