This extension translates TYPO3 content elements and records using DeepL.
Warning
Due to dependencies on various third-party packages, this extension works
only if TYPO3 is installed in Composer mode.
There will be no support for non-composer installations.
This extension translates TYPO3 content and records using the DeepL
translation service.
You will need to register an account with DeepL.
Why this extension?
There are other similar extensions to this. One is EXT:deepltranslate,
which is the first extension of the kind. It works for TYPO3 versions 8 and 9
but not later. There is a fork of this extension by web-vision GmbH named
EXT:wv_deepltranslate. This extension works with newer TYPO3 versions but
it inherits a lot of old legacy code. While developers at web-vision did a
great job supporting and developing the fork, this extension follows a
separate implementation.
Other extensions do not allow you to modify the translation process, for
example to inspect and change field values before and after translation, or to
force or prevent translation of the field. This extension provides several
events that can alter translation behavior or modify field values before and
after the translation.
The extension can translate FlexForm fields, including sections. This is useful
for custom content elements.
This extension is not in any way based on two above mentioned extensions or contains any of their code. This is
completely new code.
Source code, bugs, etc
The project is hosted on GitHub at https://github.com/dmitryd/dd_deepl.
Questions are not answered in the bug tracker. Use TYPO3 Slack for questions
and answers.
Installation
Install the extension in a TYPO3 14 Composer installation:
If the environment variable is not set, DeepL is treated as disabled for
that site.
Legacy TypoScript configuration is available only as a deprecated opt-in
fallback. See Migration before using it.
Warning
Due to dependencies on various third-party packages, this extension works
only if TYPO3 is installed in Composer mode.
There will be no support for non-composer installations.
Configuration
Configure the extension in the site configuration:
DeepL API key for the site. Free API keys end with :fx and
automatically use the DeepL free API endpoint.
The value can use a TYPO3 environment placeholder, for example
%env(TYPO3_DEEPL_API_KEY)%. If the placeholder is still
unresolved at runtime, the API key is treated as empty, DeepL is
disabled for the site, and a notice is written to the TYPO3 log.
ddDeepl.timeout
ddDeepl.timeout
Type
integer
Default
30
Timeout in seconds for network requests to DeepL. Values are limited
to the effective range from 3 to 60.
Larger pages may perform many DeepL requests. If DeepL does not
respond before the timeout, the affected localized records are removed
again so editors can retry them later. The technical error details are
written to the TYPO3 log.
ddDeepl.maximumNumberOfGlossariesPerLanguage
ddDeepl.maximumNumberOfGlossariesPerLanguage
Type
integer
Default
2
Maximum number of DeepL glossaries that can be created per language
pair through this extension.
ddDeepl.glossaries
ddDeepl.glossaries
Type
map
Default
empty
Maps a language pair to a glossary id. The key format is
source-target, for example de-en.
TypoScript configuration is only used when the extension configuration
option configurationSource is set to
legacyTypoScript. Legacy mode emits a deprecation warning.
There is no automatic fallback from site configuration to TypoScript.
Warning
Use Configuration for new installations and
Migration for existing TypoScript configuration.
How long to wait for network requests to DeepL servers
Example:
module.tx_dddeepl.settings.timeout = 5
Copied!
Setup
apiKey
apiKey
type
string / stdWrap
Default
empty
Default is a constant. If there is an environment variable named
TYPO3_DEEPL_API_KEY, it will be used instead.
glossaries
glossaries
type
array
Default
empty
An array of mappings between language pairs and glossary id values. You
can find glossary id in the Backend module or in the output of the
glossary console command (see How to manage glossaries). In most
cases DeepL uses the glossary automatically, but sometimes you need to
specify it to be used for translations.
How long to wait for network requests to DeepL servers
Example:
module.tx_dddeepl.settings.timeout = 5
Copied!
TSConfig reference
Page TSConfig
localization.enableDeepL
Datatype
boolean
Description
Enables DeepL as a TYPO3 localization handler in the localization wizard.
Note that direct DataHandler translations are not affected by this
option.
Default
1
Example
mod {
web_layout {
localization.enableDeepL = 1
}
}
Copied!
Migration
Version 14 uses site configuration as the default configuration source.
Existing TypoScript settings are not read unless legacy mode is explicitly
enabled.
Migrate TypoScript settings
Move the former TypoScript settings to the ddDeepl key in the site
configuration:
The ddDeepl.apiKey value should normally use an environment variable
so the secret is not stored in the site configuration file.
Temporary legacy mode
Legacy TypoScript configuration can be enabled temporarily in the extension
configuration. In Composer-based TYPO3 installations this configuration can be
set in config/system/additional.php:
The same value can also be stored through the TYPO3 extension configuration UI,
if it is available in the project. The resulting configuration value must be:
This mode is deprecated, emits a deprecation warning, and should only be used
as a temporary rollback path while migrating site configuration. There is no
automatic fallback from site configuration to TypoScript.
For Integrators
Integrators can do the following with the extension:
Add configuration (API key)
Manage glossaries
Add configuration
In order to use DeepL, you need to obtain the API key and configure it in the
extension. There are two types of the API key: free and paid.
Free API key is useful for development and testing. It has enough limits for
both these tasks. Free key ends with :fx.
Paid API key has much higher limits. It is meant to be used in production.
To obtain the API key you need to register with DeepL and get the key in your
DeepL account settings.
Add the API key to the site configuration under ddDeepl.apiKey. The
value can use TYPO3 environment placeholders, for example
%env(TYPO3_DEEPL_API_KEY)%. Environment variables are recommended
because they keep secrets out of the site configuration file.
Legacy TypoScript configuration can still be enabled as a deprecated
temporary fallback. See Migration.
Translation errors and retries
DeepL translations are executed while TYPO3 creates localized records. If a
single content element or related record cannot be translated, the extension
removes that localized record again instead of keeping a translated record with
original text.
Editors see a generic message that some elements were not translated and can
retry the translation later. Technical details, including the table, record
identifier, field identifier and DeepL exception message, are written to the
TYPO3 log.
The timeout for DeepL requests is configured with ddDeepl.timeout.
The default timeout is 30 seconds.
Manage glossaries
Glossaries are a way in DeepL to specify alternative translations to certain
words. Some words can have generic accepted translations, but if your site is
specific to a certain industry or activity, then words of one language may map
to something other than DeepL would typically produce. This is where glossaries
come in. They contain word pairs that map source words to target words.
DeepL supports glossaries for various language pairs.
There can be multiple glossaries per language combination. The extension
allows you to add, delete, download and remove glossaries, and to see what
glossaries you have.
Attention
Glossaries are added per API key. Make sure that you add them for both
your free key (development and testing contexts) and paid key
(production) if you use separate keys for contexts.
The extension allows you to specify the limit on the amount of glossaries per
language pair. While DeepL itself does not impose any limits, it is good to
have that number under control. Use
ddDeepl.maximumNumberOfGlossariesPerLanguage in site configuration.
How to manage glossaries
Glossary management happens via the shell command or Backend module.
When the command is executed without --site or --root, the
extension auto-selects the site only if the TYPO3 instance has exactly one
configured site. Instances with multiple sites must pass either --site
or --root. Passing both options is an error.
Here is the output of the shell command's help screen:
$ vendor/bin/typo3 deepl:glossary --help
Description:
Uploads, downloads, lists, or deletes DeepL glossaries using account settings in the current TYPO3 version
Usage:
deepl:glossary [options] [--] <action>
This command manages DeepL glossaries.
Usage:
vendor/bin/typo3 deepl:glossary info
Fetches information about supported language combinations and existing glossaries.
vendor/bin/typo3 deepl:glossary add -f file.csv -g "My glossary" -s en-us -t de
Adds a glossary.
vendor/bin/typo3 deepl:glossary get -i a1b33a94-ec7e-4ef5-8830-2f7309fab155
Fetches the glossary by its id. To see the id use the "info" command. Fetched file will be named according to the id.
vendor/bin/typo3 deepl:glossary delete -i a1b33a94-ec7e-4ef5-8830-2f7309fab155
Removes the glossary by its id. To see the id use the "info" command.
Arguments:
action What to do: add, get, delete glossaries or show the information
Options:
-f, --file[=FILE] Glossary in CSV format
-i, --id[=ID] Glossary id
-g, --name[=NAME] Glossary name
-r, --root[=ROOT] Root page id to use (if your instance has more than one)
--site[=SITE] Site identifier to use (if your instance has more than one)
-s, --source-language[=SOURCE-LANGUAGE] Source language
-t, --target-language[=TARGET-LANGUAGE] Target language
Copied!
Backend module
There is also a Backend module where it is possible to view current API limits
as well as information about uploaded glossaries. You can also upload
glossaries via this module.
The module is available as Site > DeepL in the main menu.
For Editors
Editors can translate content and records using DeepL.
Start the regular TYPO3 localization wizard from the Page module or from a
record localization button. Select DeepL as the localization handler when the
wizard asks how the localization should be processed.
DeepL does not add a separate localization button. It is available as an
option in the standard TYPO3 localization wizard.
Records will get translations if the combination of source and target language
is supported by DeepL.
Large translations
When a page contains many content elements, the localization wizard shows a
warning before the DeepL translation starts. Translating many elements can take
longer and may increase the chance of DeepL API timeouts.
If some elements cannot be translated due to DeepL errors, they are removed
from the localized page again. You can start the localization wizard later and
try translating those elements again.
For Developers
You can use the DmitrydDdDeeplServiceDeeplTranslationService class
to translate TYPO3 records, certain fields, or plain texts. Records must have
an entry in $GLOBALS['TCA'].
Create the service through dependency injection or
GeneralUtility::makeInstance(). If the current request does not contain
a site context, call setSite() before invoking DeepL operations.
If no site can be resolved, or if the site has no ddDeepl.apiKey, DeepL
is treated as disabled.
There are several events that can alter the behavior of the service. You can
use them to get notified about translations, force or prevent a field from
being translated, or alter the field value before and after it is sent to
DeepL.
API
Translation service
classDeeplTranslationService
Fully qualified name
\Dmitryd\DdDeepl\Service\DeeplTranslationService
This is the class you, as a developer, would use to translate data using DeepL.
Creates the instance of the class. You can pass additional DeepL
options as described in the DeepL documentation. The runtime cache
and configuration factory are injected by TYPO3 during normal service
creation.
setSite(?Site $site): self
returntype
self
Sets the site context for the next DeepL operations. Use this method
for CLI tasks, backend actions without a request site attribute, or
custom integrations that already know the target site.
Returns
The current service instance.
isAvailable(): bool
returntype
bool
Returns
true if DeepL can process requests with the current
site configuration and API limits.
The method will go through each field in the record, evaluate if it can
be translated and call DeepL for translation. The result is an array
with translations.
The method will get the value of the field and call DeepL for
translation. Unlike in translateRecord(), there are no checks
if the field can be translated.
The method will get the text and call DeepL for translation.
Returns
Translated field value
Events
classAfterFieldTranslatedEvent
Fully qualified name
\Dmitryd\DdDeepl\Event\AfterFieldTranslatedEvent
This event is fired after the field was translated by translateRecord or translateField
and allows to modify the translated value.
getTableName(): string
returntype
string
Returns
Table name of the field
getFieldName(): string
returntype
string
Returns
The field name
getFieldValue(): string
returntype
string
Returns
The current (translated) field value
getSourceLanguage(): SiteLanguage
returntype
\TYPO3\CMS\Core\Site\Entity\SiteLanguage
Returns
Source language to translate from
getTargetLanguage(): SiteLanguage
returntype
\TYPO3\CMS\Core\Site\Entity\SiteLanguage
Returns
Target language to translate to
setFieldValue(string $fieldValue): void
Sets the new value of the field.
classAfterRecordTranslatedEvent
Fully qualified name
\Dmitryd\DdDeepl\Event\AfterRecordTranslatedEvent
This event is fired after the record was translated by translateRecord.
You can examine fields and alter their contents by using getTranslatedFields and
setTranslatedFields. Note that there is no method for getting the source language
because you can get this information from the record.
This event is fired before the field is translated by translateRecord or translateField
and allows to modify the original field value before it is sent to DeepL.
This event is fired before the record is translated by translateRecord.
You can examine fields and alter their contents by using getTranslatedFields and
setTranslatedFields. Note that there is no method for getting the source language
because you can get this information from the record.
This event is fired after the DeepL translation service evaluated whether
the field can be translated.
getTableName(): string
returntype
string
Returns
Table name of the field
getFieldName(): string
returntype
string
Returns
The field name
getCanBeTranslated()
returntype
bool|null
Returns
true, if the service thinks that the field can be
translated, false, if definitely not, null, if the
service could not decide.
setCanBeTranslated(): void
Pass true, if the service thinks that the field can be
translated, false, if not. Note that you cannot pass
null here. If you are unsure, do not set any value. The service
will not translate the field unless the value after all events is set
to true.
classPreprocessFieldValueEvent
Fully qualified name
\Dmitryd\DdDeepl\Event\PreprocessFieldValueEvent
This event is fired before the field is set to DeepL for translation and allows you to modify the value.
A typical example would be, for example, doing data clean up or replacing with a normal space
in texts, or removing several <br> tags.