Skip to main content

Deepl Translator Bundle

Installation​

  • Execute: $ composer require open-dxp/deepl-translator-bundle
  • Add the following to your bundles.php:
    \OpenDxp\Bundle\DeeplTranslatorBundle\OpenDxpDeeplTranslatorBundle::class => ['all' => true],
  • Execute: $ bin/console opendxp:bundle:install OpenDxpDeeplTranslatorBundle

Queue Worker for shared & admin interface translations​

$ bin/console messenger:consume deepl_translate

Configuration​

Create the following configuration:

opendxp_deepl_translator:
api_key: 'YOURKEYHERE'
options:
# DeepL Options: One of \DeepL\TranslatorOptions
# @see https://github.com/DeepLcom/deepl-php#configuration
connect_timeout: 5.2
translation_options:
# Translation Options: One of \DeepL\TranslateTextOptions
# @see https://github.com/DeepLcom/deepl-php#text-translation-options

# Optional: Override default language locale mapping
# language_locale_mapping:
# en: 'en-GB'
# pt: 'pt-BR'

autotranslate:
enable: true
sourceLanguage: 'de'
targetLanguage: 'en'
classes:
- 'NewsEntry'
- 'Employee'

# Optional: ignore Mandatory fields while persisting data
# ignore_mandatory_check: true
#
# Optional: Enable field selection for the translations in data objects. This is false by default.
# dataobjects_enable_field_selection: true
#
# Optional: Define fields to ignore while translating
# element_definitions:
# - class: 'DataObject.NewsEntry'
# enable_field_selection: false # Enable/Disable field selection for this class only
# ignore_fields:
# - title
# - description
# - class: 'FieldCollection.MyFieldCollectionName'
# ignore_fields:
# - myfield1
# - myfield2

Important: An admin account still can do everything regardless of permissions.

Usage​

This bundle adds a button to data object and document editors. Click them and see the magic happen. Translating documents will translate all input, textarea and wysiwyg editables with their key and navigation name. While translating data objects the same input types will be translated, but only if they're in localized fields.

Features​

  • Translate:
    • Documents
      • Page
        • key
        • navigation_name
        • Supported editables:
          • input
          • textarea
          • wysiwyg
          • link
      • Email
        • subject
    • Objects
      • Supported data types:
        • localizedFields:
          • input
          • textarea
          • wysiwyg
        • fieldcollection
        • block
      • Ignore fields by passing ignore_fields in the element_definitions option.
      • Set enable_field_selection to true to allow the user to select which fields to translate. All allowed data types in FieldCollections or Block elements are also listed for selection. This feature is disabled by default.
    • Assets
      • Meta data (context menu)
  • Translate all shared translations
  • Glossary

Field selection​

If you want to select which fields to translate of a dataobject, you can set enable_field_selection to true in the element_definitions option (example above). If you want to select fields on all data objects, you can set dataobjects_enable_field_selection: true.

Auto translate​

The auto translate feature can be disabled globally by setting autotranslate.enable to false. On save if a DataObject is in the class list defined in autotranslate.classes, it will be automatically translated from autotranslate.sourceLanguage to autotranslate.targetLanguage. Make sure the languages are properly configured in opendxp and are supported by DeepL to avoid exceptions.

The class list can consist of a simple class name (like Product), then the standard OpenDXP namespace for DataObjects will be added during the check. You can also configure a FQCN, then it will be checked literally.

To disable automatic translation on a specific DataObject, create the Property deepl_autotranslate_disable as a checkbox and check it.

Glossaries​

Glossaries are disabled by default. To enable glossaries, the value must be set to true.

opendxp_deepl_translator:
glossary: true

Glossaries can be managed in Deepl Admin Panel (https://www.deepl.com/de/glossary). There may exist multiple glossaries for a sourceLanguage-targetLanguage combination, but only one can be active. Only active glossaries are used for the translation process. If a glossary is activated all other glossaries for the same sourceLanguage-targetLanguage combination are deactivated automatically.

Extending​

To support more specific Data Objects or Documents, the bundle can be easily extended:

Create a data extractor​

Create a class which implements OpenDxp\Bundle\DeeplTranslatorBundle\DataExtractor\DataExtractorInterface

class MyDataExtractor implements DataExtractorInterface
{
public const KEY = 'myKey';

public function extract(?ModelInterface $element, array $options = []): array
{
// ...
}

public function supports(?ModelInterface $element): bool
{
// ...
}

public function getKey(): string
{
return static::KEY;
}
}

The supports method needs to check if the Extractor supports the current object (for example an instanceof check)

The result of extract needs to be formatted in a specific way for the translator to be able to handle it. Example:

$result['name'][] = $object->getName();

This is because documents can have multiple editables of the same type.

Create a data writer​

Create a class which implements OpenDxp\Bundle\DeeplTranslatorBundle\DataWriter\DataWriterInterface

class MyDataWriter implements DataWriterInterface
{
public function supports(?ModelInterface $element): bool
{
// ...
}

public function requires(string $key): bool
{
return $key === MyDataExtractor::KEY;
}

public function write(?ModelInterface $element, array $translations, string $targetLanguage): void
{
// ...
}
}
  • The supports method needs to check if the Extractor supports the current object (for example an instanceof check)
  • The requires method needs to check for the extractor key so the writer knows which translations it handles.

Tying it together​

In your services.yaml create new services out of the writer and extractor and tag them accordingly:

services:
MyDataExtractor:
tags: [ 'dachcom.translator.data_extractor' ]

MyDataWriter:
tags: [ 'dachcom.translator.data_writer' ]

They then will be automatically included in the chain.


Genius​

A Content Crafter plan can translate through DeepL instead of a language model. Which one runs is picked in the backend, and nothing changes until somebody picks it.


Upgrade Info​

Before updating, please check our upgrade notes!


License​

DACHCOM.DIGITAL AG, Löwenhofstrasse 15, 9424 Rheineck, Schweiz
dachcom.com, [email protected]
Copyright © 2026 DACHCOM.DIGITAL. All rights reserved.

For licensing details please visit LICENSE.md