Traduire par le code avec Drupal 8

Des drapeaux symboliques suspendus sur une étagère de cuisine

Drupal 8, nativement multilingue, propose une interface graphique pour pouvoir traduire aussi bien la configuration du site (les labels des champs, les titres des vues, etc.) que les contenus eux-même. Mais nous pouvons parfois avoir besoin de traduire de façon programmatique des contenus ou encore des configurations, notamment dans le cadre d'une usine à sites pour générer par exemple un site multilingue.

Découvrons quelques exemples pour nous permettre de traduire à la volée aussi bien de la configuration que des contenus. Les exemples ci-dessous postulent que nous disposons d'un contenu original en français et que nous souhaitons leur associer une traduction anglaise.

Nous utiliserons, dans les snippets ci-dessous, la méthode loadByProperties() pour charger une entité en fonction d'une de ces propriétés, mais nous pourrions tout aussi bien la charger depuis son identifiant (s'il est connu) avec la méthode load(). A chaque contexte correspond une solution plus appropriée.

Traduire un contenu

// Translate a node.
$entitytype_manager = \Drupal::service('entity_type.manager');
$storageNode = $entitytype_manager->getStorage('node');
$random = new Random();

$titles = [
  'A propos' => 'About',
];

foreach ($titles as $title_fr => $title_en) {
  $node = $storageNode->loadByProperties(['title' => $title_fr]);
  $node = reset($node);
  if ($node && !$node->hasTranslation('en')) {
    $entity_array = $node->toArray();
    $translated_fields = [];
    $translated_fields['title'] = $title_en;
    $translated_fields['body'] = [
      'value' => '[EN] ' . $random->paragraphs(3),
      'format' => 'full_html'
    ];

    $translated_entity_array = array_merge($entity_array, $translated_fields);
    $node->addTranslation('en', $translated_entity_array)->save();
  }
}

Traduire un lien de menu

// Translate a Link.
$entitytype_manager = \Drupal::service('entity_type.manager');
$storageMenuLinkContent = $entitytype_manager->getStorage('menu_link_content');

$links_title = [
  'A propos' => 'About',
];

foreach ($links_title as $link_title_fr => $link_title_en) {
  $link = $storageMenuLinkContent->loadByProperties(['title' => $link_title_fr]);
  $link = reset($link);
  if ($link && !$link->hasTranslation('en')) {
    $link->addTranslation('en', ['title' => $link_title_en])->save();
  }
}

Traduire un bloc de contenu

// Translate a blockContent.
$entitytype_manager = \Drupal::service('entity_type.manager');
$storageBlockContent = $entitytype_manager->getStorage('block_content');

// Social block.
$social_block = $storageBlockContent->loadByProperties(['info' => 'Suivez nous']);
$social_block = reset($social_block);
if ($social_block && !$social_block->hasTranslation('en')) {
  $entity_array = $social_block->toArray();
  $translated_fields = [];
  $translated_fields['info'] = 'Follow us';
  $translated_entity_array = array_merge($entity_array, $translated_fields);
  $social_block->addTranslation('en', $translated_entity_array)->save();
}

Traduire un terme de taxonomy

// Translate a term.
$entitytype_manager = \Drupal::service('entity_type.manager');
$storageTerm = $entitytype_manager->getStorage('taxonomy_term');

$keywords = [
  'Recherche' => 'Search',
  'Enquête' => 'Survey',
  'Voiture' => 'Car',
];

foreach ($keywords as $keyword_fr => $keyword_en) {
  $term = $storageTerm->loadByProperties(['name' => $keyword_fr]);
  $term = reset($term);
  if ($term && !$term->hasTranslation('en')) {
    $entity_array = $term->toArray();
    $translated_fields = [];
    $translated_fields['name'] = $keyword_en;
    $translated_fields['description'] = [
      'value' => '[EN] ' . $random->paragraphs(3),
      'format' => 'full_html'
    ];
    $translated_fields['field_keyword_image'] = $entity_array['field_keyword_image'][0];
    $translated_fields['field_keyword_image']['alt'] = $keyword_en;
    $translated_entity_array = array_merge($entity_array, $translated_fields);
    $term->addTranslation('en', $translated_entity_array)->save();
  }
}

Traduire la configuration

Pour traduire la configuration d'un site Drupal 8, nous pouvons fournir la configuration traduite au moyen des fichiers .yml des configurations. Il faudra placer ces fichiers de configuration dans le répertoire config/install/language/en pour importer la traduction anglaise des configurations. Par exemple pour importer la traduction du type de contenu Event créé, nous pouvons placer le fichier node.type.event.yml dans ce dossier pour importer automatiquement la traduction du nom et de la description du type de contenu.

#File node.type.event.yml
name: Event
description: 'Permit to publish events.'

Mais nous pouvons aussi avoir besoin de traduire de façon dynamique, si nous ne connaissons pas les différentes configurations installées à l'avance. Nous aurons recours alors à la méthode getLanguageConfigOverride du service languageManager. Vous trouverez ci-après deux exemples d'utilisation de cette méthode.

Traduire une configuration de bloc

// Translate a block configuration.
$blockConfig = \Drupal::languageManager()->getLanguageConfigOverride('en', 'block.block.follow_us');
$blockConfig->set('settings', ['label' => 'Follow us'])->save();

Traduire une configuration système

// Translate a system configuration.
$site_name = \Drupal::config('system.site')->get('name');
$site_name = $site_name . ' [EN]';

$siteConfig = \Drupal::languageManager()->getLanguageConfigOverride('en', 'system.site');
$siteConfig->set('name', $site_name)
  ->set('slogan', 'The site slogan could be very long, be carreful')
  ->save();

Ces quelques snippets devraient nous permettre de traduire de façon programmatique les principaux types de contenu ou configurations. Pour aller plus loin sur la traduction et les capacités multilingues de Drupal 8, n'hésitez à consulter cette excellente présentation Drupal 8's multilingual APIs -- integrate with all the things. qui récapitule tous les fondements clés pour mettre en oeuvre le multilinguisme avec Drupal 8, ou encore à consulter un freelance expert Drupal 8.

Ajouter un commentaire