4

My module creates and manages some config_entities programmatically (ie. not through an EntityForm) in response to associated content entities being saved.

In order to handle multi-language content entities, I see two options:

  • create one config entity and add translations for it
  • create a unique config entity for each translation

The first seems cleaner - however, I don't see how to actually transparently manage translations for config entities. Translating an entity with the config_translation module appears to create a new entry in the config table with collection = language.xx, but I don't see how to access a translated entity explicitly (rather than it being automatically mapped by the site's interface language). Is this even possible?

5

As far as I can see -- yes, this is possible but it's not as pretty as $contentEntity->getTranslation($langcode);. The full enchillada would be:

protected function getTranslatedConfigEntity(ConfigEntityInterface $configEntity, LanguageInterface $language) {
  $langcode = $language->id():
  /** @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $configEntityType */
  $configEntityType = $configEntity->getEntityType();
  $name = $configEntityType->getConfigPrefix() . '.' . $configEntity->id();
  $translatedConfig = $this->languageManager->getLanguageConfigOverride($langcode, $name);
  $translatedConfig[$configEntity->getKeys('langcode')] = $langcode;
  $class = $configEntityType->getClass();
  return new $class($translatedConfig->get(), $configEntityType->id());
}

An alternative would be:

public function getTranslatedConfigEntity(ConfigEntityInterface $configEntity, LanguageInterface $language) {
  $currentLanguage = $this->languageManager->getConfigOverrideLanguage();
  $this->languageManager->setConfigOverrideLanguage($language);
  $translatedConfigEntity = $this->entityTypeManager
    ->getStorage($configEntity->getEntityTypeId())
    ->load($configEntity->id());
  $this->languageManager->setConfigOverrideLanguage($currentLanguage);
  return $translatedConfigEntity;
}
  • Just to mention, not all config entities can be translated with this approach. For example, webform entity defines its own translation logic. – Leksat May 17 at 9:36
5

The answer from @Smartsheet eng is correct if you want to load and read a specific translation as a config entity, see also How to progragrammatically get NodeType translated value in D8?.

However, changing them is different, because the config entity can't be saved like that, it doesn't understand what is a translation and what's not. It will just overwrite your default language with that data. See also https://www.drupal.org/project/drupal/issues/2910353.

To actually manage a translation of a config entity, you have to directly interact with the config system, you can see how in \Drupal\config_translation\Form\ConfigTranslationFormBase::submitForm():

$config_translation = \Drupal::languageManager()->getLanguageConfigOverride($langcode, $config_name);

// Write the keys you want to translate on the config object.
$config_translation->save();
  • Note: $config_translation->setData($config_entity->toArray()); is how you get from config entity to config object. – Smartsheet eng Sep 28 '18 at 6:26
  • 1
    That doesn't work for any entity type (field storages) and then you'd have everything in there, you must only add the translatable keys. – Berdir Sep 28 '18 at 6:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.