Extend i18n with translate and template literal

d99452854835696baf8e7fe898723c92633af13e

Wolfsblvt <wolfsblvt@gmx.de>

2 files changed, +46 -1Showing whitespace changes
public/script.js+3 -1
@@ -209,7 +209,7 @@ import {
209209 instruct_presets,
210210 selectContextPreset,
211211} from './scripts/instruct-mode.js';
212212import { initLocales, t, translate } from './scripts/i18n.js';
213213import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, getTokenizerModel, initTokenizers, saveTokenCache } from './scripts/tokenizers.js';
214214import {
215215 user_avatar,
@@ -7825,6 +7825,8 @@ window['SillyTavern'].getContext = function () {
78257825 messageFormatting: messageFormatting,
78267826 shouldSendOnEnter: shouldSendOnEnter,
78277827 isMobile: isMobile,
7828+ t: t,
7829+ translate: translate,
78287830 tags: tags,
78297831 tagMap: tag_map,
78307832 menuType: menu_type,
public/scripts/i18n.js+43 -0
@@ -32,6 +32,49 @@ const observer = new MutationObserver(mutations => {
3232});
3333
3434/**
35+ * Translates a template string with named arguments
36+ *
37+ * Uses the template literal with all values replaced by index placeholder for translation key.
38+ *
39+ * @example
40+ * ```js
41+ * toastr.warn(t`Tag ${tagName} not found.`);
42+ * ```
43+ * Should be translated in the translation files as:
44+ * ```
45+ * Tag ${0} not found. -> Tag ${0} nicht gefunden.
46+ * ```
47+ *
48+ * @param {TemplateStringsArray} strings - Template strings array
49+ * @param {...any} values - Values for placeholders in the template string
50+ * @returns {string} Translated and formatted string
51+ */
52+export function t(strings, ...values) {
53+ let str = strings.reduce((result, string, i) => result + string + (values[i] !== undefined ? `\${${i}}` : ''), '');
54+ let translatedStr = translate(str);
55+
56+ // Replace indexed placeholders with actual values
57+ return translatedStr.replace(/\$\{(\d+)\}/g, (match, index) => values[index]);
58+}
59+
60+/**
61+ * Translates a given key or text
62+ *
63+ * If the translation is based on a key, that one is used to find a possible translation in the translation file.
64+ * The original text still has to be provided, as that is the default value being returned if no translation is found.
65+ *
66+ * For in-code text translation on a format string, using the template literal `t` is preferred.
67+ *
68+ * @param {string} text - The text to translate
69+ * @param {string?} key - The key to use for translation. If not provided, text is used as the key.
70+ * @returns {string} - The translated text
71+ */
72+export function translate(text, key = null) {
73+ const translationKey = key || text;
74+ return localeData?.[translationKey] || text;
75+}
76+
77+/**
3578 * Fetches the locale data for the given language.
3679 * @param {string} language Language code
3780 * @returns {Promise<Record<string, string>>} Locale data