Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/kevinresol/turnwing

Type safe & hackable localization library for Haxe
https://github.com/kevinresol/turnwing

haxe localization

Last synced: 29 days ago
JSON representation

Type safe & hackable localization library for Haxe

Awesome Lists containing this project

README

        

# turnwing

Hackable localization library for Haxe

## What?

### Type safety

Translations are done with interfaces. You will never mis-spell the translation key anymore.

In many existing localization libraries, the translation function looks like this:

```haxe
loc.translate('hello', {name: 'World'});
loc.translate('orange', {number: 1});
```

There is one and only one translation function and its type is `String->Dynamic->String`.
That means it takes a String key, a Dynamic parameter object and returns a substituted string.
Several things can go wrong here: wrong translation key, wrong param name or wrong param data type.

With turnwing, we have typed translators.
Each of them is a user-defined function and typed specifically.

```haxe
loc.hello('World'); // String->String
loc.orange(1); // Int->String
```

### Peace of mind

There is only one place where errors could happen, that is when the localization data is loaded.

This is because data are validated when they are loaded. The data provider does all the heavy lifting to make sure the loaded data includes all the needed translation keys and values. As a result, there is no chance for actual translation calls to fail.

### Hackable

Users can plug in different implementations at various part of the library.

For example, `JsonProvider` uses JSON as the underlying localization format.
One can easily write a `XmlProvider` (perhaps with tink_xml).

Also, an `ErazorTemplate` may replace the default `HaxeTemplate` implementation.

## Usage

```haxe
import turnwing.*;
import turnwing.provider.*;
import turnwing.template.*;

interface MyLocale {
function hello(name:String):String;
function orange(number:Int):String;
var sub(get, never):SubLocale;
}

interface SubLocale {
function yo():String;
}

class Main {
static function main() {
var source = new ResourceStringSource(lang -> '$lang.json');
var template = new HaxeTemplate();
var loc = new Manager(new JsonProvider(source, template));
loc.get('en').handle(function(o) switch o {
case Success(localizer):
// data prepared, we can now translate something
$type(localizer); // MyLocale
trace(localizer.hello('World')); // "Hello, World!"
trace(localizer.orange(4)); // "There are 4 orange(s)!"
case Failure(e):
// something went wrong when fetching the localization data
trace(e);
});
}
}

// and your json data looks like this:
{
"hello": "Hello, ::name::!",
"orange": "There are ::number:: orange(s)!",
"sub": {
"yo": "Yo!"
}
}
```

## Providers

#### JsonProvider

`JsonProvider` is a provider for JSON sources.
Its data validation is powered by `tink_json`,
which generates the validation code with macro at compile time
according to the type information of the user-defined locale interface.

Requires a templating engine to interpolate the parameters.
The interface is defined in `Template.hx`.
`HaxeTemplate` is an implementation based on `haxe.Template` from the Haxe standard library.

Usage:

```haxe
var source = new ResourceStringSource(lang -> '$lang.json');
var template = new HaxeTemplate();
var provider = new JsonProvider(source, template);
```

To use it, install `tink_json` and include it as dependency in your project

#### FluentProvider (JS Only)

`FluentProvider` is a provider for [Fluent](https://projectfluent.org/).

Messages in the FTL file should be named the same as the Locale interface functions.
Nested interfaces should be delimited by a dash (`-`).
Please refer to the files in the `tests/data/ftl` folder as an example.

At the moment, the validation logic is incomplete and only performs a very rough check.
So, runtime error _may_ occur in a locale function call. This will be improved in the future.

Usage:

```haxe
var source = new ResourceStringSource(lang -> '$lang.ftl');
var provider = new FluentProvider(source);
```

To use it, you have to install the npm package `@fluent/bundle`