Database Datas Translation
The database data translation feature in Activator is designed to meet the needs of multilingual environments by providing efficient management of dynamic data translations. In many cases, applications must present information tailored to the end user's language, whether for user interfaces or user-generated content.
This feature prevents the need to manually manage the translation of records or duplicate data sets for each language, which would otherwise lead to potential errors and a significant increase in complexity. For instance, imagine an e-commerce platform where product descriptions, categories, and payment information need to be available in multiple languages. Thanks to the data translation feature in Activator Admin, these data can be centralized and managed efficiently, ensuring a consistent and localized user experience.
In this documentation, we will explore how to configure and use this feature to optimize translation management in your Activator environment.
Languages Supported By Activator
This multilingual📚 capability is essential for creating inclusive applications that meet the needs of diverse user groups. Whether developing or interacting with content, Activator's language support enables a personalized experience, making it easier to access and understand information in the chosen language.
Languages Supported By Activator And Default Language
Activator supports two languages: English and French.
Managing Languages With Activator Cookies
Activator leverages the language cookie to dynamically translate and provide localized values within an application. This approach ensures that users receive content in their preferred language, enhancing the overall user experience. Based on the language cookie, Activator can automatically detect and apply appropriate translations for various data elements, such as form labels, error messages and dynamic content.
How does it work?
On Activator, a field named _lang_keys
is natively integrated into all data types. This field is specifically designed to store translation values of entities records, thereby facilitating multilingual data management.
The _lang_keys
field is used to store translations of properties located at the same level within an object (consider an object here as an entity record). This means that each set of properties in an object, whether at the root level or a nested level, can have its own _lang_keys
field to manage translations independently.
Here's an example to illustrate👇:
{
"title": "A car",
"description": "A car is a motor vehicle with wheels",
"others": {
"color": "blue",
"_lang_keys": [
{
"name": "color",
"languages": [
{
"name": "french",
"value": "bleue"
},
{
"name": "english",
"value": "blue"
}
]
}
]
},
"_lang_keys": [
{
"name": "title",
"languages": [
{
"name": "french",
"value": "Une voiture"
},
{
"name": "english",
"value": "A car"
}
]
},
{
"name": "description",
"languages": [
{
"name": "french",
"value": "Une voiture est un véhicule à roues, motorisé"
},
{
"name": "english",
"value": "A car is a motor vehicle with wheels"
}
]
}
]
}
In this example, the _lang_keys
field is present at two different levels of the object: at the root level to translate the properties title
and description
, and within the nested property others
to translate the property color. This provides maximum flexibility in managing translations, ensuring that each property in an object can be translated contextually, based on its location within the data structure.
Here is a table describing the _lang_keys
property:
PROPERTY | TYPE | DESCRIPTION |
---|---|---|
name | String | The name of the main object property to which translations are associated. |
languages | Table of objects | Contains translations of the specified property in different languages. Each object represents a translation for a specific language. It must contain a collection of objects following the format:
|
Methods For Recording
This section aims to describe the different approaches and best practices for capturing and storing translations within the _lang_keys
property.
In Client APIs
Using this API, you can add translations for different languages directly within an existing data record, ensuring that end users see the content in their preferred language.
API Details
PROPERTY | DESCRIPTION |
---|---|
URL |
|
Method | POST |
BODY |
|
In A storedFunction Component
To record translations in storedfunction type components, you can use the following code as a shortcut. This code updates the language resources for a specific record within an entity.
// Unique identifier of the record for which translations will be applied
Guid recordId = Guid.Parse("ebbe2919-54d6-4891-b0ce-578a0f498000");
// Path within data object (empty if applicable at root level)
string path = string.Empty;
// Unserialize JSON data containing translations in a list of language resources
var langKeysDatas = this.DeserializeObjectFromJson<List<EntityRecordLanguageResource>>(modelJson);
// Update registration language resources
await this.Context.Entities.UpdateRecordLanguageResources(
"activatord.entities.entityName", // Entity name
recordId, // Record ID
path, // Path within object (can be empty)
langKeysDatas // Translation data
);
JSON format (model Json)
The JSON passed as an argument, modelJson, must respect the following format:
[
{
"name": "string", // Target property name
"languages": [
{
"name": "string", // Language (for example, “french”, “english”)
"value": "string" // Corresponding translation
}
]
}
]
Usage In A Driver For Display
When retrieving data, translated information is often returned in the same format as it was updated. For example, an object containing translations for a title and description might look like this:
{
"title": "A car",
"description": "A car is a motor vehicle with wheels",
"_lang_keys": [
{
"name": "title",
"languages": [
{
"name": "french",
"value": "Une voiture"
},
{
"name": "english",
"value": "A car"
}
]
},
{
"name": "description",
"languages": [
{
"name": "french",
"value": "Une voiture est un véhicule à roues, motorisé"
},
{
"name": "english",
"value": "A car is a motor vehicle with wheels"
}
]
}
]
}
Let's assume that this data is stored in a variable called item
. The aim is to display the title
and description
in the user's current language.
The code below allows you to select and display translations according to the user's language:
const getTranslatedItem = function (objectElement, item) {
if (objectElement._lang_keys && objectElement._lang_keys.length > 0) {
// Find translations corresponding to the specified element (title or description)
let translatedItem = objectElement._lang_keys.find(el => el.name == item)
if (translatedItem && translatedItem.languages.length > 0) {
// Retrieve the user's current language code (default is “english”)
const langCode = $.cookie('user_language') || "english"
// Find the right translation for your current language
translatedItem = translatedItem.languages.find(el => el.name == langCode)
// Return translated value or default value if translation not available
return translatedItem ?.value || objectElement[item]
}
}
// Return default value if no translation found
return objectElement[item]
}
// Suppose the variable item contains the data of the record from the system.
getTranslatedItem('title', item)
getTranslatedItem('description', item)
Explanation of the Code
Function getTranslatedItem
:
- Parameters:
- objectElement
: The name of the property to translate (e.g., title
or description
).
- item
: The object containing the data, including the translations.
Checking for Available Translations:
- The function begins by checking if the object contains translations (_lang_keys
). If so, it looks for the translation corresponding to the specified item (e.g., the title).
Selecting the Language:
- The code retrieves the user's current language by checking a cookie ($.cookie('user_language')
). If this cookie doesn't exist, the default language is set to English.
Finding the Appropriate Translation:
- The function searches for the translation in the user's language. If a translation is found, it is returned. Otherwise, the default value of the item (i.e., the untranslated version) is used.
Returning the Value:
- The function returns the found translation or, if unavailable, the default value.
Using the Function:
- To obtain the translation for the title or description, simply call getTranslatedItem('title', item)
or getTranslatedItem('description', item)
.
Activator's Translation Utility
A UI tool that facilitates translations
Issues
This utility allows users to input the values of an item in multiple languages simultaneously, ensuring that the data is consistently available and aligned across all specified languages.
Graphic Presentation Of This Helper
Here's a presentation of the translation utility to show you how it works.

- Name of element to be translated
- Field for setting the value of an element according to language
- translation tab(The language changes from one tab to another on click)
How it works
This component is controlled by a setting found in the system settings⚙️ module.

- Accesses the component driver
- Component driver
- JSON content for management
JSON Content:
{
"multiple": true,
"resourceName": "sys.languageresources.sysMainResource",
"languages": [
{
"name": "english",
"title": "English",
"description": "English",
"titleResKey": "english",
"descResKey": "english"
}
]
}
PROPERTY | REQUIRED | DEFAULLT VALUE | DESCRIPTION |
---|---|---|---|
multiple | Yes | true | Determines whether the component can handle multiple languages simultaneously |
ressourceName | Yes | Specifies the name of the resource to which the component refers to manage translations. | Specifies the name of the resource to which the component refers to manage translations. |
languages | Yes |
| List of languages supported by the component. Each element in the table is a language object.
|
How To Integrate It Into A Driver Component
To integrate🗃️ translation functionality into a driver, let's assume that we want to implement it in a specific context. This context will contain several important elements, including :
- The container: the main container in which data is managed.
- Item record (optional): specific data for the item to be translated, if available.
In this example, we'll concentrate on translating user input. If you'd like to know more about translating static text to be displayed in the application, please see the section on Language Ressources. However, the final summary in this example will also include translations of static texts to ensure a complete understanding of the process.
Load Helper
To start integrating the translation functionality into your driver, the first step is to load the appropriate helper. Here's how to do it:
$activator.ui.jsmodules.load('sys.jshelpers.sysRenderFieldForMultiLanguage')
.then((helper) => {
// Now we simply need to instantiate the helper
});
This code loads the JS Helpers module sys.jshelpers.sysRenderFieldForMultiLanguage
, which is essential for managing the display of multilingual fields in the user interface. Once this helper is loaded, you can instantiate the helper and use it to manage translations
Parameter Definition And Initialization
After loading the helper, the next step is to define the necessary parameters and initialize the helper. Here's how to do it:
$activator.ui.jsmodules.load('sys.jshelpers.sysRenderFieldForMultiLanguage')
.then((helper) => {
/** Initialize internationalization of input fields */
let param = { ...context }; // Copy of the context passed in parameter
param.formId = "save-jobPositionTypes-form"; // Form identifier (HTML attribute value)
param.container = $('body'); // Container in which the form will be rendered
/*
param.lang will contain the list of texts to be displayed.
These values must be translated before use.
*/
param.lang = {
error: "Error",
something_went_wrong: "Something went wrong",
this_field_is_required: "This field is required",
in: "in"
};
// Instantiate helper with defined parameters
const InputFormLanguageHelper = new helper(param);
InputFormLanguageHelper.initialize()
.then(() => {
// Actions to be taken after successful initialization
// For example, here you can display data,
// return the form or perform other operations
})
.catch(error => {
toastr.error("Something went wrong", "Error");
console.log(error);
})
.finally(() => {
// Actions to be performed, such as hiding the loader
});
/** End of internationalization of entry fields */
});
PROPERTY | DESCRIPTION |
---|---|
param | An object containing the parameters needed to configure the helper, including the formId , the container , and a lang object for message translation. |
InputFormLanguageHelper | An instance of the helper that is initialized with the defined parameters. |
initialize() | This method initializes the helper, enabling the form to be configured and rendered according to the defined translations. |
Form Display
After loading and initializing the helper, the last step is to display the form in the user interface. Here’s how to proceed:
$activator.ui.jsmodules.load('sys.jshelpers.sysRenderFieldForMultiLanguage')
.then((helper) => {
/** Input Internationalization */
let param = { ...context };
param.formId = "save-jobPositionTypes-form"; // The form id (HTML attribute value)
param.container = $('body'); // The container in which the form will be rendered
/*
param.lang will contain the list of texts to be displayed.
Please ensure these values are translated accordingly.
*/
param.lang = {
error: "Error",
something_went_wrong: "Something went wrong",
this_field_is_required: "This field is required",
in: "in"
};
// Instantiate the helper with the defined parameters
const InputFormLanguageHelper = new helper(param);
InputFormLanguageHelper.initialize()
.then(() => {
//CONTAINER = context.container Render the form within the container
CONTAINER.html(`
<form id="save-jobPositionTypes-form">
<div class="row">
<div class="col-lg-12">
${InputFormLanguageHelper.render(
/** Input Internationalization */
{
id: "title", // The name and id of the input
title: "Title", // The input label
placeholder: "Enter The Title", // The input placeholder
type: "input", // The input type ['input' || 'textarea']
requiredMessage: `This field is required` // Message when the field is required
},
true // Whether the field is required or not
/** End Input Internationalization */
)}
</div>
<div class="col-lg-12">
${InputFormLanguageHelper.render(
{
id: "description",
title: "Description",
placeholder: "Enter The Description",
type: "textarea",
requiredMessage: `This field is required`
},
true
)}
</div>
</div>
</form>
`);
}).catch(error => {
toastr.error(`Something went wrong`, `Error`);
console.log(error);
}).finally(() => {
// For example, here you can hide the loader
});
/** End Input Internationalization */
});
PROPERTY | DESCRIPTION |
---|---|
param.lang | Contains text strings that should be displayed in the UI, such as error messages. These need to be translated as needed. |
InputFormLanguageHelper.render() | there are two parameters, the first contains the definition of the field to be generated and the second tells you whether it's required or not.
The second parameter, required, takes |
CONTAINER.html() | Injects the rendered form into the specified container. |
✋CAUTION
In cases where the
required
parameter is set totrue
, the mandatory field will be the one corresponding to the current language the user is connected with. If the user does not provide a value, the translation for that field in the current language will not be performed.The default value returned in the main object for a given field will be the value provided in the first input (the one corresponding to the current language the user is connected with).
How To Send It Default Values For Fields
To send default values to form fields, you can use the setValue{}
method of the InputFormLanguageHelper
object. Here's how you can do it in the context you've provided:
- Load Modules: The script begins by loading a JavaScript module called
sysRenderFieldForMultiLanguage
to manage the internationalization of form fields. - Helper initialization: The form is initialized with translation parameters and HTML attributes such as
formId
andcontainer
. - Render Form: The form is generated with input fields for title and description. Properties such as
id
,title
,placeholder
andrequiredMessage
are defined for each field. - Load Default Values: If data (
item
) is available, it is used to pre-populate form fields usingInputFormLanguageHelper
setValue
method.
Here is the commented code for a better understanding:
$activator.ui.jsmodules.load('sys.jshelpers.sysRenderFieldForMultiLanguage')
.then((helper) => {
/** Input Internationlization */
let param = { ...context }
param.formId = "save-jobPositionTypes-form" // The form id (HTML attribute value)
param.container = $('body')
/*
param.lang contiendra la liste des textes qui pourront etre affichés, bien vouloir traduire apres ces valeurs
*/
param.lang = {
error: "Error",
something_went_wrong: "Something went wrong",
this_field_is_required: "This field is required",
in: "in"
}
const InputFormLanguageHelper = new helper(param)
InputFormLanguageHelper.initialize()
.then(() => {
CONTAINER.html(`
<form id="save-jobPositionTypes-form">
<div class="row">
<div class="col-lg-12">
${InputFormLanguageHelper.render(
/** Input Internationlization */
{
id: "title", // The name and id of the input.
title: "Title", // The input label
placeholder: "Enter The Title", // The input placeholder
type: "input", // The input type ['input' || 'textarea']
requiredMessage: `This field is required`
},
true // If the field is required or not
/** End Input Internationlization */
)}
</div>
<div class="col-lg-12">
${InputFormLanguageHelper.render(
{
id: "description",
title: "Description",
placeholder: "Enter The Description",
type: "textarea",
requiredMessage: `This field is required`
},
true
)}
</div>
</div>
</form>
`);
}).catch(error => {
toastr.error(`Something went wrong`, `Error`);
console.log(error)
}).finally(() => {
// For example, here you can hide the loader
})
/** End Input Internationlization */
})
setValue{}
: This method is used to fill form fields with default values. You pass an array of objects describing each field and the corresponding value of the item object.
This allows form fields to be pre-filled with existing values, for example when editing a record.
How To Retrieve Entered Values
To retrieve the values entered in the form fields, you can use the validateFields{}
method of InputFormLanguageHelper
. This method returns a promise that resolves with an object containing the field values if validation is successful and reject()
when all required fields in the form are not completely filled out.
Here's how you can implement this in the click event listener of the submit button:
// (You can implement this piece of code in the click listener of your submit button.)
$('#submit-btn').on('click', function() {
InputFormLanguageHelper.validateFields()
.then(datas => {
// 'datas' contains the values entered in the form fields
console.log(datas); // Log the retrieved values
})
});
This approach allows you to retrieve the entered data from the form and process it after ensuring that all required fields are correctly filled out.
Summary
After gaining an understanding of how the Activator Helpers sys.jshelpers.sysRenderFieldForMultiLanguage
functions, it becomes much easier to implement clean and efficient code.
Suppose we have a language resource component that contains our translation
{
"keys": [
{
"name": "error",
"languages": [
{
"name": "french",
"value": "Erreur"
},
{
"name": "english",
"value": "Error"
}
]
},
{
"name": "something_went_wrong",
"languages": [
{
"name": "french",
"value": "Une erreur est survenue"
},
{
"name": "english",
"value": "Something went wrong"
}
]
},
{
"name": "this_field_is_required",
"languages": [
{
"name": "french",
"value": "Ce champ est obligatoire"
},
{
"name": "english",
"value": "This field is required"
}
]
},
{
"name": "in",
"languages": [
{
"name": "french",
"value": "dans"
},
{
"name": "english",
"value": "in"
}
]
},
{
"name": "title",
"languages": [
{
"name": "french",
"value": "Titre"
},
{
"name": "english",
"value": "Title"
}
]
},
{
"name": "enter_title",
"languages": [
{
"name": "french",
"value": "Entrer le titre"
},
{
"name": "english",
"value": "Enter The Title"
}
]
},
{
"name": "description",
"languages": [
{
"name": "french",
"value": "Description"
},
{
"name": "english",
"value": "Description"
}
]
},
{
"name": "enter_description",
"languages": [
{
"name": "french",
"value": "Entrer la description"
},
{
"name": "english",
"value": "Enter The Description"
}
]
},
{
"name": "submit",
"languages": [
{
"name": "french",
"value": "Envoyer"
},
{
"name": "english",
"value": "Submit"
}
]
}
]
}
Let’s integrate the translation of static texts into our final summary. Please refer to Language Ressources for more details.
// This time, we will use a Promise.all() because we are adding a new request before displaying our form.
Promise.all([
$activator.ui.jsmodules.load('sys.jshelpers.sysRenderFieldForMultiLanguage'),
$activator.ui.loadResource({source: 'activatord.languageresources.languageSourceDemo'}) // Add the request for our language resource if it has not yet been loaded into memory
]).then((results) => {
const helper = results[0]
/** Input Internationalization */
let param = { ...context }
param.formId = "save-jobPositionTypes-form" // The form id (HTML attribute value)
param.container = $('body')
/*
param.lang will contain the list of texts that can be displayed, please translate these values accordingly
*/
param.lang = {
error: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'error' }),
something_went_wrong: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'something_went_wrong' }),
this_field_is_required: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'this_field_is_required' }),
in: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'in' })
}
const InputFormLanguageHelper = new helper(param)
InputFormLanguageHelper.initialize()
.then(() => {
CONTAINER.html(`
<form id="save-jobPositionTypes-form">
<div class="row">
<div class="col-lg-12">
${InputFormLanguageHelper.render(
/** Input Internationalization */
{
id: "title", // The name and id of the input.
title: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'title' }), // The input label
placeholder: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'enter_title' }), // The input placeholder
type: "input", // The input type ['input' || 'textarea']
requiredMessage: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'this_field_is_required' })
},
true // If the field is required or not
/** End Input Internationalization */
)}
</div>
<div class="col-lg-12">
${InputFormLanguageHelper.render(
{
id: "description",
title: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'description' }),
placeholder: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'enter_description' }),
type: "textarea",
requiredMessage: $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'this_field_is_required' })
},
true
)}
</div>
<div class="col-lg-12">
<button type="button" class="btn btn-success" id="submit-btn">${$activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'submit' })}</button>
</div>
</div>
</form>
`);
// Loading default values in the form (in the case of an update)
if (item) {
/** Input Internationalization */
InputFormLanguageHelper.setValue(
[
{
id: "title",
field: "title"
},
{
id: "description",
field: "description"
}
],
item
)
/** End Input Internationalization */
}
// End loading
}).catch(error => {
toastr.error($activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'something_went_wrong' }), $activator.ui.resourceString({ source: 'activatord.languageresources.languageSourceDemo', key: 'error' }));
console.log(error)
}).finally(() => {
// For example, here you can hide the loader
})
/** End Input Internationalization */
})
Conclusion
Activator's database data translation functionality plays an important role in ensuring that an application's dynamic data is translated for various user groups. By enabling developers to manage translations efficiently, it ensures that data remains consistent and accessible, whatever the user's preferred language, enhancing the overall usability and international reach of the application.