-
Notifications
You must be signed in to change notification settings - Fork 0
Translations
This feature adds support for translations in the framework, this comes in two key parts, the first is manual translation which works on calling (from any controller), this.translator.translate(sourceText, language)
, which will simply return the translated text or the source if nothing is found (a shortcut has been made for that which is this._t(sourceText, language)
). The second is automatic translation which is done by reading the string of data you return via either HTTP or WS, both of these plugins support translations, this works by checking for _t(Something)
in your content and it will read everything between the _t(
and )
and translate it. For WebSocket support, you need to do context.shouldTranslate(true)
and for HTTP, you need to do new Http.Response(200, {}).shouldTranslate(true)
this is because enabling it by default may affect the output code, depending on your data. I have detailed some more examples below.
Note: It's worth mentioning that by default, the translator module will automatically look at the Accept-Language header that is sent from the client, if you want to change this you can set the language yourself or if you have language based routes where the language is in the URL like:
https://example.com/en-GB/about
then you can create a middleware to automatically set the language, see the "Setting the Language" section below.
There is only a single option called translations
which should be the folder path for the translations, this MUST be defined for translations to work, otherwise translations will not be loaded, and all calls will just return the source text.
We expect the
translations
option to be an absolute path, we suggest using theresolve
method from thepath
built-on package.
In this example, our folders are stored in the project root under /translations
, this is because both the uncompiled dev mode and compiled prod mode will be able to access the same files.
import { Engine } from '@symbux/turbo';
import { resolve } from 'path';
const engine = new Engine({
autowire: true,
translations: resolve(__dirname, '../translations'),
});
As of the initial release, we only support JSON formats for languages, and we structure them like so:
// fr-FR.json
{
"Home": "Accueil",
"Our Work": "Notre travail",
"About Us": "À propos de nous",
"Contact Us": "Nous contacter",
"Get In Touch": "Entrer en contact"
}
Please note that ALL translation files in the translations folder should be named under the following format, for example,
fr-FR.json
for French/France.
The demo application in the main project has an example here.
If you wish to use translations in any of your controllers you can call on the translator module, which is, by default, injected to the abstract controller.
An example below for a controller using the HTTP plugin.
import { AbstractController, Http } from '@symbux/turbo';
@Http.Controller('/test')
export default class WsApiController extends AbstractController {
@Http.Get('/translate')
public async translate(context: Http.Context): Promise<Http.Response> {
const response1 = new Http.Response(200, {
message: this.translator.translate('Hello World', 'fr-FR'),
});
// OR
const response2 = new Http.Response(200, {
message: this._t('Hello World', 'fr-FR'),
});
}
}
An example below for a controller using the WS plugin.
import { AbstractController, Ws } from '@symbux/turbo';
@Ws.Controller('wsapi')
export default class WsApiController extends AbstractController {
@Ws.Action()
public async translate(context: Ws.Context): Promise<string> {
context.send({
command: 'wsapi/translate',
content: {
message: this.translator.translate('Home', 'fr-FR'),
},
});
// OR
context.send({
command: 'wsapi/translate',
content: {
message: this._t('Home', 'fr-FR'),
},
});
}
}
In some cases, your application may not utilise the Accept-Language header and you want something a custom instead. There are various ways to do this, by default, the Accept-Language header produces an array of supported languages, you can add a language by adding a new item at the front of that, as the translator module will loop through the languages and attempt to find a matching language you have on file.
So in this example we have a en-US language defined, but the user wants French, so you may have set some session information that says they want to use french, or it could be in your route, in the below example we are going to explore the "route" method.
We shall create a middleware first:
import { Middleware, Http, AbstractMiddleware } from '@symbux/turbo';
// Note the http part at the end, we are saying ALL http requests should use this.
@Middleware('http.lang', {}, 'http')
export default class LanguageReader extends AbstractMiddleware implements Http.IMiddleware {
public async handle(context: Http.Context): Promise<boolean> {
// Add base language (english).
context.setLanguage('en-US');
// Now let's check for a URL parameter, if none, we ignore.
const userLang = context.getParams()?.lang;
if (!userLang) return true;
// Enable auto translation.
context.shouldTranslate(true);
// Now we want to set it to the context.
context.setLanguage(userLang);
return true;
}
}
Now that the above has been done, all HTTP routes will now use the language set in the URL, but if there is no language defined in the params, it will fall back to en-US rather than the user's accept-language header.
- Controllers
- Middleware
- Autowire
- Plugins
- Tasks
- Fibres
- Authentication
- Registry
- Services
- Dependecy Injection
- Translations (i18n)
- Safe Quit
- Exception Handling
- Event Listener
- Custom Logger
- HTTP Plugin - Built-In
- WS Plugin - Built-In
- Discord Plugin - External
- Vite Plugin - External
- Inspect Plugin - External
- CLI Plugin - External
- Got an issue? Join our Discord
- Need your own plugin? Contact Me
- Have an idea? Let's Discuss
- Want to support me? Buy me a coffee