Skip to content

Commit

Permalink
Merge pull request #12 from apache-superset/kristw--translation
Browse files Browse the repository at this point in the history
Add @superset-ui/translation
  • Loading branch information
kristw authored and zhaoyongjie committed Nov 26, 2021
1 parent e0c71f0 commit e2c83f9
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## `@superset-ui/translation`

[![Version](https://img.shields.io/npm/v/@superset-ui/translation.svg?style=flat)](https://img.shields.io/npm/v/@superset-ui/translation.svg?style=flat)

`i18n` locales and translation for Superset

### SupersetTranslation

#### Example usage

```js
import { configure, t } from '@superset-ui/translation';

configure({
languagePack: {...},
});

console.log(t('text to be translated'));
```

#### API

`configure({ [languagePack] })`

- Initialize the translator
- Initialize with the default language if no `languagePack` is specified.

`t(text[, args])`

- Translate `text` when no `args` is provided.
- Translate `text` and substitute `args` into the placeholders specified within `text`.

For example

```js
t('Hello %(name)s', user)
```

See [sprintf-js](https://github.com/alexei/sprintf.js) for more details on how to define placeholders.

### Development

`@data-ui/build-config` is used to manage the build configuration for this package including babel
builds, jest testing, eslint, and prettier.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "@superset-ui/translation",
"version": "0.0.0",
"description": "Superset UI translation",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"files": [
"esm",
"lib"
],
"scripts": {
"build:cjs": "beemo babel ./src --out-dir lib/ --minify",
"build:esm": "beemo babel ./src --out-dir esm/ --esm --minify",
"build": "yarn run build:cjs && yarn run build:esm",
"dev": "beemo babel --watch ./src --out-dir esm/ --esm",
"jest": "beemo jest --color --coverage",
"eslint": "beemo eslint \"./{src,test}/**/*.{js,jsx,json,md}\"",
"lint": "yarn run prettier && yarn run eslint",
"lint:fix": "yarn run prettier --write && yarn run eslint --fix",
"test": "yarn run jest",
"prettier": "beemo prettier \"./{src,test}/**/*.{js,jsx,json,md}\"",
"prepublish": "yarn run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"keywords": [
"superset",
"client",
"translation"
],
"author": "Superset",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"devDependencies": {
"@data-ui/build-config": "^0.0.23"
},
"dependencies": {
"@babel/runtime": "^7.1.2",
"jed": "^1.1.1",
"sprintf-js": "^1.1.1"
},
"beemo": {
"module": "@data-ui/build-config",
"drivers": [
"babel",
"eslint",
{
"driver": "jest",
"env": {
"NODE_ENV": "test"
}
},
"prettier"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Jed from 'jed';
import { sprintf } from 'sprintf-js';

const DEFAULT_LANGUAGE_PACK = {
domain: 'superset',
locale_data: {
superset: {
'': {
domain: 'superset',
lang: 'en',
plural_forms: 'nplurals=1; plural=0',
},
},
},
};

export default class Translator {
constructor({ languagePack = DEFAULT_LANGUAGE_PACK } = {}) {
this.i18n = new Jed(languagePack);
}

translate(input, ...args) {
if (input === null || input === undefined) {
return input;
}
const text = this.i18n.gettext(input);
return (args.length > 0) ? sprintf(text, ...args) : text;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Translator from './Translator';

let singleton;

function configure(config) {
singleton = new Translator(config);
return singleton;
};

function getInstance() {
if (!singleton) {
throw new Error('You must call configure(...) before calling other methods');
}
return singleton;
}

function t(...args) {
return getInstance().translate(...args);
}

export { configure, t };
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { configure, t } from './TranslatorSingleton';
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Translator from '../src/Translator';
import languagePackZh from './languagePacks/zh.json';

describe('Translator', () => {
it('exists', () => {
expect(Translator).toBeDefined();
});
describe('new Translator(config)', () => {
it('initializes when config is not specified', () => {
expect(new Translator()).toBeInstanceOf(Translator);
});
it('initializes when config is an empty object', () => {
expect(new Translator({})).toBeInstanceOf(Translator);
});
it('initializes when config is specified', () => {
expect(new Translator({
languagePack: languagePackZh,
})).toBeInstanceOf(Translator);
});
});
describe('.translate(input, ...args)', () => {
const translator = new Translator({
languagePack: languagePackZh,
});
it('returns null for null input', () => {
expect(translator.translate(null)).toBeNull();
});
it('returns undefined for undefined input', () => {
expect(translator.translate(undefined)).toBeUndefined();
});
it('translates simple text', () => {
expect(translator.translate('second')).toEqual('秒');
});
it('translates template text with arguments', () => {
expect(translator.translate('Copy of %s', 1)).toEqual('1 的副本');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Translator from '../src/Translator';
import { configure, t } from '../src/TranslatorSingleton';
import languagePackZh from './languagePacks/zh.json';

describe('TranslatorSingleton', () => {
describe('before configure()', () => {
describe('t()', () => {
it('throws error', () => {
expect(() => t('second')).toThrow();
});
});
});
describe('after configure()', () => {
describe('configure()', () => {
it('creates and returns a translator', () => {
expect(configure()).toBeInstanceOf(Translator);
});
});
describe('t()', () => {
it('after configure() returns translated text', () => {
configure({
languagePack: languagePackZh,
});
expect(t('second')).toEqual('秒');
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { configure, t } from '../src/index';

describe('index', () => {
it('exports configure()', () => {
expect(configure).toBeDefined();
expect(configure).toBeInstanceOf(Function);
});
it('exports t()', () => {
expect(t).toBeDefined();
expect(t).toBeInstanceOf(Function);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"domain": "superset",
"locale_data": {
"superset": {
"": {
"domain": "superset",
"plural_forms": "nplurals=2; plural=(n != 1)",
"lang": "en"
},
"second": [""],
"Copy of %s": [""]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"domain": "superset",
"locale_data": {
"superset": {
"": {
"domain": "superset",
"plural_forms": "nplurals=1; plural=0",
"lang": "zh"
},
"second": [""],
"Copy of %s": ["%s 的副本"]
}
}
}

0 comments on commit e2c83f9

Please sign in to comment.