Skip to content

Commit

Permalink
* (bluefox) Added i18n module
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Aug 30, 2024
1 parent 136f5e9 commit 1133ab5
Show file tree
Hide file tree
Showing 19 changed files with 1,173 additions and 770 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,26 @@ And the following **modules** are exposed:

Note that `commonTools.letsEncrypt` is not available anymore as the next controller won't support it (use `@iobroker/webserver` instead).
## i18n
Developer can use internationalisation in backend.
For that call
```javascript
const i18n = require('@iobroker/adapter-core').i18n;
// later in "ready" method
i18n.init(__dirname, adapter);
// If you use class syntax, you can use `this` instead of `adapter`
i18n.init(__dirname, this);
```
and then in code
```javascript
console.log(i18n.t('text to translate %s', 'argument1'));
// or to get the ioBroker.Translated object
console.log(JSON.stringify(i18n.tt('text to translate %s and %s', 'argument1', 'argument2')));
```
## Automatic backup of data files
ioBroker has the ability to include files written by adapters in its backups. To enable that, you need to add the following to `io-package.json`:
Expand Down Expand Up @@ -117,6 +137,7 @@ If you find errors in the definitions, e.g., function calls that should be allow

### **WORK IN PROGRESS**
* (foxriver76) updated types
* (bluefox) Added i18n module

### 3.1.6 (2024-06-04)
* (foxriver76) improve exported types
Expand Down
109 changes: 109 additions & 0 deletions build/cjs/i18n.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions build/cjs/i18n.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions build/cjs/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions build/cjs/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 21 additions & 0 deletions build/esm/build/cjs/i18n.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export declare function init(
/** The root directory of the adapter */
rootDir: string,
/** The adapter instance or the language to use */
langOrAdmin: ioBroker.Adapter | ioBroker.Languages): Promise<void>;
/**
* Get translation as one string
*/
export declare function t(
/** Word to translate */
key: string,
/** Optional parameters to replace %s */
...args: (string | number | boolean | null)[]): string;
/**
* Get translation as ioBroker.Translated object
*/
export declare function tt(
/** Word to translate */
key: string,
/** Optional parameters to replace %s */
...args: (string | number | boolean | null)[]): ioBroker.StringOrTranslated;
1 change: 1 addition & 0 deletions build/cjs/index.d.ts → build/esm/build/cjs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ExitCodes } from "./exitCodes.js";
import "@iobroker/types";
export { commonTools } from "./controllerTools.js";
export * from "./utils.js";
export * as i18n from "./utils.js";
/**
* Returns the absolute path of the data directory for the current host. On linux, this is usually `/opt/iobroker/iobroker-data`.
*/
Expand Down
File renamed without changes.
21 changes: 21 additions & 0 deletions build/esm/i18n.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export declare function init(
/** The root directory of the adapter */
rootDir: string,
/** The adapter instance or the language to use */
langOrAdmin: ioBroker.Adapter | ioBroker.Languages): Promise<void>;
/**
* Get translation as one string
*/
export declare function t(
/** Word to translate */
key: string,
/** Optional parameters to replace %s */
...args: (string | number | boolean | null)[]): string;
/**
* Get translation as ioBroker.Translated object
*/
export declare function tt(
/** Word to translate */
key: string,
/** Optional parameters to replace %s */
...args: (string | number | boolean | null)[]): ioBroker.StringOrTranslated;
99 changes: 99 additions & 0 deletions build/esm/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { readFileSync, readdirSync, existsSync } from "node:fs";
import { join } from "node:path";
let language = "en";
let words = null;
// Init internationalization
export async function init(
/** The root directory of the adapter */
rootDir,
/** The adapter instance or the language to use */
langOrAdmin) {
if (langOrAdmin && typeof langOrAdmin === "object") {
const adapter = langOrAdmin;
const systemConfig = await adapter.getForeignObjectAsync("system.config");
if (systemConfig?.common.language) {
language = systemConfig?.common.language;
}
}
else if (typeof langOrAdmin === "string") {
language = langOrAdmin;
}
let files;
if (existsSync(join(rootDir, "i18n"))) {
files = readdirSync(join(rootDir, "i18n"));
}
else if (existsSync(join(rootDir, "lib/i18n"))) {
files = readdirSync(join(rootDir, "lib/i18n"));
}
else {
throw new Error("Cannot find i18n directory");
}
words = {};
files.forEach((file) => {
if (file.endsWith(".json")) {
const lang = file.split(".")[0];
const wordsForLanguage = JSON.parse(readFileSync(join(rootDir, `/i18n/${file}`)).toString("utf8"));
Object.keys(wordsForLanguage).forEach((key) => {
if (words) {
if (!words[key]) {
words[key] = {};
}
words[key][lang] = wordsForLanguage[key];
}
});
}
});
}
/**
* Get translation as one string
*/
export function t(
/** Word to translate */
key,
/** Optional parameters to replace %s */
...args) {
if (!words) {
throw new Error("i18n not initialized. Please call 'init(adapter)' before");
}
if (!words[key]) {
return key;
}
let text = words[key][language] || words[key].en || key;
if (args.length) {
for (let i = 0; i < args.length; i++) {
text = text.replace("%s",
// @ts-expect-error No idea why args[i] is not accepted here
args[i] === null ? "null" : args[i].toString());
}
}
return text;
}
/**
* Get translation as ioBroker.Translated object
*/
export function tt(
/** Word to translate */
key,
/** Optional parameters to replace %s */
...args) {
if (!words) {
throw new Error("i18n not initialized. Please call 'init(adapter)' before");
}
if (words[key]) {
if (words[key].en && words[key].en.includes("%s")) {
const result = {};
Object.keys(words[key]).forEach((lang) => {
for (let i = 0; i < args.length; i++) {
result[lang] =
// @ts-expect-error words[key] cannot be null
words[key][lang].replace("%s",
// @ts-expect-error No idea why args[i] is not accepted here
args[i] === null ? "null" : args[i].toString());
}
});
return result;
}
return words[key];
}
return key;
}
1 change: 1 addition & 0 deletions build/esm/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ExitCodes } from "./exitCodes.js";
import "@iobroker/types";
export { commonTools } from "./controllerTools.js";
export * from "./utils.js";
export * as i18n from "./utils.js";
/**
* Returns the absolute path of the data directory for the current host. On linux, this is usually `/opt/iobroker/iobroker-data`.
*/
Expand Down
1 change: 1 addition & 0 deletions build/esm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "@iobroker/types";
// Export utility methods to be used in adapters
export { commonTools } from "./controllerTools.js";
export * from "./utils.js";
export * as i18n from "./utils.js";
/**
* Returns the absolute path of the data directory for the current host. On linux, this is usually `/opt/iobroker/iobroker-data`.
*/
Expand Down
Loading

0 comments on commit 1133ab5

Please sign in to comment.