@kwaeri/i18n
v0.3.1
Published
The internationalization component module of the @kwaeri platform.
Downloads
6
Maintainers
Readme
kwaeri-i18n
A Massively Modified Open Source Project by kirvedx
kwaeri/i18n is the internationalization component module for the kwaeri application platform
TOC
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 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 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:
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:
// 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:
{
"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:
console.log( i18n.getMessage( "messageName" ) );
Search Order
Where the translation is taken from is currently determined by the following logic:
- A
package.json
file is read, if available, and a property nameddefault_locale
searched for. If found, it's value is configured as the default locale. Ifdefault_locale
was not provided a fallback value of "en" is substituted. - When
new i18n(...)
is called, any locales provided are configured as additional locales. - 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.- The default locale, if available, is searched first.
- 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. - If no value is found an empty string is returned.
4(b)
getLocalisedMessage( name: string, locale: string, ...placeholders: any[] ): string
retrieves a specific localisation.- The specified locale, if available, is searched first.
- 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. - If the message is not found in the related base locale, then the default locale is searched, if available.
- If the default locale was a derived locale, and the message was not found - the related base locale is then searched, if available.
- 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:
// 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:
- Template them by name in a message's content by surrounding their name with the dollar sign
$
character at their position within the message. - 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 acontent
sub-property that indicates its position within the message template and which placeholder argument - when provided in agetMessage()
orgetLocalisedMessage()
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()
orgeLocalisedMessage()
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.
{
"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
There you'll find topics such as the guidelines for contributions; step-by-step walk-throughs for getting set up, Coding Standards, CSS Naming Conventions, and more.
Other Ways to Contribute
There are other ways to contribute to the project other than with code. Consider testing the software, or in case you've found an Bug - please report it. You can also support the project monetarly through 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
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
You may optionally start an issue, track, and manage it via email by sending an email to our project's Service Desk.
For more in-depth documentation on the process of submitting bug reports, please visit the Massively Modified Wiki on 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. 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.
For more in-depth information regarding vulnerability reports, confidentiality, and our practices; Please visit the Massively Modified Wiki on Vulnerability
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.