Change record status: 
Project: 
Introduced in branch: 
7.x
Introduced in version: 
7.15
Description: 

A generic way to access the entity language (if available) has been introduced: now it is possible to use the entity_language() function to retrieve an entity's language, if the entity type defines it. This value may be changed when editing the entity and represents the language its textual components are supposed to have.

This is a fully backward-compatible API change; nonetheless, module maintainers/contributors are encouraged to update their code as soon as possible, in order to take advantage of the new capabilities that entity_language() provides to entities in multilingual environments. Adjusting the code should be as simple as replacing every occurrence of

$node->language;

with

entity_language('node', $node);

where node can be any entity type, of course. Special attention should be given to field_attach_form():

field_attach_form('node', $node, $form, $form_state, $node->language);

should become

field_attach_form('node', $node, $form, $form_state, entity_language('node', $node));

The new API function mirrors the entity_label() function and relies on two ways to define the entity language, both based on the implementation of hook_entity_info():

  • Through a 'language' entity key defining the name of the entity property to be inspected to get the entity language.
  • Through the implementation of a 'language callback' returning the language code matching the entity language. Quoting from the API documentation:

    The language callback is meant to be used primarily for temporary alterations of the property value: entity-defining modules are encouraged to always define a language property, instead of using the callback as main entity language source. In fact not having a language property defined is likely to prevent an entity from being queried by language. Moreover, given that entity_language() is not necessarily used everywhere it would be appropriate, modules implementing the language callback should be aware that this might not be always called.

    The main reason behind the introduction of the language callback was supporting the ability of displaying a multilingual entity form (see #1282018: Improve UX of language-aware entity forms for an example). In most situations defining an entity language property should be enough to ensure an entity is properly handled in multilingual environments.

The value returned when an entity type has no entity language info is NULL to preserve backward compatibility. In fact LANGUAGE_NONE is an assignable value and we need a way to differentiate between the case where an entity has LANGUAGE_NONE assigned and the one where it has no language support at all. See #1495648-12: Introduce entity language support for details.

The entity_language() function has been introduced with two main use cases in mind:

  • Before introducing it there was no consistent default value to pass to the field_attach_form() function, which in turn lead to code breaking field language support, see for instance #1534674: Comment field language is completely broken. The value returned by entity_language() is now the recommended value to be passed as $langcode parameter of the field_attach_form() function, when the logic being implemented does not explicitly dictate a different one.
  • As a foundational function to provide better API tools and #1260640: Improve field language API DX.

As a beneficial side-effect it is now possible to have language-aware taxonomy term aliases if a module implements language support for the taxonomy term entity type.

Since the entity_language() function is not available on drupal core before 7.15, the implementing modules will need to:

  • either set a dependency on core 7.15 through the folllowing line in the .info file:
    dependencies[] = system (>7.14)
    
  • or introduce a wrapper function checking for the existence of the new function and provide a sensible fallback for the logic implemented by the module, for instance:
    /**
    * Returns the language code of the given entity.
    *
    * Backward compatibility layer to ensure that installations running an older
    * version of core where entity_language() is not available do not break.
    *
    * @param string $entity_type
    *   An entity type.
    * @param object $entity
    *   An entity object.
    */
    function mymodule_entity_language($entity_type, $entity) {
      $langcode = NULL;
      if (function_exists('entity_language')) {
        $langcode = entity_language($entity_type, $entity);
      }
      elseif (!empty($entity->language)) {
        $langcode = $entity->language;
      }
      return $langcode;
    }
    
Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Module developer documentation done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done
Details: 

Updated the Language support for entity fields documentation page and the field_attach_form() API documentation with references to this change record and the related API documentation.