logo

Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll
18/06/2025, by Ivan

En Drupal 8, el idioma de los campos ya no se proporciona en la API pública, en su lugar los campos se adjuntan a objetos con soporte de idioma, de los cuales "heredan" su idioma.

Las principales ventajas aquí son:

  • No necesitamos preocuparnos por la portabilidad de los campos, ya que esta la gestiona el objeto entidad internamente.
      // Determinar de alguna forma el $active_langcode.
      $translation = $entity->getTranslation($active_langcode);
      $value = $translation->field_foo->value;
  • Ya no es necesario pasar el idioma activo, de hecho podemos simplemente pasar el objeto de traducción que implementa EntityInterface y es esencialmente un clon del objeto original, solo con un idioma interno diferente. Esto significa que en muchos casos el código recibido puede no conocer el idioma (por supuesto, a menos que explícitamente trate con el idioma).
      // Instanciar el objeto de traducción adecuado solo una vez y pasarlo
      // donde sea necesario. Esto es típicamente manejado por subsistemas del core
      // y en muchos casos comunes no se requiere recuperar explícitamente
      // el objeto de traducción.
      $langcode = Drupal::languageManager()->getLanguage(Language::TYPE_CONTENT);
      $translation = $entity->getTranslation($langcode);
      entity_do_stuff($translation);

      function entity_do_stuff(EntityInterface $entity) {
        $value = $entity->field_foo->value;
        // hacer cosas
      }
  • Ahora tenemos una API reutilizable para la negociación del idioma de la entidad, que se puede usar para determinar la traducción de la entidad que mejor se adapta a un contexto determinado:
      // Código simplificado para generar un array renderizable para una entidad.
      function viewEntity(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
        // El método EntityManagerInterface::getTranslationFromContext()
        // aplicará la lógica de negociación de idioma de la entidad a todo el objeto
        // y devolverá el objeto de traducción apropiado para el contexto dado.
        // El parámetro $langcode es opcional e indica el idioma del contexto actual.
        // Si no se especifica, se usa el idioma de contenido actual,
        // que es el comportamiento deseado durante la fase de renderizado.
        // Tenga en cuenta que los valores de los campos no se modifican,
        // así que los valores vacíos simplemente no se mostrarán.
        $langcode = NULL;
        $translation = $this->entityManager->getTranslationFromContext($entity, $langcode);
        $build = entity_do_stuff($translation, 'full');
        return $build;
      }

También podemos especificar un parámetro opcional $context, que puede usarse para describir el contexto en el que se usará el objeto de traducción:

      // Código simplificado para la generación de reemplazos de tokens.
      function node_tokens($type, $tokens, array $data = array(), array $options = array()) {
        $replacements = array();

        // Si no se especifica idioma para este contexto, simplemente usamos
        // el idioma predeterminado de la entidad.
        if (!isset($options['langcode'])) {
          $langcode = Language::LANGCODE_DEFAULT;
        }

        // Pasamos un parámetro $context que describe la operación que se realiza.
        // La operación predeterminada es 'entity_view'.
        $context = array('operation' => 'node_tokens');
        $translation = \Drupal::service('entity.repository')->getTranslationFromContext($data['node'], $langcode, $context);
        $items = $translation->get('body');

        // hacer cosas

        return $replacements;
      }

La lógica usada para determinar el objeto de traducción devuelto puede ser modificada por módulos. Véase LanguageManager::getFallbackCandidates() para más detalles.

Los datos reales de los campos se distribuyen entre todos los objetos de traducción, y modificar el valor de un campo no traducible lo cambia automáticamente para todos los objetos de traducción.

  $entity->langcode->value = 'en';
  $translation = $entity->getTranslation('it');
  
  $en_value = $entity->field_foo->value; // $en_value es 'bar'
  $it_value = $translation->field_foo->value; // $it_value es 'bella'

  $entity->field_untranslatable->value = 'baz';
  $translation->field_untranslatable->value = 'zio';
  $value = $entity->field_untranslatable->value; // $value es 'zio'

En cualquier momento se puede crear una instancia de un objeto de traducción desde el objeto original o desde otro objeto de traducción mediante el método EntityInterface::getTranslation(). Si se necesita explícitamente el idioma activo, se puede obtener con EntityInterface::language(). La entidad original puede obtenerse con EntityInterface::getUntranslated().

  $entity->langcode->value = 'en';

  $translation = $entity->getTranslation('it');
  $langcode = $translation->language()->id; // $langcode es 'it';

  $untranslated_entity = $translation->getUntranslated();
  $langcode = $untranslated_entity->language()->id; // $langcode es 'en';

  $identical = $entity === $untranslated_entity; // $identical es TRUE

  $entity_langcode = $translation->getUntranslated()->language()->id; // $entity_langcode es 'en'

EntityInterface ahora tiene varios métodos que facilitan trabajar con traducciones de entidades. Si un fragmento de código debe actuar sobre cada traducción disponible, puede usar EntityInterface::getTranslationLanguages():

  foreach ($entity->getTranslationLanguages() as $langcode => $language) {
    $translation = $entity->getTranslation($langcode);
    entity_do_stuff($translation);
  }

También existen formas de agregar una traducción, eliminarla o comprobar si existe:

  if (!$entity->hasTranslation('fr')) {
    $translation = $entity->addTranslation('fr', array('field_foo' => 'bag'));
  }

  // Esto es equivalente al siguiente código, aunque si se especifica un código
  // de idioma inválido se lanzará una excepción.
  $translation = $entity->getTranslation('fr');
  $translation->field_foo->value = 'bag';

  // Acceder a un campo en un objeto de traducción eliminado provoca una excepción.
  $translation = $entity->getTranslation('it');
  $entity->removeTranslation('it');
  $value = $translation->field_foo->value; // lanza InvalidArgumentException

Cuando se añaden o eliminan traducciones de entidad al almacenamiento, se disparan respectivamente los siguientes hooks:

  • hook_entity_translation_insert()
  • hook_entity_translation_delete()

El idioma del campo aún puede obtenerse llamando al método correspondiente del propio objeto campo:

  $langcode = $translation->field_foo->getLangcode();

 

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.