From 35d144c6782d56f9fd626a4cc578548fe3477747 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Sat, 19 Feb 2022 09:52:59 +0800 Subject: [PATCH] use vue-gettext --- README-zh_CN.md | 18 +- README.md | 23 +- frontend/Makefile | 61 ++ frontend/babel.config.js | 6 +- frontend/package.json | 2 + frontend/src/App.vue | 8 +- frontend/src/api/config.js | 2 +- frontend/src/api/domain.js | 2 +- frontend/src/api/install.js | 2 +- frontend/src/assets/css/dark.less | 1 - frontend/src/components/Chart/LineChart.vue | 17 +- frontend/src/components/Logo/Logo.vue | 2 +- .../RichText/CodeBlockComponent.vue | 18 +- frontend/src/components/RichText/MenuBar.vue | 12 +- frontend/src/components/RichText/MenuItem.vue | 4 +- frontend/src/components/RichText/RichText.vue | 2 +- .../components/RichText/RichTextEditor.vue | 2 +- .../src/components/StdDataDisplay/StdCurd.vue | 2 +- .../components/StdDataDisplay/StdTable.vue | 32 +- .../components/StdDataEntry/StdRadioGroup.vue | 2 +- .../components/VueItextarea/VueItextarea.vue | 6 +- frontend/src/layouts/SideBar.vue | 2 + frontend/src/lazy.js | 6 +- frontend/src/lib/http/index.js | 2 + frontend/src/lib/store/index.js | 5 +- frontend/src/lib/store/settings.js | 21 + frontend/src/lib/translate/gettext.js | 29 + frontend/src/lib/translate/index.js | 5 + frontend/src/lib/utils/index.js | 8 +- frontend/src/locale/en/LC_MESSAGES/app.po | 123 ++++ frontend/src/locale/en/LC_MESSAGES/app.po~ | 123 ++++ frontend/src/locale/zh_CN/LC_MESSAGES/app.mo | Bin 0 -> 1563 bytes frontend/src/locale/zh_CN/LC_MESSAGES/app.po | 125 ++++ frontend/src/locale/zh_CN/LC_MESSAGES/app.po~ | 125 ++++ frontend/src/locale/zh_TW/LC_MESSAGES/app.po | 122 ++++ frontend/src/locale/zh_TW/LC_MESSAGES/app.po~ | 122 ++++ frontend/src/main.js | 10 + frontend/src/router/index.js | 39 +- frontend/src/translations.json | 1 + frontend/src/views/config/Config.vue | 22 +- frontend/src/views/config/ConfigEdit.vue | 18 +- .../{doashboard => dashboard}/DashBoard.vue | 52 +- frontend/src/views/domain/CertInfo.vue | 10 +- frontend/src/views/domain/DomainAdd.vue | 14 +- frontend/src/views/domain/DomainEdit.vue | 64 +- frontend/src/views/domain/DomainList.vue | 40 +- frontend/src/views/domain/columns.js | 64 +- frontend/src/views/domain/methods.js | 12 +- frontend/src/views/other/About.vue | 5 +- frontend/src/views/other/Install.vue | 2 +- frontend/src/views/other/Login.vue | 4 +- frontend/src/views/user/User.vue | 28 +- frontend/version.json | 6 +- frontend/yarn.lock | 617 +++++++++++++++++- server/api/analytic.go | 1 - server/model/config-backup.go | 2 +- server/model/curd.go | 32 +- server/test/analytic_test.go | 48 +- server/test/lego_test.go | 136 ++-- server/test/nginx_test.go | 2 +- server/tool/config_list.go | 70 +- 61 files changed, 1929 insertions(+), 412 deletions(-) create mode 100644 frontend/Makefile create mode 100644 frontend/src/lib/store/settings.js create mode 100644 frontend/src/lib/translate/gettext.js create mode 100644 frontend/src/lib/translate/index.js create mode 100644 frontend/src/locale/en/LC_MESSAGES/app.po create mode 100644 frontend/src/locale/en/LC_MESSAGES/app.po~ create mode 100644 frontend/src/locale/zh_CN/LC_MESSAGES/app.mo create mode 100644 frontend/src/locale/zh_CN/LC_MESSAGES/app.po create mode 100644 frontend/src/locale/zh_CN/LC_MESSAGES/app.po~ create mode 100644 frontend/src/locale/zh_TW/LC_MESSAGES/app.po create mode 100644 frontend/src/locale/zh_TW/LC_MESSAGES/app.po~ create mode 100644 frontend/src/translations.json rename frontend/src/views/{doashboard => dashboard}/DashBoard.vue (78%) diff --git a/README-zh_CN.md b/README-zh_CN.md index 766cc884..ac50f259 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,4 +1,5 @@ # Nginx UI + Yet another Nginx Web UI Version: 1.1.0 @@ -15,46 +16,59 @@ Version: 1.1.0 ## 项目预览 ### 登录 + ![](resources/screenshots/login.png) ### 仪表盘 + ![](resources/screenshots/dashboard.png) ### 用户列表 + ![](resources/screenshots/user-list.png) ### 域名列表 + ![](resources/screenshots/domain-list.png) ### 域名编辑 + ![](resources/screenshots/domain-edit.png) ### 配置列表 + ![](resources/screenshots/config-list.png) ### 配置编辑 + ![](resources/screenshots/config-edit.png) ## 使用前注意 -Nginx UI 遵循 Nginx 的标准,创建的网站配置文件位于 Nginx 配置目录(自动检测)下的 `sites-available` 目录, -启用后的网站的配置文件将会创建一份软连接到 `sites-enabled` 目录中。因此,您可能需要调整配置文件的组织方式。 +Nginx UI 遵循 Nginx 的标准,创建的网站配置文件位于 Nginx 配置目录(自动检测)下的 `sites-available` 目录, 启用后的网站的配置文件将会创建一份软连接到 `sites-enabled` +目录中。因此,您可能需要调整配置文件的组织方式。 ## 安装 + 1. 克隆项目 + ``` git clone https://github.com/0xJacky/nginx-ui ``` + 2. 编译后端 + ``` cd server go build -o nginx-ui-server main.go ``` + 3. 启动后端 1. 前台启动 `./nginx-ui-server` 2. 后台启动 `nohup ./nginx-ui-server &` 4. 添加配置文件到 nginx + ``` server { listen 80; diff --git a/README.md b/README.md index a9d36605..80ee10dd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Nginx UI + Yet another Nginx Web UI Version: 1.1.0 @@ -17,46 +18,60 @@ Version: 1.1.0 ## Screenshots ### Login + ![](resources/screenshots/login.png) ### Dashboard + ![](resources/screenshots/dashboard.png) ### Users Management + ![](resources/screenshots/user-list.png) ### Domains Management + ![](resources/screenshots/domain-list.png) ### Domain Editor + ![](resources/screenshots/domain-edit.png) ### Configurations Management + ![](resources/screenshots/config-list.png) ### Configuration Editor + ![](resources/screenshots/config-edit.png) ## Note Before Use -The Nginx UI follows the Nginx standard of creating site configuration files in the `sites-available` directory under the Nginx configuration directory (auto-detected). -The configuration files for an enabled site will create a soft link to the `sites-enabled` directory. Therefore, you may need to adjust the way the configuration files are organised. +The Nginx UI follows the Nginx standard of creating site configuration files in the `sites-available` directory under +the Nginx configuration directory (auto-detected). The configuration files for an enabled site will create a soft link +to the `sites-enabled` directory. Therefore, you may need to adjust the way the configuration files are organised. ## Install + 1. Clone + ``` git clone https://github.com/0xJacky/nginx-ui ``` + 2. Compiling the backend + ``` cd server go build -o nginx-ui-server main.go ``` + 3. Start up the backend - 1. `./nginx-ui-server` for direct run. - 2. `nohup ./nginx-ui-server &` for run as service. + 1. `./nginx-ui-server` for direct run. + 2. `nohup ./nginx-ui-server &` for run as service. 4. Adding a configuration file to nginx + ``` server { listen 80; diff --git a/frontend/Makefile b/frontend/Makefile new file mode 100644 index 00000000..8ed2d18e --- /dev/null +++ b/frontend/Makefile @@ -0,0 +1,61 @@ +# On OSX the PATH variable isn't exported unless "SHELL" is also set, see: http://stackoverflow.com/a/25506676 +SHELL = /bin/bash +NODE_BINDIR = ./node_modules/.bin +export PATH := $(NODE_BINDIR):$(PATH) +LOGNAME ?= $(shell logname) + +# adding the name of the user's login name to the template file, so that +# on a multi-user system several users can run this without interference +TEMPLATE_POT ?= /tmp/template-$(LOGNAME).pot + +# Where to find input files (it can be multiple paths). +INPUT_FILES = ./src + +# Where to write the files generated by this makefile. +OUTPUT_DIR = ./src + +# Available locales for the app. +LOCALES = zh_CN zh_TW en + +# Name of the generated .po files for each available locale. +LOCALE_FILES ?= $(patsubst %,$(OUTPUT_DIR)/locale/%/LC_MESSAGES/app.po,$(LOCALES)) + +GETTEXT_SOURCES ?= $(shell find $(INPUT_FILES) -name '*.jade' -o -name '*.html' -o -name '*.js' -o -name '*.vue' 2> /dev/null) + +# Makefile Targets +.PHONY: clean makemessages translations all + +all: + @echo choose a target from: clean makemessages translations + +clean: + rm -f $(TEMPLATE_POT) $(OUTPUT_DIR)/translations.json + +makemessages: $(TEMPLATE_POT) + +translations: ./$(OUTPUT_DIR)/translations.json +# Create a main .pot template, then generate .po files for each available language. +# Thanx to Systematic: https://github.com/Polyconseil/systematic/blob/866d5a/mk/main.mk#L167-L183 +$(TEMPLATE_POT): $(GETTEXT_SOURCES) +# `dir` is a Makefile built-in expansion function which extracts the directory-part of `$@`. +# `$@` is a Makefile automatic variable: the file name of the target of the rule. +# => `mkdir -p /tmp/` + mkdir -p $(dir $@) +# Extract gettext strings from templates files and create a POT dictionary template. + gettext-extract --quiet --attribute v-translate --output $@ $(GETTEXT_SOURCES) +# Generate .po files for each available language. + @for lang in $(LOCALES); do \ + export PO_FILE=$(OUTPUT_DIR)/locale/$$lang/LC_MESSAGES/app.po; \ + mkdir -p $$(dirname $$PO_FILE); \ + if [ -f $$PO_FILE ]; then \ + echo "msgmerge --update $$PO_FILE $@"; \ + msgmerge --lang=$$lang --update $$PO_FILE $@ || break ;\ + else \ + msginit --no-translator --locale=$$lang --input=$@ --output-file=$$PO_FILE || break ; \ + msgattrib --no-wrap --no-obsolete -o $$PO_FILE $$PO_FILE || break; \ + fi; \ + done; + +$(OUTPUT_DIR)/translations.json: $(LOCALE_FILES) + mkdir -p $(OUTPUT_DIR) + gettext-compile --output $@ $(LOCALE_FILES) diff --git a/frontend/babel.config.js b/frontend/babel.config.js index 4fa78b99..6136ee4c 100644 --- a/frontend/babel.config.js +++ b/frontend/babel.config.js @@ -1,10 +1,10 @@ module.exports = { presets: [ - "@vue/cli-plugin-babel/preset" + '@vue/cli-plugin-babel/preset' ], - "plugins": [ + 'plugins': [ '@babel/plugin-proposal-optional-chaining', '@babel/plugin-proposal-nullish-coalescing-operator', - ["import", {"libraryName": "ant-design-vue", "libraryDirectory": "es", "style": true}, "syntax-dynamic-import"] + ['import', {'libraryName': 'ant-design-vue', 'libraryDirectory': 'es', 'style': true}, 'syntax-dynamic-import'] ], } diff --git a/frontend/package.json b/frontend/package.json index 8b82790b..37882e3b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,6 +16,7 @@ "vue": "^2.6.11", "vue-chartjs": "^3.5.1", "vue-codemirror": "^4.0.6", + "vue-gettext": "^2.1.12", "vue-itextarea": "^1.0.9", "vue-router": "^3.5.1", "vuex": "^3.6.2", @@ -39,6 +40,7 @@ "@vue/cli-service": "~4.5.0", "babel-eslint": "^10.1.0", "babel-plugin-import": "^1.13.3", + "easygettext": "^2.17.0", "eslint": "^6.7.2", "eslint-plugin-vue": "^6.2.2", "less": "^3.11.1", diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 9024d26b..873e9393 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,12 +1,12 @@ diff --git a/frontend/src/api/config.js b/frontend/src/api/config.js index ea85806f..9f829c61 100644 --- a/frontend/src/api/config.js +++ b/frontend/src/api/config.js @@ -1,4 +1,4 @@ -import http from "@/lib/http" +import http from '@/lib/http' const base_url = '/config' diff --git a/frontend/src/api/domain.js b/frontend/src/api/domain.js index f06b2554..7cf95641 100644 --- a/frontend/src/api/domain.js +++ b/frontend/src/api/domain.js @@ -1,4 +1,4 @@ -import http from "@/lib/http" +import http from '@/lib/http' const base_url = '/domain' diff --git a/frontend/src/api/install.js b/frontend/src/api/install.js index 488293d9..cd02c21b 100644 --- a/frontend/src/api/install.js +++ b/frontend/src/api/install.js @@ -1,4 +1,4 @@ -import http from "@/lib/http"; +import http from '@/lib/http' const install = { get_lock() { diff --git a/frontend/src/assets/css/dark.less b/frontend/src/assets/css/dark.less index e8a2eb5c..aa7b5800 100644 --- a/frontend/src/assets/css/dark.less +++ b/frontend/src/assets/css/dark.less @@ -37,7 +37,6 @@ @popover-bg: @black_bg; @background-color-light: fade(@white, 4%); // background of header and selected item - // Descriptions // --- @descriptions-bg: @background-color-light; diff --git a/frontend/src/components/Chart/LineChart.vue b/frontend/src/components/Chart/LineChart.vue index b43444de..e5b39adf 100644 --- a/frontend/src/components/Chart/LineChart.vue +++ b/frontend/src/components/Chart/LineChart.vue @@ -1,24 +1,25 @@ diff --git a/frontend/src/components/RichText/RichTextEditor.vue b/frontend/src/components/RichText/RichTextEditor.vue index 627c8b10..c4b419e3 100644 --- a/frontend/src/components/RichText/RichTextEditor.vue +++ b/frontend/src/components/RichText/RichTextEditor.vue @@ -116,7 +116,7 @@ export default { } } border: 1px solid @gray; - line-height: 1.5!important; + line-height: 1.5 !important; &__header { display: flex; diff --git a/frontend/src/components/StdDataDisplay/StdCurd.vue b/frontend/src/components/StdDataDisplay/StdCurd.vue index b9f04e3c..2ae96450 100644 --- a/frontend/src/components/StdDataDisplay/StdCurd.vue +++ b/frontend/src/components/StdDataDisplay/StdCurd.vue @@ -66,7 +66,7 @@ diff --git a/frontend/src/layouts/SideBar.vue b/frontend/src/layouts/SideBar.vue index 6d9a8321..a5125c5b 100644 --- a/frontend/src/layouts/SideBar.vue +++ b/frontend/src/layouts/SideBar.vue @@ -82,10 +82,12 @@ export default { .sidebar { position: fixed; width: 200px; + .ant-menu-inline { height: calc(100vh - 120px); overflow-y: auto; overflow-x: hidden; + .ant-menu-item { width: unset; } diff --git a/frontend/src/lazy.js b/frontend/src/lazy.js index 6f800f7d..510aa9cd 100644 --- a/frontend/src/lazy.js +++ b/frontend/src/lazy.js @@ -38,16 +38,16 @@ import { Select, Skeleton, Slider, + Space, Spin, Statistic, Steps, + Switch, Table, Tabs, Tooltip, Transfer, - Upload, - Switch, - Space + Upload } from 'ant-design-vue' Vue.use(ConfigProvider) diff --git a/frontend/src/lib/http/index.js b/frontend/src/lib/http/index.js index 404976d8..76aee51a 100644 --- a/frontend/src/lib/http/index.js +++ b/frontend/src/lib/http/index.js @@ -1,5 +1,6 @@ import axios from 'axios' import store from '../store' +import {router} from '@/router' /* 创建 axios 实例 */ let http = axios.create({ @@ -40,6 +41,7 @@ http.interceptors.response.use( case 403: // 无权访问时,直接登出 await store.dispatch('logout') + router.push('/login').catch() break } return Promise.reject(error.response.data) diff --git a/frontend/src/lib/store/index.js b/frontend/src/lib/store/index.js index 4a5608c1..ecc11f39 100644 --- a/frontend/src/lib/store/index.js +++ b/frontend/src/lib/store/index.js @@ -2,6 +2,7 @@ import Vue from 'vue' import Vuex from 'vuex' import VuexPersistence from 'vuex-persist' import {user} from './user' +import {settings} from './settings' Vue.use(Vuex) @@ -9,13 +10,13 @@ const debug = process.env.NODE_ENV !== 'production' const vuexLocal = new VuexPersistence({ storage: window.localStorage, - modules: ['user'] + modules: ['user', 'settings'] }) export default new Vuex.Store({ // 将各组件分别模块化存入 Store modules: { - user + user, settings }, plugins: [vuexLocal.plugin], strict: debug diff --git a/frontend/src/lib/store/settings.js b/frontend/src/lib/store/settings.js new file mode 100644 index 00000000..43e0ce10 --- /dev/null +++ b/frontend/src/lib/store/settings.js @@ -0,0 +1,21 @@ +export const settings = { + namespace: true, + state: { + language: '' + }, + mutations: { + set_language(state, payload) { + state.language = payload + }, + }, + actions: { + set_language({commit}, data) { + commit('set_language', data) + }, + }, + getters: { + current_language(state) { + return state.language + } + } +} diff --git a/frontend/src/lib/translate/gettext.js b/frontend/src/lib/translate/gettext.js new file mode 100644 index 00000000..fe89d489 --- /dev/null +++ b/frontend/src/lib/translate/gettext.js @@ -0,0 +1,29 @@ +import {translate} from 'vue-gettext' +import store from '@/lib/store' +import {availableLanguages} from '@/lib/translate/index' +import translations from '@/translations.json' + +let lang = window.navigator.language +if (!lang.includes('zh')) { + lang = lang.split('-')[0] +} else { + lang = lang.replace('-', '_') +} +store.getters.current_language || +store.commit('set_language', availableLanguages[lang] ? lang : 'en') + +const config = { + language: store.getters.current_language, + getTextPluginSilent: true, + getTextPluginMuteLanguages: [], + silent: true, +} + +// easygettext aliases +const { + gettext: $gettext, +} = translate + +translate.initTranslations(translations, config) + +export default $gettext diff --git a/frontend/src/lib/translate/index.js b/frontend/src/lib/translate/index.js new file mode 100644 index 00000000..79c89f12 --- /dev/null +++ b/frontend/src/lib/translate/index.js @@ -0,0 +1,5 @@ +export const availableLanguages = { + zh_CN: '简', + zh_TW: '繁', + en: 'En' +} diff --git a/frontend/src/lib/utils/index.js b/frontend/src/lib/utils/index.js index 8334b108..b4193575 100644 --- a/frontend/src/lib/utils/index.js +++ b/frontend/src/lib/utils/index.js @@ -32,11 +32,11 @@ export default { Vue.prototype.scrollPosition = scrollPosition Vue.prototype.getWebSocketRoot = () => { - const protocol = location.protocol === "https:" ? "wss://" : "ws://" - if (process.env.NODE_ENV === 'development' && process.env["VUE_APP_API_WSS_ROOT"]) { - return process.env["VUE_APP_API_WSS_ROOT"] + const protocol = location.protocol === 'https:' ? 'wss://' : 'ws://' + if (process.env.NODE_ENV === 'development' && process.env['VUE_APP_API_WSS_ROOT']) { + return process.env['VUE_APP_API_WSS_ROOT'] } - return protocol + location.host + process.env["VUE_APP_API_WSS_ROOT"] + return protocol + location.host + process.env['VUE_APP_API_WSS_ROOT'] } } } diff --git a/frontend/src/locale/en/LC_MESSAGES/app.po b/frontend/src/locale/en/LC_MESSAGES/app.po new file mode 100644 index 00000000..543507ec --- /dev/null +++ b/frontend/src/locale/en/LC_MESSAGES/app.po @@ -0,0 +1,123 @@ +msgid "" +msgstr "" +"Project-Id-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" +"Generated-By: easygettext\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/router/index.js:98 +msgid "404 Not Found" +msgstr "" + +#: src/router/index.js:76 +msgid "About" +msgstr "" + +#: src/router/index.js:47 +msgid "Add Sites" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Cached:" +msgstr "" + +#: src/router/index.js:60 +msgid "Config" +msgstr "" + +#: src/router/index.js:19 +msgid "Dashboard" +msgstr "" + +#: src/router/index.js:124 +msgid "Detected version update, this page will automatically refresh." +msgstr "" + +#: src/views/dashboard/DashBoard.vue:95 +msgid "Free:" +msgstr "" + +#: src/router/index.js:12 +msgid "Home" +msgstr "" + +#: src/router/index.js:86 +msgid "Install" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:13 +msgid "Load averages" +msgstr "" + +#: src/router/index.js:92 +msgid "Login" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:23 +msgid "Memory" +msgstr "" + +#: src/router/index.js:68 +msgid "Modify Config" +msgstr "" + +#: src/router/index.js:51 +msgid "Modify Sites" +msgstr "" + +#: src/router/index.js:104 +msgid "Not Found" +msgstr "" + +#: src/router/index.js:128 +msgid "OK" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:96 +msgid "Physical memory:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:38 +msgid "Server status" +msgstr "" + +#: src/router/index.js:35 +msgid "Sites" +msgstr "" + +#: src/router/index.js:43 +msgid "Sites List" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:32 +msgid "Storage" +msgstr "" + +#: src/router/index.js:123 +msgid "System message" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:124 +msgid "Total: " +msgstr "" + +#: src/views/dashboard/DashBoard.vue:12 +msgid "Uptime" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Used:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:123 +msgid "Used: " +msgstr "" + +#: src/router/index.js:27 +msgid "Users" +msgstr "" diff --git a/frontend/src/locale/en/LC_MESSAGES/app.po~ b/frontend/src/locale/en/LC_MESSAGES/app.po~ new file mode 100644 index 00000000..60380c61 --- /dev/null +++ b/frontend/src/locale/en/LC_MESSAGES/app.po~ @@ -0,0 +1,123 @@ +msgid "" +msgstr "" +"Project-Id-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" +"Generated-By: easygettext\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/router/index.js:98 +msgid "404 Not Found" +msgstr "" + +#: src/router/index.js:76 +msgid "About" +msgstr "" + +#: src/router/index.js:47 +msgid "Add Sites" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Cached: " +msgstr "" + +#: src/router/index.js:60 +msgid "Config" +msgstr "" + +#: src/router/index.js:19 +msgid "Dashboard" +msgstr "" + +#: src/router/index.js:124 +msgid "Detected version update, this page will automatically refresh." +msgstr "" + +#: src/views/dashboard/DashBoard.vue:95 +msgid "Free:" +msgstr "" + +#: src/router/index.js:12 +msgid "Home" +msgstr "" + +#: src/router/index.js:86 +msgid "Install" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:13 +msgid "Load averages" +msgstr "" + +#: src/router/index.js:92 +msgid "Login" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:23 +msgid "Memory" +msgstr "" + +#: src/router/index.js:68 +msgid "Modify Config" +msgstr "" + +#: src/router/index.js:51 +msgid "Modify Sites" +msgstr "" + +#: src/router/index.js:104 +msgid "Not Found" +msgstr "" + +#: src/router/index.js:128 +msgid "OK" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:96 +msgid "Physical memory:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:38 +msgid "Server status" +msgstr "" + +#: src/router/index.js:35 +msgid "Sites" +msgstr "" + +#: src/router/index.js:43 +msgid "Sites List" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:32 +msgid "Storage" +msgstr "" + +#: src/router/index.js:123 +msgid "System message" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:124 +msgid "Total: " +msgstr "" + +#: src/views/dashboard/DashBoard.vue:12 +msgid "Uptime" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Used:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:123 +msgid "Used: " +msgstr "" + +#: src/router/index.js:27 +msgid "Users" +msgstr "" diff --git a/frontend/src/locale/zh_CN/LC_MESSAGES/app.mo b/frontend/src/locale/zh_CN/LC_MESSAGES/app.mo new file mode 100644 index 0000000000000000000000000000000000000000..a415c8de00e0d3d7b414c096ffc420eb1e461cb3 GIT binary patch literal 1563 zcmZXST}&KR6vt0(wRLN)V*RR`+(%7Zq-jl>F=`M>B?2V^#+Vp0FqhpiyEB`ayVW(C zP~zf(#b7L@&>CE84gCX_kn`;a`TR+c;~TaAS@0g%Eg;wF29b*10Ph3e1UcRTIsSbx1`dOqe;m9Q zoYeMLAm_gV^8F=kU)T2c;CA$S3w!|QKSC_uzYVgE0OY)XX#bxe>)M872f^JSpT7ul z+)>RgkmLKb-LGkDe@62Ia4+tS>GK(o`zvbyg7&Y2obQ&lf715P;4b(hZT}APJpKZA zgS#M#b?w80KPi7_v{37T=d`&V!^=b19K-W|5S#mAExeG9?#Jd_k792wu8q;v)+3ty zA2sNA*35I|9(l30eYLmxgTE=S{n!ul%b})2qRUmH&CNO%HTSz&Ma`BadTb?qYB2|r z(lV&Ubq4JOwVHmi-!(mpTBVW$N?PK$^nBZOL^flYN;W^C$_Y;ndeToeQky5GK`*;$N$rlWa7Z1lX$ceQ5bMKA*ba5dwCm-l)3xluoX{e) zRTsD={n#tioy_@MNu+CW2K7h}2?YwMtWWib+EaAczM>xGay9D7`AVh{<@;>*x)5Xt z>dPn_0{eWPKikAA7!bKge$@pdczTD^Zm#JZ2gUzNvgo<_VCvw*9^^i{mqGaWx= zqLv|=|1*w+bkHuQh>K1li`wyCX{HU~xQ_hCXNdQbZ?$yAI@>#sY?V9E*c8J+lyp!b zmq9fp-&N0KQl{-ZCkB$H=S%f`UvFFd@YX$6GAOzoa0)RJrj9g{!4t z?2G8~bToXOqP5S0Z_XIBkspuB^HeEasut&>vu7wgKNMd37{SqKAv|{_Ji8p8Ui@wC zWIb1~I8s@gseW`R7@G?Ut2p{)XqcjlH#VlOBH7ocagBoc(dzj;MN6fqG+SMst(MCa zO_zf5Bn2aRl+{%$>+|6$NU15(#{aZmC`U6NQZ#xoni#1^8x)=!55|hY^jtKy5)Pfv z88m{z6j~va35Msih;XG4o>-u8s1)SC#XnSCpQsj3hEppWQ_B>rUageZqf>Lnzg`8w I5f)bIZ@@IcbpQYW literal 0 HcmV?d00001 diff --git a/frontend/src/locale/zh_CN/LC_MESSAGES/app.po b/frontend/src/locale/zh_CN/LC_MESSAGES/app.po new file mode 100644 index 00000000..3b91a26d --- /dev/null +++ b/frontend/src/locale/zh_CN/LC_MESSAGES/app.po @@ -0,0 +1,125 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \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" +"Generated-By: easygettext\n" +"X-Generator: Poedit 3.0.1\n" + +#: src/router/index.js:98 +msgid "404 Not Found" +msgstr "404 找不到页面" + +#: src/router/index.js:76 +msgid "About" +msgstr "关于" + +#: src/router/index.js:47 +msgid "Add Sites" +msgstr "添加站点" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Cached:" +msgstr "缓存:" + +#: src/router/index.js:60 +msgid "Config" +msgstr "配置" + +#: src/router/index.js:19 +msgid "Dashboard" +msgstr "仪表盘" + +#: src/router/index.js:124 +msgid "Detected version update, this page will automatically refresh." +msgstr "检测到版本更新,页面将会自动刷新。" + +#: src/views/dashboard/DashBoard.vue:95 +msgid "Free:" +msgstr "空闲:" + +#: src/router/index.js:12 +msgid "Home" +msgstr "首页" + +#: src/router/index.js:86 +msgid "Install" +msgstr "安装" + +#: src/views/dashboard/DashBoard.vue:13 +msgid "Load averages" +msgstr "系统负载" + +#: src/router/index.js:92 +msgid "Login" +msgstr "登录" + +#: src/views/dashboard/DashBoard.vue:23 +msgid "Memory" +msgstr "内存" + +#: src/router/index.js:68 +msgid "Modify Config" +msgstr "配置修改" + +#: src/router/index.js:51 +msgid "Modify Sites" +msgstr "站点修改" + +#: src/router/index.js:104 +msgid "Not Found" +msgstr "找不到页面" + +#: src/router/index.js:128 +msgid "OK" +msgstr "好的" + +#: src/views/dashboard/DashBoard.vue:96 +msgid "Physical memory:" +msgstr "物理内存:" + +#: src/views/dashboard/DashBoard.vue:38 +msgid "Server status" +msgstr "服务器状态" + +#: src/router/index.js:35 +msgid "Sites" +msgstr "站点" + +#: src/router/index.js:43 +msgid "Sites List" +msgstr "站点列表" + +#: src/views/dashboard/DashBoard.vue:32 +msgid "Storage" +msgstr "存储" + +#: src/router/index.js:123 +msgid "System message" +msgstr "系统消息" + +#: src/views/dashboard/DashBoard.vue:124 +msgid "Total: " +msgstr "总共: " + +#: src/views/dashboard/DashBoard.vue:12 +msgid "Uptime" +msgstr "运行时间" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Used:" +msgstr "已使用:" + +#: src/views/dashboard/DashBoard.vue:123 +msgid "Used: " +msgstr "已使用: " + +#: src/router/index.js:27 +msgid "Users" +msgstr "用户" diff --git a/frontend/src/locale/zh_CN/LC_MESSAGES/app.po~ b/frontend/src/locale/zh_CN/LC_MESSAGES/app.po~ new file mode 100644 index 00000000..1a3d823a --- /dev/null +++ b/frontend/src/locale/zh_CN/LC_MESSAGES/app.po~ @@ -0,0 +1,125 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \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" +"Generated-By: easygettext\n" +"X-Generator: Poedit 3.0.1\n" + +#: src/router/index.js:98 +msgid "404 Not Found" +msgstr "404 找不到页面" + +#: src/router/index.js:76 +msgid "About" +msgstr "关于" + +#: src/router/index.js:47 +msgid "Add Sites" +msgstr "添加站点" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Cached: " +msgstr "缓存: " + +#: src/router/index.js:60 +msgid "Config" +msgstr "配置" + +#: src/router/index.js:19 +msgid "Dashboard" +msgstr "仪表盘" + +#: src/router/index.js:124 +msgid "Detected version update, this page will automatically refresh." +msgstr "检测到版本更新,页面将会自动刷新。" + +#: src/views/dashboard/DashBoard.vue:95 +msgid "Free:" +msgstr "空闲:" + +#: src/router/index.js:12 +msgid "Home" +msgstr "首页" + +#: src/router/index.js:86 +msgid "Install" +msgstr "安装" + +#: src/views/dashboard/DashBoard.vue:13 +msgid "Load averages" +msgstr "系统负载" + +#: src/router/index.js:92 +msgid "Login" +msgstr "登录" + +#: src/views/dashboard/DashBoard.vue:23 +msgid "Memory" +msgstr "内存" + +#: src/router/index.js:68 +msgid "Modify Config" +msgstr "配置修改" + +#: src/router/index.js:51 +msgid "Modify Sites" +msgstr "站点修改" + +#: src/router/index.js:104 +msgid "Not Found" +msgstr "找不到页面" + +#: src/router/index.js:128 +msgid "OK" +msgstr "好的" + +#: src/views/dashboard/DashBoard.vue:96 +msgid "Physical memory:" +msgstr "物理内存:" + +#: src/views/dashboard/DashBoard.vue:38 +msgid "Server status" +msgstr "服务器状态" + +#: src/router/index.js:35 +msgid "Sites" +msgstr "站点" + +#: src/router/index.js:43 +msgid "Sites List" +msgstr "站点列表" + +#: src/views/dashboard/DashBoard.vue:32 +msgid "Storage" +msgstr "存储" + +#: src/router/index.js:123 +msgid "System message" +msgstr "系统消息" + +#: src/views/dashboard/DashBoard.vue:124 +msgid "Total: " +msgstr "总共: " + +#: src/views/dashboard/DashBoard.vue:12 +msgid "Uptime" +msgstr "运行时间" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Used:" +msgstr "已使用:" + +#: src/views/dashboard/DashBoard.vue:123 +msgid "Used: " +msgstr "已使用: " + +#: src/router/index.js:27 +msgid "Users" +msgstr "用户" diff --git a/frontend/src/locale/zh_TW/LC_MESSAGES/app.po b/frontend/src/locale/zh_TW/LC_MESSAGES/app.po new file mode 100644 index 00000000..6095b829 --- /dev/null +++ b/frontend/src/locale/zh_TW/LC_MESSAGES/app.po @@ -0,0 +1,122 @@ +msgid "" +msgstr "" +"Project-Id-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" +"Generated-By: easygettext\n" + +#: src/router/index.js:98 +msgid "404 Not Found" +msgstr "" + +#: src/router/index.js:76 +msgid "About" +msgstr "" + +#: src/router/index.js:47 +msgid "Add Sites" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Cached:" +msgstr "" + +#: src/router/index.js:60 +msgid "Config" +msgstr "" + +#: src/router/index.js:19 +msgid "Dashboard" +msgstr "" + +#: src/router/index.js:124 +msgid "Detected version update, this page will automatically refresh." +msgstr "" + +#: src/views/dashboard/DashBoard.vue:95 +msgid "Free:" +msgstr "" + +#: src/router/index.js:12 +msgid "Home" +msgstr "" + +#: src/router/index.js:86 +msgid "Install" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:13 +msgid "Load averages" +msgstr "" + +#: src/router/index.js:92 +msgid "Login" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:23 +msgid "Memory" +msgstr "" + +#: src/router/index.js:68 +msgid "Modify Config" +msgstr "" + +#: src/router/index.js:51 +msgid "Modify Sites" +msgstr "" + +#: src/router/index.js:104 +msgid "Not Found" +msgstr "" + +#: src/router/index.js:128 +msgid "OK" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:96 +msgid "Physical memory:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:38 +msgid "Server status" +msgstr "" + +#: src/router/index.js:35 +msgid "Sites" +msgstr "" + +#: src/router/index.js:43 +msgid "Sites List" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:32 +msgid "Storage" +msgstr "" + +#: src/router/index.js:123 +msgid "System message" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:124 +msgid "Total: " +msgstr "" + +#: src/views/dashboard/DashBoard.vue:12 +msgid "Uptime" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Used:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:123 +msgid "Used: " +msgstr "" + +#: src/router/index.js:27 +msgid "Users" +msgstr "" diff --git a/frontend/src/locale/zh_TW/LC_MESSAGES/app.po~ b/frontend/src/locale/zh_TW/LC_MESSAGES/app.po~ new file mode 100644 index 00000000..6bd8bd48 --- /dev/null +++ b/frontend/src/locale/zh_TW/LC_MESSAGES/app.po~ @@ -0,0 +1,122 @@ +msgid "" +msgstr "" +"Project-Id-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" +"Generated-By: easygettext\n" + +#: src/router/index.js:98 +msgid "404 Not Found" +msgstr "" + +#: src/router/index.js:76 +msgid "About" +msgstr "" + +#: src/router/index.js:47 +msgid "Add Sites" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Cached: " +msgstr "" + +#: src/router/index.js:60 +msgid "Config" +msgstr "" + +#: src/router/index.js:19 +msgid "Dashboard" +msgstr "" + +#: src/router/index.js:124 +msgid "Detected version update, this page will automatically refresh." +msgstr "" + +#: src/views/dashboard/DashBoard.vue:95 +msgid "Free:" +msgstr "" + +#: src/router/index.js:12 +msgid "Home" +msgstr "" + +#: src/router/index.js:86 +msgid "Install" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:13 +msgid "Load averages" +msgstr "" + +#: src/router/index.js:92 +msgid "Login" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:23 +msgid "Memory" +msgstr "" + +#: src/router/index.js:68 +msgid "Modify Config" +msgstr "" + +#: src/router/index.js:51 +msgid "Modify Sites" +msgstr "" + +#: src/router/index.js:104 +msgid "Not Found" +msgstr "" + +#: src/router/index.js:128 +msgid "OK" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:96 +msgid "Physical memory:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:38 +msgid "Server status" +msgstr "" + +#: src/router/index.js:35 +msgid "Sites" +msgstr "" + +#: src/router/index.js:43 +msgid "Sites List" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:32 +msgid "Storage" +msgstr "" + +#: src/router/index.js:123 +msgid "System message" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:124 +msgid "Total: " +msgstr "" + +#: src/views/dashboard/DashBoard.vue:12 +msgid "Uptime" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:94 +msgid "Used:" +msgstr "" + +#: src/views/dashboard/DashBoard.vue:123 +msgid "Used: " +msgstr "" + +#: src/router/index.js:27 +msgid "Users" +msgstr "" diff --git a/frontend/src/main.js b/frontend/src/main.js index f5e2d9d6..00c6d376 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -9,6 +9,9 @@ import NProgress from 'nprogress' import 'nprogress/nprogress.css' import utils from '@/lib/utils' import api from '@/api' +import GetTextPlugin from 'vue-gettext' +import {availableLanguages} from '@/lib/translate' +import translations from '@/translations.json' Vue.use(utils) @@ -17,6 +20,13 @@ Vue.config.productionTip = false Vue.prototype.$routeConfig = routes Vue.prototype.$api = api +Vue.use(GetTextPlugin, { + availableLanguages, + defaultLanguage: store.getters.current_language, + translations: translations, + silent: true +}) + NProgress.configure({ easing: 'ease', speed: 500, diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index b72de26b..3feb635b 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -2,20 +2,21 @@ import Vue from 'vue' import VueRouter from 'vue-router' import axios from 'axios' import store from '@/lib/store' +import $gettext from '@/lib/translate/gettext' Vue.use(VueRouter) export const routes = [ { path: '/', - name: '首页', + name: $gettext('Home'), component: () => import('@/layouts/BaseLayout'), redirect: '/dashboard', children: [ { path: 'dashboard', - component: () => import('@/views/doashboard/DashBoard'), - name: '仪表盘', + component: () => import('@/views/dashboard/DashBoard'), + name: $gettext('Dashboard'), meta: { //hiddenHeaderContent: true, icon: 'home' @@ -23,7 +24,7 @@ export const routes = [ }, { path: 'user', - name: '用户管理', + name: $gettext('Users'), component: () => import('@/views/user/User.vue'), meta: { icon: 'user' @@ -31,7 +32,7 @@ export const routes = [ }, { path: 'domain', - name: '网站管理', + name: $gettext('Sites'), component: () => import('@/layouts/BaseRouterView'), meta: { icon: 'cloud' @@ -39,24 +40,24 @@ export const routes = [ redirect: '/domain/list', children: [{ path: 'list', - name: '网站列表', + name: $gettext('Sites List'), component: () => import('@/views/domain/DomainList.vue'), }, { path: 'add', - name: '添加站点', + name: $gettext('Add Sites'), component: () => import('@/views/domain/DomainAdd.vue'), }, { path: ':name', - name: '编辑站点', + name: $gettext('Modify Sites'), component: () => import('@/views/domain/DomainEdit.vue'), meta: { hiddenInSidebar: true } - }, ] + },] }, { path: 'config', - name: '配置管理', + name: $gettext('Config'), component: () => import('@/views/config/Config.vue'), meta: { icon: 'file' @@ -64,7 +65,7 @@ export const routes = [ }, { path: 'config/:name', - name: '配置编辑', + name: $gettext('Modify Config'), component: () => import('@/views/config/ConfigEdit.vue'), meta: { hiddenInSidebar: true @@ -72,7 +73,7 @@ export const routes = [ }, { path: 'about', - name: '关于', + name: $gettext('About'), component: () => import('@/views/other/About.vue'), meta: { icon: 'info-circle' @@ -82,25 +83,25 @@ export const routes = [ }, { path: '/install', - name: '安装', + name: $gettext('Install'), component: () => import('@/views/other/Install'), meta: {noAuth: true} }, { path: '/login', - name: '登录', + name: $gettext('Login'), component: () => import('@/views/other/Login'), meta: {noAuth: true} }, { path: '/404', - name: '404 Not Found', + name: $gettext('404 Not Found'), component: () => import('@/views/other/Error'), meta: {noAuth: true, status_code: 404, error: 'Not Found'} }, { path: '*', - name: '未找到页面', + name: $gettext('Not Found'), redirect: '/404', meta: {noAuth: true} } @@ -119,12 +120,12 @@ router.beforeEach((to, from, next) => { if (!(process.env.VUE_APP_VERSION === r.data.version && Number(process.env.VUE_APP_BUILD_ID) === r.data.build_id)) { Vue.prototype.$info({ - title: '系统信息', - content: '检测到版本更新,将会自动刷新本页', + title: $gettext('System message'), + content: $gettext('Detected version update, this page will automatically refresh.'), onOk() { location.reload() }, - okText: '好的' + okText: $gettext('OK') }) } }) diff --git a/frontend/src/translations.json b/frontend/src/translations.json new file mode 100644 index 00000000..65e079c3 --- /dev/null +++ b/frontend/src/translations.json @@ -0,0 +1 @@ +{"en":{},"zh_CN":{"404 Not Found":"404 找不到页面","About":"关于","Add Sites":"添加站点","Cached:":"缓存:","Config":"配置","Dashboard":"仪表盘","Detected version update, this page will automatically refresh.":"检测到版本更新,页面将会自动刷新。","Free:":"空闲:","Home":"首页","Install":"安装","Load averages":"系统负载","Login":"登录","Memory":"内存","Modify Config":"配置修改","Modify Sites":"站点修改","Not Found":"找不到页面","OK":"好的","Physical memory:":"物理内存:","Server status":"服务器状态","Sites":"站点","Sites List":"站点列表","Storage":"存储","System message":"系统消息","Total: ":"总共: ","Uptime":"运行时间","Used:":"已使用:","Used: ":"已使用: ","Users":"用户"},"zh_TW":{}} \ No newline at end of file diff --git a/frontend/src/views/config/Config.vue b/frontend/src/views/config/Config.vue index ca0d60c5..1a37bfc5 100644 --- a/frontend/src/views/config/Config.vue +++ b/frontend/src/views/config/Config.vue @@ -17,29 +17,29 @@