Skip to content

Commit

Permalink
Adding function to parse language for ICU to address #35 (#63)
Browse files Browse the repository at this point in the history
* Adding function to parse language for ICU

* Adding missing semicolon
  • Loading branch information
karoun authored Apr 3, 2023
1 parent 6d65e18 commit 9615bc9
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ i18next.use(ICU).init(i18nextOptions);

// Will be run when parser throws an error. Can return any string, which can be used as a fallback, in case of broken translation.
// If omitted, the default swallows the error and returns the unsubstituted string (res)
parseErrorHandler: (err, key, res, options) => {}
parseErrorHandler: (err, key, res, options) => {},

// Transform the language code prior to ICU locale parsing, useful for supporting psuedo-locales like en-ZZ
// If omitted, the default leaves the language code as is
parseLngForICU: (lng) => lng,
}
```

Expand Down
3 changes: 2 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ declare module "i18next-icu" {
bindI18n?: string;
bindI18nStore?: string;
parseErrorHandler?: (err: Error, key: string, res: string, options: Object) => string;
parseLngForICU?: (lng: string) => string;
}

export interface IcuInstance<TOptions = IcuConfig> extends ThirdPartyModule {
Expand All @@ -34,7 +35,7 @@ declare module "i18next-icu" {
}

interface IcuConstructor {
new (config?: IcuConfig): IcuInstance;
new(config?: IcuConfig): IcuInstance;
type: "i18nFormat";
}

Expand Down
18 changes: 11 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ function getDefaults() {
memoizeFallback: false,
bindI18n: '',
bindI18nStore: '',
parseErrorHandler: (err, key, res, options) => {
return res
}
parseErrorHandler: (err, key, res, options) => {
return res;
},
parseLngForICU: (lng) => {
return lng;
},
};
}

Expand All @@ -27,7 +30,7 @@ class ICU {
this.formats = this.options.formats;

if (i18next) {
const { bindI18n, bindI18nStore, memoize } = this.options;
const { bindI18n, bindI18nStore, memoize } = this.options;

i18next.IntlMessageFormat = IntlMessageFormat;
i18next.ICU = this;
Expand All @@ -36,7 +39,7 @@ class ICU {
if (bindI18n) {
i18next.on(bindI18n, () => this.clearCache())
}

if (bindI18nStore) {
i18next.store.on(bindI18nStore, () => this.clearCache())
}
Expand All @@ -59,17 +62,18 @@ class ICU {

try {
if (!fc) {
const transformedLng = this.options.parseLngForICU(lng);
// without ignoreTag, react-i18next <Trans> translations with <0></0> placeholders
// will fail to parse, as IntlMessageFormat expects them to be defined in the
// options passed to fc.format() as { 0: (children) => string }
// but the replacement of placeholders is done in react-i18next
fc = new IntlMessageFormat(res, lng, this.formats, { ignoreTag: true });
fc = new IntlMessageFormat(res, transformedLng, this.formats, { ignoreTag: true });
if (this.options.memoize && (this.options.memoizeFallback || !info || hadSuccessfulLookup)) utils.setPath(this.mem, memKey, fc);
}

return fc.format(options);
} catch (err) {
return this.options.parseErrorHandler(err, key,res, options);
return this.options.parseErrorHandler(err, key, res, options);
}
}

Expand Down
18 changes: 18 additions & 0 deletions test/icu.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,24 @@ describe("icu format", () => {
i18next.addResourceBundle("en", "translation", { key: "value" });
expect(spy).toHaveBeenCalledTimes(2);
});

it("should transform the language code", () => {
i18next.use(ICU).init({
lng: "invalid-icu-language",
resources: {
"invalid-icu-language": {
translation: {
key: "Hello {who}",
}
}
},
i18nFormat: {
parseLngForICU: (lng) => "en-US",
},
});

expect(i18next.t("key", { who: 'world' })).toEqual("Hello world");
});
});

describe("with missing keys", () => {
Expand Down

0 comments on commit 9615bc9

Please sign in to comment.