Manages translations of user-facing content - products, page HTML, emails and UI labels - for the current organisation. A translation is recorded against a source object (a type, id and optional field) and can be looked up directly or by a SHA-1 hash of the source text. The active language for a request is resolved from a query parameter, a cookie, the current profile's language preference or the browser's Accept-Language header, in that order, falling back to the current website's default language. It also drives an AI-assisted editing pass that identifies translatable text within page HTML, optionally corrects spelling and grammar, wraps newly-found text for translation, and generates translations into every configured language via the configured LLM. Registered as translationService for server-side scripts, and reached from Java via C(TranslationService.class).
Group: Managers
Properties
| Property | Returns | Description |
|---|---|---|
| crypt | MessageDigest | |
| languages | List<Language> | Lists the languages configured for the current organisation. |
| selectedLangCode | String | Resolves the language code that should be used for content shown to the current user. |
| translationAuthor | boolean | Checks whether the current profile is authorised to author (create or edit) translations on the current website. |
Methods
get(Long id) · setTranslate(Translation t, String translated) · deleteLanguage(Language lang) · deleteTranslation(Translation trans) · findTypes() · getLanguages() · searchTranslations(String langCode, String sourceType, String sourceId, String sourceField) · getTranslationByObject(String langCode, String sourceType, String sourceId) · getTranslationByObject(String langCode, String sourceType, String sourceId, String sourceField) · getTranslationBySource(String langCode, String sourceText) · getTranslationByHash(String langCode, String sourceHash) · setTranslation(String langCode, String sourceText, String sourceType, String sourceId, String translation) · setTranslation(String langCode, String sourceText, String sourceType, String sourceId, String sourceField, String translation) · copyTranslations(String sourceType, String fromSourceId, String toSourceId) · existTranslation(String langCode, String sourceText, String sourceType, String sourceId, String sourceField, String translation) · calcHash(String sourceText) · getSelectedLangCode() · selectedLangCode(Profile currentUser) · translateWithDefault(String sourceType, String sourceId, String field, String defaultText) · translate(String sourceType, String sourceId, String field, String langCode) · translate(String sourceType, String sourceId, String field) · translateText(String sourceText) · generateTranslation(String targetLangCode, String sourceText) · setTranslatedText(String translated, String sourceText) · getTranslatedFileName(String name, String langCode) · setTranslation(String langCode, Translatable translatable, String field, String copy) · isTranslationAuthor() · isTranslationAuthor(Profile user, Website website) · aiEditPageContent(String html, String sourceLangCode, boolean correctSpellingGrammar, boolean wrapTranslatableSpans, boolean createTranslations)
get(Long id)
Returns: Translation
Looks up a translation by its database id.
| Parameter | Description |
|---|---|
id | the translation's database id |
setTranslate(Translation t, String translated)
Returns: void
Sets the translated text on an existing translation and saves the change immediately.
| Parameter | Description |
|---|---|
t | the translation to update |
translated | the new translated text to store |
deleteLanguage(Language lang)
Returns: void
Deletes a language configured for the current organisation. Logs a warning and throws a runtime exception without deleting anything if the given language belongs to a different organisation.
| Parameter | Description |
|---|---|
lang | the language to delete |
deleteTranslation(Translation trans)
Returns: void
Deletes a single translation. Logs a warning and throws a runtime exception without deleting anything if the given translation belongs to a different organisation than the current one.
| Parameter | Description |
|---|---|
trans | the translation to delete |
findTypes()
Returns: List<Pair<String,Long>>
Lists the distinct translation source types recorded for the current organisation, each with the number of translations of that type.
getLanguages()
Returns: List<Language>
Lists the languages configured for the current organisation.
searchTranslations(String langCode, String sourceType, String sourceId, String sourceField)
Returns: List<Translation>
Finds translations for the current organisation matching the given language, source type and source id. Any blank filter is ignored, so passing all blank values returns every translation for the organisation. The sourceField parameter is accepted but not used to filter results.
| Parameter | Description |
|---|---|
langCode | the language code to filter by, or blank to match any language |
sourceType | the translation source type to filter by, or blank to match any type |
sourceId | the source object's id to filter by, or blank to match any id |
sourceField | accepted but not used to filter results |
getTranslationByObject(String langCode, String sourceType, String sourceId)
Returns: String
Looks up the stored translation for a source object in a given language, matching only a translation with no field set.
| Parameter | Description |
|---|---|
langCode | the language to look up, returns null if blank |
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
getTranslationByObject(String langCode, String sourceType, String sourceId, String sourceField)
Returns: String
Looks up the stored translation for a source object in a given language. When sourceField is given it is matched against either the translation's source field name or its source hash, so a hash can be passed in place of a field name; when sourceField is null, the translation with no field set is returned.
| Parameter | Description |
|---|---|
langCode | the language to look up, returns null if blank |
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
sourceField | the field name or source hash to match, or null to match a translation with no field set |
getTranslationBySource(String langCode, String sourceText)
Returns: String
Looks up a translation for raw source text by hashing it and delegating to a hash-based lookup.
| Parameter | Description |
|---|---|
langCode | the language to translate into, or null to return sourceText unchanged |
sourceText | the source text to translate |
getTranslationByHash(String langCode, String sourceHash)
Returns: String
Looks up a translation by the SHA-1 hash of its source text and its language code.
| Parameter | Description |
|---|---|
langCode | the language to translate into |
sourceHash | the SHA-1 hash of the source text, as produced by calcHash |
setTranslation(String langCode, String sourceText, String sourceType, String sourceId, String translation)
Returns: void
Stores a translation for a source object with no field set, delegating to the field-aware overload.
| Parameter | Description |
|---|---|
langCode | the language the translation is in |
sourceText | the original source text, hashed and stored alongside the translation |
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
translation | the translated text to store |
setTranslation(String langCode, String sourceText, String sourceType, String sourceId, String sourceField, String translation)
Returns: void
Creates or updates the stored translation for a source object, field and language, recording the current profile as editor. If a translation already exists for the given source type, id, field and language it is updated in place; otherwise a new one is created.
| Parameter | Description |
|---|---|
langCode | the language the translation is in |
sourceText | the original source text, hashed and stored alongside the translation |
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
sourceField | the field being translated, or null to store a translation with no field set |
translation | the translated text to store |
copyTranslations(String sourceType, String fromSourceId, String toSourceId)
Returns: void
Copies all translations of the given source type from one source id to another. Used when duplicating an object (e.g. a group email) so its translation labels follow the copy, which has a new id.
| Parameter | Description |
|---|---|
sourceType | the translation source type, e.g. "email" |
fromSourceId | the source id to copy translations from |
toSourceId | the source id to copy translations to |
existTranslation(String langCode, String sourceText, String sourceType, String sourceId, String sourceField, String translation)
Returns: Boolean
Checks whether a translation already exists for the given language, source type, id and field. The sourceText and translation parameters are accepted but not used by this check.
| Parameter | Description |
|---|---|
langCode | the language code to check for |
sourceText | unused |
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
sourceField | the field being translated, or null to match a translation with no field set |
translation | unused |
calcHash(String sourceText)
Returns: String
Computes the SHA-1 hex hash used to look up a translation by its source text.
| Parameter | Description |
|---|---|
sourceText | the text to hash |
getSelectedLangCode()
Returns: String
Resolves the language code that should be used for content shown to the current user.
selectedLangCode(Profile currentUser)
Returns: String
Resolves the language code to use for the current request, checking in order: a selectedLangCode request parameter, a selectedLangCode cookie, the given profile's language preference, the current website's default language, and finally the browser's Accept-Language header matched against the organisation's configured languages.
| Parameter | Description |
|---|---|
currentUser | the profile to fall back to for a language preference, or null if there is no current user |
translateWithDefault(String sourceType, String sourceId, String field, String defaultText)
Returns: String
Translates a source object's field into the current request's language, falling back to a default when no translation exists.
| Parameter | Description |
|---|---|
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
field | the field being translated, may be null |
defaultText | the text to return if no translation is found |
translate(String sourceType, String sourceId, String field, String langCode)
Returns: String
Translates a source object's field into the given language.
| Parameter | Description |
|---|---|
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
field | the field being translated, may be null |
langCode | the language to translate into |
translate(String sourceType, String sourceId, String field)
Returns: String
Translates a source object's field into the current request's selected language.
| Parameter | Description |
|---|---|
sourceType | the translation source type, e.g. "email" or "Product" |
sourceId | the source object's id |
field | the field being translated, may be null |
translateText(String sourceText)
Returns: String
Translates raw source text into the current request's selected language, looking it up by its content hash.
| Parameter | Description |
|---|---|
sourceText | the source text to translate |
generateTranslation(String targetLangCode, String sourceText)
Returns: String
Machine-translates source text into the given target language using the configured translation provider.
| Parameter | Description |
|---|---|
targetLangCode | the language code to translate into |
sourceText | the text to translate |
setTranslatedText(String translated, String sourceText)
Returns: void
Stores translated text keyed by the content hash of the source text, for the current request's selected language.
| Parameter | Description |
|---|---|
translated | the translated text to store |
sourceText | the original source text, hashed to form the lookup key |
getTranslatedFileName(String name, String langCode)
Returns: String
Builds a language-specific variant of a file name by inserting the language code immediately before the file extension.
| Parameter | Description |
|---|---|
name | the base file name, must contain a '.' extension separator |
langCode | the language code to insert before the extension |
setTranslation(String langCode, Translatable translatable, String field, String copy)
Returns: void
Stores a translation for a translatable object's field, using the object's source type and id.
| Parameter | Description |
|---|---|
langCode | the language the translation is in |
translatable | the object being translated, supplies the source type and id |
field | the field being translated |
copy | the translated text to store |
isTranslationAuthor()
Returns: boolean
Checks whether the current profile is authorised to author (create or edit) translations on the current website.
isTranslationAuthor(Profile user, Website website)
Returns: boolean
Checks whether the given profile is authorised to author (create or edit) translations on the given website.
| Parameter | Description |
|---|---|
user | the profile to check |
website | the website to check authorisation against |
aiEditPageContent(String html, String sourceLangCode, boolean correctSpellingGrammar, boolean wrapTranslatableSpans, boolean createTranslations)
Returns: Map<String,Object>
Runs an AI editing pass over a page's HTML body: identifies translatable text, optionally corrects spelling and grammar, wraps translatable text in trans-lookup spans, and generates translations for every configured language other than the source language. Only leaf elements (elements with no element children) are treated as text segments, and any element inside a data-dynamic-href container or a keditor-component-data element is left untouched entirely - component structure and attributes are never modified, only text content and newly-inserted trans-lookup spans. An element already wrapped as a trans-lookup span is not re-corrected or re-wrapped on a later run - it is only used to backfill translations for languages that don't already have one, so a translator's manual edits are never overwritten. Kcode placeholder tokens are masked before sending text to the LLM and restored afterwards; a segment is skipped rather than risking corruption if a token goes missing from the AI's response.
| Parameter | Description |
|---|---|
html | the page's current HTML body |
sourceLangCode | the page's current language code, excluded from the generated translations |
correctSpellingGrammar | whether to fix spelling/grammar mistakes in translatable text |
wrapTranslatableSpans | whether to wrap newly-identified translatable text in {@code .trans-lookup} spans |
createTranslations | whether to generate {@link Translation} rows for every configured language |