Skip to content

Translators

Machine translation of content. A translator is a row in PageBlocks → Translators; the component calls the provider's API and stores the result as a translation of the original.

This is about content, not about interface strings — those live in lexicons and are handled by Localization.

Drivers

DriverProvider
chatgptOpenAI
claudeAnthropic
geminiGoogle
grokxAI
deeplDeepL

Four of them are LLMs and one is a dedicated translation service; they share one interface, so switching is a matter of changing the row.

Configuring one

FieldWhat it is
nameHuman-readable name
driverOne of the keys above
api_keyThe provider's key
modelModel name, for the LLM drivers
base_urlOverride the endpoint — for a proxy or a self-hosted gateway
promptInstruction template, LLM drivers only
published_atAn unpublished translator is not used

An unknown driver is not an error: it is written to the MODX log and the factory returns nothing.

The prompt

The default asks for the translation only, preserving HTML and placeholders. Your own template can use two placeholders:

Translate the following text from [[+from]] to [[+to]].
Reply with the translation only, preserving any HTML markup and placeholders:

[[+from]] and [[+to]] are replaced with the language codes in upper case. This is the knob to reach for when a provider keeps "helpfully" adding explanations around the translation, or mangles your {$placeholders}.

It never throws

translate() always returns a string. Every failure path returns the original text and writes the reason to the MODX log:

SituationResult
Empty or numeric textReturned unchanged, no request made
No API keyOriginal text, reason logged
Transport failed or provider erroredOriginal text, reason logged
Response could not be parsedOriginal text, response logged

That is deliberate — a translation run over hundreds of rows should not abort halfway because one request timed out. It also means a silent failure looks like "nothing was translated". When that happens, read the log before changing the settings.

Numbers are skipped on purpose: sending 2024 to an LLM and getting a paraphrase back is a real risk, and there is nothing to translate anyway.

Token budget

For the LLM drivers the output allowance scales with the input — roughly twenty tokens per word plus a floor for short strings, capped at 8192. Translations are about as long as their source, and the cap is there so a runaway response is not billed.

What gets translated

Translations are stored per language in pb_translations, against the languages configured in pb_languages. The page keeps the original when a translation is missing, so a half-finished translation never blanks the site.

Cost is yours

Every one of these providers bills per request. The component does not batch, cache or deduplicate across runs — translating the same field twice costs twice. Start on a few rows and look at the result before pointing it at a whole table.

© PageBlocks 2019-present