This document describes the translation system architecture used in Nginx UI, specifically focusing on how vue3-gettext integrates with the Vue 3 frontend, the structure and format of translation files, and how translations are extracted from source code and loaded at runtime.
For information about the translation workflow using Weblate and how translators contribute, see Weblate Integration. For a complete list of supported languages and their completion status, see Supported Languages.
Nginx UI uses vue3-gettext, a Vue 3 port of the GNU gettext internationalization system, to manage translations across 14 languages. The system follows a standard gettext workflow: translatable strings are marked in source code, extracted to template files, translated in PO (Portable Object) files, and loaded at runtime based on the user's language preference.
Sources:
Sources:
PO (Portable Object) files are the standard format for gettext translations. Each PO file contains metadata in the header and a series of message entries mapping source strings (msgid) to translated strings (msgstr).
| Section | Description | Example |
|---|---|---|
| Header | Metadata including language, translator, plural forms | "Language: zh_CN\n" |
| Message Entry | Source string and translation | msgid "Add Site" msgstr "添加站点" |
| Context | Source code location reference | #: src/routes/modules/sites.ts:26 |
| Plural Forms | Handling singular/plural translations | msgid_plural "Certificates Status" |
| Variable Interpolation | Dynamic content in strings | "%{name}, %{email}, %{caDir}" |
#: src/language/generate.ts:37 msgid "[Nginx UI] ACME User: %{name}, Email: %{email}, CA Dir: %{caDir}" msgstr "[Nginx UI] ACME 用户:%{name},邮箱:%{email},CA 目录:%{caDir}" #: src/routes/modules/sites.ts:26 src/views/site/site_add/SiteAdd.vue:74 msgid "Add Site" msgstr "添加站点" #: src/views/certificate/components/AutoCertManagement.vue:67 #: src/views/site/site_edit/components/Cert/Cert.vue:58 msgid "Certificate Status" msgid_plural "Certificates Status" msgstr[0] "证书状态" Sources:
Each PO file begins with a header containing critical metadata:
| Header Field | Purpose |
|---|---|
Language | ISO 639-1 language code + optional region code |
Plural-Forms | Formula for plural form selection |
Last-Translator | Translator contact information |
PO-Revision-Date | Last modification timestamp |
Content-Type | Character encoding (always UTF-8) |
Sources:
Vue3-gettext provides several methods for marking strings as translatable in Vue components and TypeScript files:
| Method | Use Case | Example |
|---|---|---|
$gettext('string') | Simple translation | $gettext('Add Site') |
$ngettext(singular, plural, n) | Plural forms | $ngettext('Certificate Status', 'Certificates Status', count) |
interpolate(string, vars) | Variable substitution | interpolate('%{name}', {name: 'John'}) |
$pgettext(context, string) | Contextual translation | $pgettext('navbar', 'Home') |
Each message entry includes comments indicating where the string appears in source code:
#: src/routes/modules/sites.ts:26 #: src/views/site/site_add/SiteAdd.vue:74 msgid "Add Site" msgstr "添加站点" This enables:
Sources:
Special translation strings for dynamic messages (like certificate operations) are pre-defined in a dedicated file:
Sources:
The extraction process identifies translatable strings by scanning for:
v-translate, translate-context, translate-plural$gettext(), $ngettext(), $pgettext()gettext: for translator notesSources:
The LINGUAS file defines all available languages:
en zh_CN zh_TW fr_FR es de_DE ru_RU vi_VN ko_KR tr_TR ar uk_UA ja_JP pt_PT | Locale Code | Language | Region |
|---|---|---|
en | English | Generic |
zh_CN | Chinese | Simplified (China) |
zh_TW | Chinese | Traditional (Taiwan) |
fr_FR | French | France |
es | Spanish | Generic |
de_DE | German | Germany |
ru_RU | Russian | Russia |
vi_VN | Vietnamese | Vietnam |
ko_KR | Korean | South Korea |
tr_TR | Turkish | Turkey |
ar | Arabic | Generic (RTL support) |
uk_UA | Ukrainian | Ukraine |
ja_JP | Japanese | Japan |
pt_PT | Portuguese | Portugal |
Sources:
Different languages have different rules for pluralization. The Plural-Forms header defines the formula for each language.
| Language | Plural-Forms Formula | Description |
|---|---|---|
| English | nplurals=2; plural=(n != 1); | 0 is plural, 1 is singular |
| Chinese | nplurals=1; plural=0; | No plural distinction |
| Russian | nplurals=2; plural=(n != 1); | Complex slavic rules |
| Arabic | nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5; | Six plural forms |
In languages with multiple plural forms (like Russian or Arabic), additional msgstr[n] entries are required:
Sources:
Translation strings can contain variables that are substituted at runtime using the %{variable} syntax:
In Vue components, variables are passed as an object:
Common Variable Patterns:
| Pattern | Usage | Example PO Entry |
|---|---|---|
%{name} | User/resource names | "Auto-renewal enabled for %{name}" |
%{start}-%{end} | Ranges | "%{start}-%{end} of %{total} items" |
%{error} | Error messages | "Failed to execute, error: %{error}" |
%{groupName} | Resource groups | "Includes nodes from group %{groupName}" |
Sources:
PO entries include references to source file locations where each string is used:
#: src/components/NgxConfigEditor/NgxServer.vue:144 #: src/components/NgxConfigEditor/NgxUpstream.vue:97 #: src/language/curd.ts:19 msgid "Add" msgstr "添加" This shows the string "Add" appears in three different files, helping translators understand context.
Some entries include special comments for translators:
#: src/views/nginx_log/components/IndexingSettingsModal.vue:217 msgid "* Performance metrics measured on Apple M2 Pro (12-core) with 32GB RAM. Actual performance may vary based on your hardware configuration." msgstr "* 性能指标基于 Apple M2 Pro (12 核)和 32GB 内存测得。实际性能可能因您的硬件配置而异。" Sources:
The Nginx UI translation system architecture consists of:
%{variable} syntaxAll translation files are located in app/src/language/ with the master template at app/src/language/messages.pot and language-specific translations in subdirectories like app/src/language/zh_CN/app.po app/src/language/es/app.po etc.
Sources:
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.