Skip to content

Instantly share code, notes, and snippets.

@bitsmanent
Last active July 23, 2023 22:12
Show Gist options
  • Save bitsmanent/ee6eea3010021bc62d188739b42c86cd to your computer and use it in GitHub Desktop.
Save bitsmanent/ee6eea3010021bc62d188739b42c86cd to your computer and use it in GitHub Desktop.
Simple translations with parametrized strings and infinite plural forms
/* Do not use code you have not read first.
* Original file: https://gist.github.com/clamiax/ee6eea3010021bc62d188739b42c86cd */
let T9N_DEFLANG = null;
function _() {
if(!T9N_DEFLANG)
return "";
return t9n_format(T9N_DEFLANG, ...Array.from(arguments));
}
function t9n_use(lang) {
T9N_DEFLANG = lang;
}
function t9n_format(lang, label, ...argv) {
const node = lang.catalog[label];
const idx = lang.getpidx(argv[0]) || 0;
const fmt = typeof node == "object" && node[idx] ? node[idx] : node;
if(!fmt)
return label;
return t9n_printf(fmt, ...argv);
}
function t9n_printf(fmt, ...argv) {
let ret = "", len, i, ai;
for(i = 0, len = fmt.length; i < len; ++i) {
if(fmt[i] == '%') {
++i;
if(fmt[i] != '%') {
ai = "";
while(/\d/.test(fmt[i]))
ai += fmt[i++];
ret += ai !== "" ? argv[ai] : fmt[i-1];
--i;
continue;
}
}
ret += fmt[i];
}
return ret;
}
/* export the module (e.g. in React) */
//export {t9n_use,t9n_format,_}
@bitsmanent
Copy link
Author

bitsmanent commented Jan 21, 2020

React Native sample usage:

/* translations */
import {t9n_use,_} from "./src/t9n";
import it_IT from "./languages/it_IT";

global._ = _; /* t9n._ anywhere */

const Languages = [
        {name: "Italiano", locale: "it_IT", data: it_IT},
];

The file ./languages/it_IT.js is like the following:

export default {
        getpidx: (n) => n == 1 ? 0 : 1,
        catalog: {
                SLOGAN: "t9n rocks (it_IT)",
                /* ... */
        }
};

A getlocale implementation may looks like this:

import {NativeModules} from "react-native";

function getlocale() {
        let locid;

        if(Platform.OS == "ios") {
                locid = NativeModules.SettingsManager.settings.AppleLanguages[0];
                locid = locid.replace('-', '_'); /* always use the same format */
        }
        else
                locid = NativeModules.I18nManager.localeIdentifier;
        return locid;
}

Then at some point during startup (possibly before the first render, in App constructor):

/* set the App language */
const locale = getlocale();
const lang = Languages.find(x => x.locale == locale) || Languages[0];
t9n_use(lang.data);

This take the language from the OS locale. If language is not supported then take the first element from Languages. You may also want to check user preferences if any and force the specified language instead.

Now you can use the _ function to translate anything in the app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment