README
Translation Transformer
Purpose
Liferay.Language.get(...)
request
Deprecation of Due to technical limitations starting with Liferay 7.3, a vital functionality for querying translations in the frontend has been deprecated and removed. Read more about this here: https://issues.liferay.com/browse/LPS-123191
The language filter and its problems
The now missing functionality has been replaced with the language filter. It replaces on server side all the
Liferay.Language.get(...)
appearances in the .js
files with its corresponding translation.
This leads to multiple problems. The biggest of them: Dynamic Keys.
Dynamic Keys
Let's say we have the following code.
const key = 'language-key'
const translation = Liferay.Language.get(key)
// translation = 'language-key'
The language filter would not be able to replace the Liferay.Language.get(key)
because on server side the language
filter doesn't run any of the JavaScript code. This is a problem because dynamic keys are, in most cases, vital to the
functionality of the application and mostly can't be replaced by hard coded keys.
Solution
Get all language property keys from the language.properties
files and add them to a JavaScript object.
Language.properties
language-key=Translation Value
translations.js
export default {
'language-key': Liferay.Language.get('language-key')
}
On server side, the language filter is now able to replace the Liferay.Language.get('language-key')
with its
corresponding translation.
Now we can get any translation, even with dynamic keys:
import translations from 'translations'
const key = 'language-key'
const translation = translations[key]
// translation = 'Translation Value'
Usage
The package contains a command line interface as well as an exported class called TranslationService
.
CLI
The command line interface is there to get all the language keys and create the translations.js
file. It has to be
configured either inside the package.json
file or in an external configuration file called translation.config.js
.
Configuration
translation.config.js
If you want, you can use a dedicated configuration file in the JavaScript format, instead of directly configuring the
script inside the package.json
. This allows to have for example the keys in a dedicated file. It has to export a
JavaScript object in the common js format.
// translation.config.js
const keys = require('./keys')
module.exports = {
location: 'path/to/wan...',
properties: [
'path/to...'
],
keys,
typescript: true
}
// keys.js
module.exports [
'additional-key-1',
'additional-key-2'
]
If the configuration file exists on the same level as the package.json
, it will be used automatically. If not, you
will have to pass the path to the configuration file with its name as parameter with the call of the cli as you can see
in the following example:
translation-transformer -c /path/to/config/translation-customname.config.js
package.json
If you don't use a dedicated configuration file, you need a block with the name translation
. The block should contain
configurations according to the following example.
{
"translation": {
"location": "path/to/wanted/directory/where/translations.js/will/be/located",
"properties": [
"path/to/language/properties/files/directory",
"path/to/other/language/properties/files/directory"
],
"keys": [
"additional-key-1",
"additional-key-2"
],
"typescript": true
}
}
Run
Inside the package.json
file, you need to have a new script
entry which calls the cli.
{
"scripts": {
"translate": "translation-transformer"
}
}
If you then run npm run translate
, the CLI will try to get all language keys out of the found property files, and the
additionally defined keys and creates a new file to the defined location
.
TranslationService
After creating the translations.js
with the CLI, the preferred way to use the object with all the translations in it
is the TranslationService
class.
// generated translations.js file
import translations from '../translations'
import TranslationService from '@clavis/translation-transformer'
// pass the translations object to the constructor of the TranslationService class
const translationService = new TranslationService(translations)
// now you can use the translate method on the translationService
// the api for the translate method is exactly the same as for the Liferay.Language.get method.
const translation = translationService.translate('language-key')
// if the value of the translation contains placeholders like `{0}` you can pass params as following
const translationWithParams = translationService.translate('language-key-placeholder', ['Content'])