feat: enhance plugin page internationalization (#7998)

* feat: enhance plugin page internationalization

- Updated PluginRoute to read initial context from JWT and set it in the bridge SDK.
- Added methods to retrieve locale and plugin metadata for better i18n support.
- Enhanced pluginI18n utility to resolve page-specific translations and added new functions for page titles and descriptions.
- Modified PluginPagePage and PluginDetailPage to utilize new i18n features for dynamic content rendering.
- Improved documentation for plugin page i18n structure and usage.
- Added tests to verify the correct integration of i18n in plugin pages and context handling.

* fix test
This commit is contained in:
Weilong Liao
2026-05-04 20:15:21 +08:00
committed by GitHub
parent 319f50be2a
commit cb4f941e43
12 changed files with 952 additions and 72 deletions

View File

@@ -1,62 +1,106 @@
import { useI18n } from '@/i18n/composables'
import { useI18n } from "@/i18n/composables";
function getLocaleData(i18n, locale) {
if (!i18n || typeof i18n !== 'object' || !locale) return null
return i18n[locale] || null
if (!i18n || typeof i18n !== "object" || !locale) return null;
return i18n[locale] || null;
}
function getByPath(source, key) {
if (!source || typeof source !== 'object' || !key) return undefined
if (!source || typeof source !== "object" || !key) return undefined;
const parts = key.split('.')
let current = source
const parts = key.split(".");
let current = source;
for (const part of parts) {
if (!current || typeof current !== 'object' || !(part in current)) {
return undefined
if (!current || typeof current !== "object" || !(part in current)) {
return undefined;
}
current = current[part]
current = current[part];
}
return current
return current;
}
export function resolvePluginI18n(i18n, locale, key, fallback = '') {
const localeData = getLocaleData(i18n, locale)
const value = getByPath(localeData, key)
return value === undefined || value === null ? fallback : value
export function resolvePluginI18n(i18n, locale, key, fallback = "") {
const localeData = getLocaleData(i18n, locale);
const value = getByPath(localeData, key);
return value === undefined || value === null ? fallback : value;
}
function getPluginPageI18nBase(page) {
if (page && typeof page === "object") {
if (typeof page.i18n_key === "string" && page.i18n_key.trim()) {
return page.i18n_key.trim();
}
const pageName = page.page_name || page.name;
return pageName ? `pages.${pageName}` : "";
}
return page ? `pages.${page}` : "";
}
export function usePluginI18n() {
const { locale } = useI18n()
const { locale } = useI18n();
const resolve = (i18n, key, fallback = '') => {
return resolvePluginI18n(i18n, locale.value, key, fallback)
}
const resolve = (i18n, key, fallback = "") => {
return resolvePluginI18n(i18n, locale.value, key, fallback);
};
const pluginName = (plugin) => {
const fallback = plugin?.display_name?.length ? plugin.display_name : plugin?.name
return resolve(plugin?.i18n, 'metadata.display_name', fallback || '')
}
const fallback = plugin?.display_name?.length
? plugin.display_name
: plugin?.name;
return resolve(plugin?.i18n, "metadata.display_name", fallback || "");
};
const pluginDesc = (plugin, fallback = '') => {
const pluginDesc = (plugin, fallback = "") => {
return resolve(
plugin?.i18n,
'metadata.desc',
fallback || plugin?.desc || plugin?.description || '',
)
}
"metadata.desc",
fallback || plugin?.desc || plugin?.description || "",
);
};
const pluginShortDesc = (plugin, fallback = '') => {
const pluginShortDesc = (plugin, fallback = "") => {
return resolve(
plugin?.i18n,
'metadata.short_desc',
fallback || plugin?.short_desc || plugin?.desc || plugin?.description || '',
)
}
"metadata.short_desc",
fallback ||
plugin?.short_desc ||
plugin?.desc ||
plugin?.description ||
"",
);
};
const configText = (i18n, path, attr, fallback = '') => {
const key = path ? `config.${path}.${attr}` : `config.${attr}`
return resolve(i18n, key, fallback)
}
const pluginPageText = (plugin, page, attr, fallback = "") => {
const base = getPluginPageI18nBase(page);
if (!base || !attr) {
return fallback;
}
return resolve(plugin?.i18n, `${base}.${attr}`, fallback);
};
const pluginPageTitle = (plugin, page, fallback = "") => {
const pageFallback =
fallback ||
(page && typeof page === "object"
? page.title || page.name || page.page_name
: page) ||
"";
return pluginPageText(plugin, page, "title", pageFallback);
};
const pluginPageDescription = (plugin, page, fallback = "") => {
const pageFallback =
fallback ||
(page && typeof page === "object" ? page.description || page.desc : "") ||
"";
return pluginPageText(plugin, page, "description", pageFallback);
};
const configText = (i18n, path, attr, fallback = "") => {
const key = path ? `config.${path}.${attr}` : `config.${attr}`;
return resolve(i18n, key, fallback);
};
return {
locale,
@@ -64,6 +108,9 @@ export function usePluginI18n() {
pluginName,
pluginDesc,
pluginShortDesc,
pluginPageText,
pluginPageTitle,
pluginPageDescription,
configText,
}
};
}