Custom Translator
When DeepL and Copilot AI don't fit, you can plug in any translation backend. Three options, increasing in capability:
Option 1: Closure
The simplest path. Set strategy to a closure with the signature fn (string $text, string $target, ?string $source): string. The plugin auto-wraps it in CallableStrategy.
return [
'johannschopplich.content-translator' => [
'strategy' => function (string $text, string $toLanguageCode, ?string $fromLanguageCode = null): string {
return myCustomTranslateFunction($text, $toLanguageCode, $fromLanguageCode);
}
]
];
A closure cannot mark a single text as failed – its return type is string. Return an empty string for a text you could not translate: the plugin keeps the source text and records a drop. Returning the source text yourself counts as a successful translation.
Strategy implementation that batches at the wire level.Option 2: Custom Strategy
For per-unit failure handling, observability, and access to TranslationUnit::$fieldKey, implement the Strategy interface directly. See Implementing a Custom Strategy for the full pattern – return null for a unit you could not translate, emit a warning for it, and throw TranslationException only when zero units survived.