@kwaeri/i18n
Version:
The internationalization component module of the @kwaeri platform.
211 lines (142 loc) • 14 kB
Markdown
# [](https://patreon.com/kirvedx) kwaeri-i18n [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YUW4CWCAABCU2)
A Massively Modified Open Source Project by kirvedx
[](https://keybase.io/rik)
[](https://developers.google.com/profile/u/117028112450485835638)
[](https://github.com/kirvedx)
[](https://github.com/kirvedx)
[](https://npmjs.com/~rik)
kwaeri/i18n is the internationalization component module for the kwaeri application platform
[](https://gitlab.com/kwaeri/i18n/commits/master) [](https://kwaeri.gitlab.io/i18n/coverage/) [](https://bestpractices.coreinfrastructure.org/projects/1879)
## TOC
* [The Implementation](#the-implementation)
* [Getting Started](#getting-started)
* [Installation](#installation)
* [Usage](#usage)
* [Search Order](#search-order)
* [Placeholders](#placeholders)
* [How to Contribute Code](#how-to-contribute-code)
* [Other Ways to Contribute](#other-ways-to-contribute)
* [Bug Reports](#bug-reports)
* [Vulnerability Reports](#vulnerability-reports)
* [Confidential Issues](#confidential-issues)
* [Donations](#donations)
## The Implementation
The i18n component provides internationalization for end users of @kwaeri/cli and the @kwaeri platform in general [kue].
## Getting Started
**NOTE**
@kwaeri/i18n is not ready for production. We've published this module for testing and development purposes. You're free to try out anything that may already be available, but please be aware that there is likely to be many aspects of the platform which are not working and/or are completely broken. As we near completion of the new platform, we'll update documentation and provide complete examples and tutorials for getting started.
### Installation
[@kwaeri/node-kit](https://www.npmjs.com/package/@kwaeri/node-kit) wraps the various components under the kwaeri scope, and provides a single entry point to the node-kit platform for easing the process of building a kwaeri application.
[@kwaeri/cli](https://www.npmjs.com/package/@kwaeri/cli) wraps the various CLI components under the @kwaeri scope, and provides a single entry point to the user executable framework.
However, if you wish to use @kwaeri/i18n - perform the following steps:
Install @kwaeri/i18n:
```bash
npm install @kwaeri/i18n
```
### Usage
The i18n component can be used for internationalization with or without the kwaeri platform.
To leverage the i18n component, you'll first need to include it:
```typescript
// INCLUDES
import { i18n } from '@kwaeri/i18n';..
```
Next, you'll need to provide the locales you wish to support through infrastructure:
```
⇨ MyProject
⇨ ⇨ package.json, *.ts, etc
⇨ ⇨ _locales
⇨ ⇨ ⇨ en
⇨ ⇨ ⇨ ⇨ messages.json
⇨ ⇨ ⇨ en_GB
⇨ ⇨ ⇨ ⇨ messages.json
⇨ ⇨ ⇨ de_DE
⇨ ⇨ ⇨ ⇨ messages.json
```
The `messages.json` file is where you provide the content for the locale in question. Only the variable name and `content` properties and values are required:
```json
{
"messageName": {
"content": "This is an example message"
}
}
```
You can make a call to `i18n.getMessage( messageName: string, ...placeholderValues?: string[] ): string` anywhere you need to support internationalization:
```typescript
console.log( i18n.getMessage( "messageName" ) );
```
#### Search Order
Where the translation is taken from is currently determined by the following logic:
1. A `package.json` file is read, if available, and a property named `default_locale` searched for. If found, it's value is configured as the default locale. If `default_locale` was not provided a fallback value of "en" is substituted.
2. When `new i18n(...)` is called, any locales provided are configured as additional locales.
3. When `i18n.init()` is called, an attempt to read in all locales configured - as a compliment to, and including, the default - is made. If successful the locales are mapped.
There are two methods which can be used for fetching localised messages:
* **4(a)** `getMessage( name: string, ...placeholders: any[] ): string` retrieves localised messages according to the configured locale.
1. The default locale, if available, is searched first.
2. If the default locale was a derived locale, such as `en_US`, and the message was not found - the related base locale is then searched (i.e. `en` ), if available.
3. If no value is found an empty string is returned.
* **4(b)** `getLocalisedMessage( name: string, locale: string, ...placeholders: any[] ): string` retrieves a specific localisation.
1. The specified locale, if available, is searched first.
2. If the specified locale was a derived locale, such as `en_US`, and the message was not found - its related base locale is then searched (i.e. `en`), if available.
3. If the message is not found in the related base locale, then the default locale is searched, if available.
4. If the default locale was a derived locale, and the message was not found - the related base locale is then searched, if available.
5. If no value is found, an empty string is returned.
#### Placeholders
Template content - or content you want printed within a message as part of a message template, are known as placeholders - and can be passed in as additional arguments to `getMessage()` or `getLocalisedMessage()`.
The signature of the *getMessage* methods shows `...placeholders: any[]` in their respective argument position(s). Please do not mistake that for an array as the argument type. All arguments in JavaScript are accessible within a function body via the `arguments` built-in; You can access any passed arguments - including any extra, non-named, arguments that were passed - via `arguments[x]`; where `x` is the position of the argument with regards to the order in which it was passed to the functions invocation.
In Typescript, we can denote that all extra arguments will be received under a specific name by using the rest spread syntax (i.e. `...placeholders: any[]`). This, in fact, names the remaining arguments, and packs them into a nested array in its respective position - but it's nifty for minimizing syntax for the callers of our methods.
With that said, you can pass the placeholders values in the order they should appear within the message template as individual arguments:
```typescript
// We can get intricate if we want:
try {
// Some error creating code:
throw new Error( `ASSERTION_ERROR: ${i18n.getMessage( "assertionError", "Some untranslated text", `${new Error().lineNumber}` )}` );
}
catch( exception ) {
DEBUG( ( exception as Error ).message );
}
```
To leverage placeholders - or template parameters, follow a two-part process for defining them:
1. Template them by name in a message's content by surrounding their name with the dollar sign `$` character at their position within the message.
2. Define their value within the `placeholders` object for any message, by creating a sub-property that's named respectively whos value is of object type. Within that specific placeholder's object define a `content` sub-property that indicates its position within the message template and which placeholder argument - when provided in a `getMessage()` or `getLocalisedMessage()` invocation - is the argument that should replace it, by specifying a positional template parameter (i.e. `$1`) as its value.
Things to note:
* Placeholders are not defined in order, but are supplied in order; Logic exists to break the placeholder processing loop when as many placeholders have been replaced as values for placeholders have been provided.
* Any placeholder that is not provided a value in a `getMessage()` or `geLocalisedMessage()` invocation is left as-is within the message template.
* Additional placeholders are ignored.
* A maximum of 8 placeholders are supported per message.
This behavior is intended to keep things consistent with other implementations - such as [Chrome's i18n implementation](https://developer.chrome.com/docs/extensions/reference/i18n/).
```json
{
"assertionError": {
"content": "ASSERTION_ERROR: $details$",
"description": "A description to help translators understand the purpose and use of the translatable message",
"placeholders": {
"details": {
"content": "$1",
"example": "A string and number cannot be loosely asserted as equal in value without first being converted to the same type."
}
}
}
}
```
To be continued...
## How to Contribute Code
Our Open Source projects are always open to contribution. If you'd like to cocntribute, all we ask is that you follow the guidelines for contributions, which can be found at the [Massively Modified Wiki](https://gitlab.com/mmod/documentation/wikis/Contribute-to-Massively-Modified/Contribute-Code)
There you'll find topics such as the guidelines for contributions; step-by-step walk-throughs for getting set up, [Coding Standards](https://gitlab.com/mmod/documentation/wikis/Contribute-to-Massively-Modified/Coding-Standards), [CSS Naming Conventions](https://gitlab.com/mmod/documentation/wikis/Contribute-to-Massively-Modified/CSS-Naming-Conventions), and more.
## Other Ways to Contribute
There are other ways to contribute to the project other than with code. Consider [testing](https://gitlab.com/mmod/documentation/wikis/Contribute-to-Massively-Modified/Test-Code) the software, or in case you've found an [Bug](https://gitlab.com/mmod/documentation/wikis/Other-Ways-to-Contribute/Bug-Reports) - please report it. You can also support the project monetarly through [donations](https://gitlab.com/mmod/documentation/wikis/Contribute-to-Massively-Modified/Donations) via PayPal.
Regardless of how you'd like to contribute, you can also find in-depth information for how to do so at the [Massively Modified Wiki](https://gitlab.com/mmod/documentation/wikis/Other-Ways-to-Contribute)
### Bug Reports
To submit bug reports, request enhancements, and/or new features - please make use of the **issues** system baked-in to our source control project space at [Gitlab](https://gitlab.com/groups/kwaeri/node-kit/-/issues)
You may optionally start an issue, track, and manage it via email by sending an email to our project's [Service Desk](mailto:incoming+kwaeri-i18n-21483883-issue-@incoming.gitlab.com).
For more in-depth documentation on the process of submitting bug reports, please visit the [Massively Modified Wiki on Bug Reports](https://gitlab.com/mmod/documentation/wikis/Other-Ways-to-Contribute/Bug-Reports)
### Vulnerability Reports
Our Vulnerability Reporting process is very similar to Gitlab's. In fact, you could say its a *fork*.
To submit vulnerability reports, please email our [Security Group](mailto:security@mmod.co). We will try to acknowledge receipt of said vulnerability by the next business day, and to also provide regular updates about our progress. If you are curious about the status of your report feel free to email us again. If you wish to encrypt your disclosure email, like with gitlab - please email us to ask for our GPG Key.
Please refrain from requesting compensation for reporting vulnerabilities. We will publicly acknowledge your responsible disclosure, if you request us to do so. We will also try to make the confidential issue public after the vulnerability is announced.
You are not allowed, and will not be able, to search for vulnerabilities on Gitlab.com. As our software is open source, you may download a copy of the source and test against that.
#### Confidential Issues
When a vulnerability is discovered, we create a [confidential issue] to track it internally. Security patches will be pushed to private branches and eventually merged into a `security` branch. Security issues that are not vulnerabilites can be seen on our [public issue tracker](https://gitlab.com/groups/kwaeri/node-kit/-/issues?scope=all&utf8=✓&state=opened&label_name[]=Security).
For more in-depth information regarding vulnerability reports, confidentiality, and our practices; Please visit the [Massively Modified Wiki on Vulnerability](https://gitlab.com/mmod/documentation/wikis/Other-Ways-to-Contribute/Vulnerability-Reports)
### Donations
If you cannot contribute time or energy to neither the code base, documentation, nor community support; please consider making a monetary contribution which is extremely useful for maintaining the Massively Modified network and all the goodies offered free to the public.
[](https://patreon.com/kirvedx) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YUW4CWCAABCU2) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YUW4CWCAABCU2)