Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Translate programmatically with Drupal 8

Drupal 8, natively multilingual, offers a GUI to be able to translate both the site configuration (field's label, view's title, etc.) and the contents themselves. But we sometimes need to translate programmatically contents  or configurations, particularly in the context of a website factory to generate such a multilingual site.

Discover some examples to help us translate on the fly both configurations and contents. The examples below assume that we have an original content in French and that we wish to associate their English translation.

We will use, in the snippets below, the loadByProperties() method to load an entity based on one of its properties, but we might as well load it from its identifier (if known) with the load() method. Each context has an appropriate solution.

Translate programmatically a node

// 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();
  }
}

Translate programmatically a menu link

// 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();
  }
}

Translate programmatically a block content

// 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();
}

Translate programmatically a taxonomy term

// 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();
  }
}

Translate configuration

To translate the configuration of a Drupal 8 website, we can provide configuration translated using configuration files .yml. We must place these configuration files in the config / install / language / en to import the English translation. For example, to import the translation of the content type Event created, we can place the node.type.event.yml file in that folder to automatically import the translation of the name and description of the content type.

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

But we may also need to translate dynamically, if we do not know the different configurations installed in advance. Then we will resort to the method getLanguageConfigOverride() from the languageManager service. Below are two examples using this method.

Translate programmatically a block configuration

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

Translate programmatically a system configuration

// 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();

These few snippets should allow us to translate programmatically most content entity type or configurations. Going further on translation and multilingual capabilities of Drupal 8, you can check out this excellent presentation Drupal 8's multilingual APIs -- integrate with all the things, which summarizes all the key concepts to implement multilingual Drupal 8 website.

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web