2.0.1 • Published 1 year ago

tiny-trans v2.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

tiny-trans - lib for localisation

Simple translate manager with supporting of dynamic imports, variables and plural. You can use a lib for react applications react-tiny-trans

Install

npm i tiny-trans
// or
yarn add tiny-trans 

Usage

You can use different files for translates. Below I use follow example files

lang_ru.json

{
  "screens": {
    "Home": {
      "title": "Заголовок",
      "description": "Описание ${desc} ${name}",
      "plural": {
        "zero": "${COUNT} бананов",
        "one": "${COUNT} банан",
        "two": "${COUNT} банана",
        "few": "${COUNT} банана",
        "many": "${COUNT} бананов",
        "other": "${COUNT} бананов"
      }
    }
  }
  "extrapoint": {
    "anything": "Что-нибудь"
  }
}

lang_en.json

{
  "screens": {
    "Home": {
      "title": "Title",
      "description": "Description ${desc} ${name}",
      "plural": {
        "zero": "${COUNT} bananas",
        "one": "${COUNT} banane",
        "two": "${COUNT} bananas",
        "few": "${COUNT} bananas",
        "many": "${COUNT} bananas",
        "other": "${COUNT} bananas"
      }
    }
  }
  "extrapoint": {
    "anything": "Anything"
  }
}

Creating

You should pass the translations and the starting locale to the init method. You can also explicitly specify possible locales by passing Locale type when creating a Trans instance

import ru from './lang_ru.json';
import en from './lang_en.json';

enum Locale {
  ru = 'ru',
  en = 'en',
}

const trans = new Trans<Locale>({
  translations: { ru, en },
  locale: Locale.en,
});
await trans.init();

Creating with dynamic imports

Files of translates will dynamic download. See webpack code-splitting

enum Locale {
  ru = 'ru',
  en = 'en',
}

const trans = new Trans<Locale>({
  translations: { 
    ru: () => new Promise((resolve) => import('./lang_ru.json').then((res) => resolve(res.default))), 
    en: () => new Promise((resolve) => import('./lang_en.json').then((res) => resolve(res.default))), 
  },
  locale: Locale.en,
});
await trans.init();

or you can use fetch for dynamic download

enum Locale {
  ru = 'ru',
  en = 'en',
}

const trans = new Trans<Locale>({
  translations: { 
    ru: async () => await fetch('url_of_my_translate_ru.json'), 
    en: async () => await fetch('url_of_my_translate_en.json'), 
  },
  locale: Locale.en,
});
await trans.init();

Creating with custom pluralization

You can pass the custom plural functions.

Note: under hood it uses Intl.PluralRules(locale).select(count), but it does not support in IE. You can pass in the init method own plural functions object.

import ru from './lang_ru.json';
import en from './lang_en.json';

enum Locale { ru = 'ru', en = 'en', }

const trans = new Trans({ translations: { ru, en }, locale: Locale.en, pluralRecord: { ru: (count: number, locale: string) => "zero" | "one" | "two" | "few" | "many" | "other", en: (count: number, locale: string) => "zero" | "one" | "two" | "few" | "many" | "other" } }); await trans.init();

### Translate
You can write in different ways:

// case 1 const translate = trans.createTranslatescreens; translateHome.title; // en -> Title; ru -> Заголовок

// case 2 const translate = trans.createTranslatescreens.Home; translatetitle; // en -> Title; ru -> Заголовок

// case 3 const translate = trans.createTranslatescreens.Home.title; translate; // en -> Title; ru -> Заголовок

// case 4 const translate = trans.createTranslate; translatescreens.Home.title; // en -> Title; ru -> Заголовок

> **Note:** createTranslate and translate take a TemplateStringsArray or a string as first param.

createTranslatesome // it works createTranslate('some') // it works too createTranslate'some' // it does not work!

translatesome // it works translate('some') // it works too translate'some' // it does not work!

### Translate with variables

const translate = trans.createTranslatescreens.Home; translate('description', { variables: { desc: "Any", name: "Name" } }); // en -> Description Any Name; ru -> Описание Any Name

### Translate with plural

const translate = trans.createTranslatescreens.Home; translate('plural', { count: 3 }); // en -> 3 bananas; ru -> 3 банана

> **Note:** _COUNT_ is reserved name. Don't name your variables so.

translate('description', { variables: { COUNT: "you data" } }) // bad

### Translate with few points
In any translation function, you can write the full path, and this works even if a different root path is passed to `createTranslate`

const translate = trans.createTranslatescreens; translateHome.title // en -> Title; ru -> Заголовок
translateextrapoint.anything // en -> Anything; ru -> Что-нибудь

### Error handing
Sometimes we mistake in translate files, and we need see it

const translate = trans.createTranslatescreens.Home; translateplural // throw "invalid translate! result: "object Object"; result as a json: {"zero":"zero bananas","one":"one banane","two":"two bananas","few":"${COUNT} bananas","many":"${COUNT} bananas","other":"${COUNT} bananas"}; rootResult: "undefined"; rootResult as a json: undefined. full path: "screens.Home.plural"; translate path: "plural";"

Also you can ignore error:

const translate = trans.createTranslatescreens.Home; translate(plural, { errorsMode: 'ignore' }) // returns ''

Or you can handle error:

const translate = trans.createTranslatescreens.Home; translate(plural, { errorsMode: (error: TransError) => 'handle error' }) // returns 'handle error'

## API
### Methods
#### constructor

type PluralFn = (count: number, locale: string) => "zero" | "one" | "two" | "few" | "many" | "other";

constructor(params: { /**

  • for example: { ru: { test: 'тест' }, en: { test: 'test' } } */ translations: Record<Locale, unknown>; /**
  • string */ locale: Locale; /**
  • If you want you can pass custom plural hanlders */ pluralRecord?: Record<Locale, PluralFn>; })
#### init
Download dynamic files

init(): Promise

#### changeLocale

changeLocale(locale: Locale): Promise

#### createTranslate

createTranslate(module: string | TemplateStringsArray): Translate

#### translate

type Variables = Record<string, string>; type ErrorsMode = 'ignore' | 'throw' | 'console' | ((error: TransError) => string);

type TranslateOptions = { /**

  • ignore the error, handle error, show in the console or throw error (throw by default)
  • */ errorsMode?: ErrorsMode; /**
  • it uses for the plural if it exists
  • */ count?: number; /**
  • for replaced the variable patters - ${variable}
  • */ variables?: T; };

type Translate = ( path: string | TemplateStringsArray, options?: TranslateOptions ) => string;

### Events

You can listen trans events. They will be helpful for creating a lib for any frameworks
* `loadstart` Triggered before only dynamic importing
* `loadend` Triggered after only dynamic importing
* `change-locale` Triggered every time by `changeLocale` method but after `loadend`. It takes a `locale` as a first argument
* `init` Triggered single time in the end by `init` method. It takes a `locale` as a first argument

// To add trans.addEventListener('loadstart', () => void); trans.addEventListener('loadend', () => void); trans.addEventListener('change-locale', (locale: string) => void); trans.addEventListener('init', (locale: string) => void);

// To remove trans.removeEventListener('loadstart', () => void); trans.removeEventListener('loadend', () => void); trans.removeEventListener('change-locale', (locale: string) => void); trans.removeEventListener('init', (locale: string) => void);

2.0.1

1 year ago

2.0.0

1 year ago

2.0.0-doc

1 year ago

2.0.0-doc-1

1 year ago

2.0.0-doc-2

1 year ago

1.1.15

1 year ago

1.1.14

1 year ago

1.1.12

3 years ago

1.1.13

3 years ago

1.1.9

3 years ago

1.1.8

3 years ago

1.1.7

3 years ago

1.1.11

3 years ago

1.1.10

3 years ago

1.1.6

3 years ago

1.1.5

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.9

3 years ago

1.1.4

3 years ago

1.1.3

3 years ago

1.1.2

3 years ago

1.0.11

3 years ago

1.0.10

3 years ago

1.0.13

3 years ago

1.0.12

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago