From 7e0ad2c7997dc7ce6df5308b2f914f0d9a4fa20c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sat, 12 Apr 2025 23:01:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=89=8D=E7=AB=AF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/gettext.config.js | 7 --- web/gettext.config.mjs | 62 ++++++++++++++++++++++++ web/src/i18n/i18n.ts | 5 -- web/src/locales/en.po | 30 ++++++++++++ web/src/locales/frontend.pot | 23 +++++++++ web/src/locales/zh_CN.po | 29 +++++++++++ web/src/locales/zh_TW.po | 29 +++++++++++ web/src/main.ts | 4 +- web/src/router/guard/page-title-guard.ts | 3 +- web/src/utils/gettext/index.ts | 40 +++++++++++++-- web/src/views/setting/SettingHttps.vue | 15 +++--- 11 files changed, 218 insertions(+), 29 deletions(-) delete mode 100644 web/gettext.config.js create mode 100644 web/gettext.config.mjs create mode 100644 web/src/locales/en.po create mode 100644 web/src/locales/frontend.pot create mode 100644 web/src/locales/zh_CN.po create mode 100644 web/src/locales/zh_TW.po diff --git a/web/gettext.config.js b/web/gettext.config.js deleted file mode 100644 index 613d9257..00000000 --- a/web/gettext.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - output: { - path: './src/locales', - potPath: './frontend.pot', - locales: ['en', 'zh_CN', 'zh_TW'] - } -} diff --git a/web/gettext.config.mjs b/web/gettext.config.mjs new file mode 100644 index 00000000..4c47e63d --- /dev/null +++ b/web/gettext.config.mjs @@ -0,0 +1,62 @@ +export default { + input: { + include: ['**/*.js', '**/*.ts', '**/*.vue'], + exclude: ['utils/gettext/**'], + jsExtractorOpts: [ + { + keyword: '__', // $gettext + options: { + content: { + replaceNewLines: '\n' + }, + arguments: { + text: 0 + } + } + }, + { + keyword: '_n', // $ngettext + options: { + content: { + replaceNewLines: '\n' + }, + arguments: { + text: 0, + textPlural: 1 + } + } + }, + { + keyword: '_x', // $pgettext + options: { + content: { + replaceNewLines: '\n' + }, + arguments: { + context: 0, + text: 1 + } + } + }, + { + keyword: '_nx', // $npgettext + options: { + content: { + replaceNewLines: '\n' + }, + arguments: { + context: 0, + text: 1, + textPlural: 2 + } + } + } + ] + }, + output: { + path: './src/locales', + potPath: './frontend.pot', + locales: ['en', 'zh_CN', 'zh_TW'], + linguas: false + } +} diff --git a/web/src/i18n/i18n.ts b/web/src/i18n/i18n.ts index c5789d70..5d0d9cb1 100644 --- a/web/src/i18n/i18n.ts +++ b/web/src/i18n/i18n.ts @@ -1,5 +1,4 @@ import type { App } from 'vue' -import type { Composer } from 'vue-i18n' import { createI18n } from 'vue-i18n' import { useThemeStore } from '@/store' @@ -24,7 +23,3 @@ export function setupI18n(app: App) { }) app.use(i18n) } - -export const trans = (key: string, attributes = {}) => { - return (i18n.global.t as Composer['t'])(key, attributes) -} diff --git a/web/src/locales/en.po b/web/src/locales/en.po new file mode 100644 index 00000000..189f6e89 --- /dev/null +++ b/web/src/locales/en.po @@ -0,0 +1,30 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/views/setting/SettingHttps.vue:25 +msgid "Saved successfully" +msgstr "Saved successfully" + +#: src/views/setting/SettingHttps.vue:34 +msgid "Panel HTTPS" +msgstr "Panel HTTPS" + +#: src/views/setting/SettingHttps.vue:37 +msgid "Certificate" +msgstr "Certificate" + +#: src/views/setting/SettingHttps.vue:44 +msgid "Private Key" +msgstr "Private Key" + +#: src/views/setting/SettingHttps.vue:54 +msgid "Save" +msgstr "Save" diff --git a/web/src/locales/frontend.pot b/web/src/locales/frontend.pot new file mode 100644 index 00000000..4c7aa4de --- /dev/null +++ b/web/src/locales/frontend.pot @@ -0,0 +1,23 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +#: src/views/setting/SettingHttps.vue:25 +msgid "Saved successfully" +msgstr "" + +#: src/views/setting/SettingHttps.vue:34 +msgid "Panel HTTPS" +msgstr "" + +#: src/views/setting/SettingHttps.vue:37 +msgid "Certificate" +msgstr "" + +#: src/views/setting/SettingHttps.vue:44 +msgid "Private Key" +msgstr "" + +#: src/views/setting/SettingHttps.vue:54 +msgid "Save" +msgstr "" diff --git a/web/src/locales/zh_CN.po b/web/src/locales/zh_CN.po new file mode 100644 index 00000000..85c8b021 --- /dev/null +++ b/web/src/locales/zh_CN.po @@ -0,0 +1,29 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/views/setting/SettingHttps.vue:25 +msgid "Saved successfully" +msgstr "" + +#: src/views/setting/SettingHttps.vue:34 +msgid "Panel HTTPS" +msgstr "" + +#: src/views/setting/SettingHttps.vue:37 +msgid "Certificate" +msgstr "" + +#: src/views/setting/SettingHttps.vue:44 +msgid "Private Key" +msgstr "" + +#: src/views/setting/SettingHttps.vue:54 +msgid "Save" +msgstr "" diff --git a/web/src/locales/zh_TW.po b/web/src/locales/zh_TW.po new file mode 100644 index 00000000..94b809b7 --- /dev/null +++ b/web/src/locales/zh_TW.po @@ -0,0 +1,29 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/views/setting/SettingHttps.vue:25 +msgid "Saved successfully" +msgstr "" + +#: src/views/setting/SettingHttps.vue:34 +msgid "Panel HTTPS" +msgstr "" + +#: src/views/setting/SettingHttps.vue:37 +msgid "Certificate" +msgstr "" + +#: src/views/setting/SettingHttps.vue:44 +msgid "Private Key" +msgstr "" + +#: src/views/setting/SettingHttps.vue:54 +msgid "Save" +msgstr "" diff --git a/web/src/main.ts b/web/src/main.ts index b4ff1b94..4caba7c6 100644 --- a/web/src/main.ts +++ b/web/src/main.ts @@ -9,7 +9,7 @@ import App from './App.vue' import { setupI18n } from '@/i18n/i18n' import { setupRouter } from '@/router' import { setupStore, useThemeStore } from '@/store' -import { setupGettext, setupNaiveDiscreteApi } from '@/utils' +import { createGettext, setupNaiveDiscreteApi } from '@/utils' import { install as VueMonacoEditorPlugin } from '@guolao/vue-monaco-editor' @@ -30,7 +30,7 @@ async function setupApp() { await setupStore(app) await setupNaiveDiscreteApi() await setupPanel().then(() => { - setupGettext(app) + app.use(createGettext) setupI18n(app) }) await setupRouter(app) diff --git a/web/src/router/guard/page-title-guard.ts b/web/src/router/guard/page-title-guard.ts index d29836d4..3d42b24b 100644 --- a/web/src/router/guard/page-title-guard.ts +++ b/web/src/router/guard/page-title-guard.ts @@ -1,13 +1,12 @@ import type { Router } from 'vue-router' -import { trans } from '@/i18n/i18n' import { useThemeStore } from '@/store' export function createPageTitleGuard(router: Router) { const themeStore = useThemeStore() router.afterEach((to) => { const pageTitle = String(to.meta.title) - if (pageTitle) document.title = `${trans(pageTitle)} | ${themeStore.name}` + if (pageTitle) document.title = `${pageTitle} | ${themeStore.name}` else document.title = themeStore.name }) } diff --git a/web/src/utils/gettext/index.ts b/web/src/utils/gettext/index.ts index 8eb61e04..42887264 100644 --- a/web/src/utils/gettext/index.ts +++ b/web/src/utils/gettext/index.ts @@ -1,10 +1,41 @@ import type { App } from 'vue' -import { createGettext } from 'vue3-gettext' +import { createGettext as vue3Gettext } from 'vue3-gettext' -let gettext: ReturnType +export let gettext: ReturnType + +export function $gettext(msgid: string, params?: Record) { + return gettext.$gettext(msgid, params) +} + +export function $ngettext( + msgid: string, + plural: string, + n: number, + params?: Record +) { + return gettext.$ngettext(msgid, plural, n, params) +} export function setupGettext(app: App) { - gettext = createGettext({ + gettext = vue3Gettext({ + availableLanguages: { + en: 'English', + zh_CN: '简体中文', + zh_TW: '繁體中文' + }, + defaultLanguage: 'zh_CN', + globalProperties: { + gettext: ['$gettext', '__'], // 这样支持同时使用 $gettext, __ 两种方式 + ngettext: ['$ngettext', '_n'], + pgettext: ['$pgettext', '_x'], + npgettext: ['$npgettext', '_nx'] + } + }) + app.use(gettext) +} + +export function createGettext(): any { + gettext = vue3Gettext({ availableLanguages: { en: 'English', zh_CN: '简体中文', @@ -12,5 +43,6 @@ export function setupGettext(app: App) { }, defaultLanguage: 'zh_CN' }) - app.use(gettext) + + return gettext } diff --git a/web/src/views/setting/SettingHttps.vue b/web/src/views/setting/SettingHttps.vue index 0b7aaec8..52df6113 100644 --- a/web/src/views/setting/SettingHttps.vue +++ b/web/src/views/setting/SettingHttps.vue @@ -1,9 +1,6 @@ @@ -34,17 +31,17 @@ const handleSave = () => { 错误的证书可能导致面板无法访问,请谨慎操作! - + - + - + { - {{ $t('settingIndex.edit.actions.submit') }} + {{ $gettext('Save') }}