Custom Translator

Plug in any translation API or local logic – via a closure, a CallableStrategy, or your own Strategy implementation.

When DeepL and Copilot AI don't fit, you can plug in any translation backend. Three options, increasing in capability:

Closure

One translation per text, no batching. Fastest to write.

CallableStrategy

Same as above, made explicit. The migration target for translateFn.

Custom Strategy

Implement Strategy for batching, mode-aware dispatch, and structured exceptions.

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.

config.php
return [
    'johannschopplich.content-translator' => [
        'strategy' => function (string $text, string $toLanguageCode, ?string $fromLanguageCode = null): string {
            return myCustomTranslateFunction($text, $toLanguageCode, $fromLanguageCode);
        }
    ]
];
A closure runs once per text. DeepL and AI strategies batch – this one cannot. For high-volume sites or large batch translations, prefer a custom Strategy implementation that batches at the wire level.

Option 2: Custom Strategy

For per-unit failure handling, observability, and access to TranslationUnit::$mode / $fieldKey, implement the Strategy interface directly. See Implementing a Custom Strategy for the full pattern – pre-fill source text, attempt each unit, emit a warning on per-unit failure, throw TranslationException only when zero units survived.

Migrating from the deprecated translateFn config? See the Migration Guide – it's a one-line rename.