Allow language selection (#191)

* Add dropdown for language

* Use vue-i18n to translate strings

* Tweak header styling

* Add Chinese languages in

* Typo

* Get language from browser (#193)

* adaptive system language

* Modify the adaptive system language

* Remove dead code

* Delete lang default values

* Move browser language detection to util

* Remove todos

* Fix global PHP dropdown

Co-authored-by: 墨娘 <61287199+moniang@users.noreply.github.com>
pull/199/head
Matt (IPv4) Cowley 2020-12-11 16:54:12 +00:00 committed by GitHub
parent 7d3290d850
commit ff88e2f322
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 539 additions and 434 deletions

5
package-lock.json generated
View File

@ -12560,6 +12560,11 @@
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
"dev": true "dev": true
}, },
"vue-i18n": {
"version": "8.22.2",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.22.2.tgz",
"integrity": "sha512-rb569fVJInPUgS/bbCxEQ9DrAoFTntuJvYoK4Fpk2VfNbA09WzdTKk57ppjz3S+ps9hW+p9H+2ASgMvojedkow=="
},
"vue-loader": { "vue-loader": {
"version": "15.9.3", "version": "15.9.3",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz", "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz",

View File

@ -53,6 +53,7 @@
"simple-js-sha2-256": "^1.0.7", "simple-js-sha2-256": "^1.0.7",
"string-similarity": "^4.0.2", "string-similarity": "^4.0.2",
"vue": "^2.6.12", "vue": "^2.6.12",
"vue-i18n": "^8.22.2",
"vue-select": "^3.10.8" "vue-select": "^3.10.8"
}, },
"devDependencies": { "devDependencies": {

View File

@ -0,0 +1,27 @@
/*
Copyright 2020 DigitalOcean
This code is licensed under the MIT License.
You may obtain a copy of the License at
https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
export default 'en';

View File

@ -46,5 +46,5 @@ export default {
reverseProxy: 'Reverse proxy', reverseProxy: 'Reverse proxy',
reverseProxyLower: 'reverse proxy', reverseProxyLower: 'reverse proxy',
restrict: 'Restrict', restrict: 'Restrict',
listen: 'listen', path: 'Path',
}; };

View File

@ -29,6 +29,9 @@ import common from '../common';
export default { export default {
title: `${common.nginx}Config`, title: `${common.nginx}Config`,
description: `The easiest way to configure a performant, secure, and stable ${common.nginx} server.`, description: `The easiest way to configure a performant, secure, and stable ${common.nginx} server.`,
en: 'English',
zhCN: 'Chinese (simplified)',
zhTW: 'Chinese (traditional)',
singleColumnMode: 'Single column mode', singleColumnMode: 'Single column mode',
splitColumnMode: 'Split column mode', splitColumnMode: 'Split column mode',
perWebsiteConfig: 'Per-website config', perWebsiteConfig: 'Per-website config',

View File

@ -31,5 +31,4 @@ export default {
reverseProxyCannotBeEnabledWithPhp: `${common.reverseProxy} cannot be enabled whilst ${common.php} is enabled.`, reverseProxyCannotBeEnabledWithPhp: `${common.reverseProxy} cannot be enabled whilst ${common.php} is enabled.`,
reverseProxyCannotBeEnabledWithPython: `${common.reverseProxy} cannot be enabled whilst ${common.python} is enabled.`, reverseProxyCannotBeEnabledWithPython: `${common.reverseProxy} cannot be enabled whilst ${common.python} is enabled.`,
enableReverseProxy: `${common.enable} ${common.reverseProxyLower}`, enableReverseProxy: `${common.enable} ${common.reverseProxyLower}`,
path: 'Path',
}; };

View File

@ -31,6 +31,5 @@ export default {
fallbackRoutingPhpPath: `Fallback routing ${common.php} path`, fallbackRoutingPhpPath: `Fallback routing ${common.php} path`,
legacyPhpRouting: `Legacy ${common.php} routing`, legacyPhpRouting: `Legacy ${common.php} routing`,
enableLegacyRouting: `${common.enable} legacy routing`, enableLegacyRouting: `${common.enable} legacy routing`,
path: 'Path',
routing: 'Routing', routing: 'Routing',
}; };

View File

@ -26,13 +26,12 @@ THE SOFTWARE.
export default { export default {
domain: 'Domain', domain: 'Domain',
path: 'Path',
documentRoot: 'Document root', documentRoot: 'Document root',
oneOrMoreOtherDomainsAreAlsoNamed: 'One or more other domains are also named', oneOrMoreOtherDomainsAreAlsoNamed: 'One or more other domains are also named',
thisWillCauseIssuesWithConfigGeneration: 'This will cause issues with config generation.', thisWillCauseIssuesWithConfigGeneration: 'This will cause issues with config generation.',
wwwSubdomain: 'www subdomain', wwwSubdomain: 'www subdomain',
cdnSubdomain: 'CDN subdomain', cdnSubdomain: 'CDN subdomain',
redirectSubdomains: 'Redirect subdomains', redirectSubdomains: 'Redirect subdomains',
routing: 'Routing',
server: 'Server', server: 'Server',
listen: 'listen',
}; };

View File

@ -24,9 +24,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
import en from './en'; export { default as en } from './en';
export { default as zhCN } from './zh-cn';
const lang = 'en'; export { default as zhTW } from './zh-tw';
const packs = { en };
export default packs[lang];

View File

@ -46,5 +46,5 @@ export default {
reverseProxy: '反向代理', reverseProxy: '反向代理',
reverseProxyLower: '反向代理', reverseProxyLower: '反向代理',
restrict: '限制', restrict: '限制',
listen: '监听', path: '路径',
}; };

View File

@ -29,6 +29,9 @@ import common from '../common';
export default { export default {
title: `${common.nginx} 配置`, title: `${common.nginx} 配置`,
description: `配置高性能、安全、稳定的${common.nginx}服务器的最简单方法。`, description: `配置高性能、安全、稳定的${common.nginx}服务器的最简单方法。`,
en: '英语',
zhCN: '简体中文',
zhTW: '繁体中文',
singleColumnMode: '垂直模式', singleColumnMode: '垂直模式',
splitColumnMode: '水平模式', splitColumnMode: '水平模式',
perWebsiteConfig: '站点配置', perWebsiteConfig: '站点配置',

View File

@ -31,5 +31,4 @@ export default {
reverseProxyCannotBeEnabledWithPhp: `${common.reverseProxy}在启用${common.php}时无法启用。`, reverseProxyCannotBeEnabledWithPhp: `${common.reverseProxy}在启用${common.php}时无法启用。`,
reverseProxyCannotBeEnabledWithPython: `${common.reverseProxy}在启用${common.python}时无法启用。`, reverseProxyCannotBeEnabledWithPython: `${common.reverseProxy}在启用${common.python}时无法启用。`,
enableReverseProxy: `${common.enable} ${common.reverseProxyLower}`, enableReverseProxy: `${common.enable} ${common.reverseProxyLower}`,
path: '路径',
}; };

View File

@ -31,6 +31,5 @@ export default {
fallbackRoutingPhpPath: `后备路由${common.php}路径`, fallbackRoutingPhpPath: `后备路由${common.php}路径`,
legacyPhpRouting: `传统${common.php}路由`, legacyPhpRouting: `传统${common.php}路由`,
enableLegacyRouting: `${common.enable}传统路由`, enableLegacyRouting: `${common.enable}传统路由`,
path: '路径',
routing: '路由设置', routing: '路由设置',
}; };

View File

@ -26,13 +26,12 @@ THE SOFTWARE.
export default { export default {
domain: '站点', domain: '站点',
path: '路径',
documentRoot: '运行目录', documentRoot: '运行目录',
oneOrMoreOtherDomainsAreAlsoNamed: '发现了重复的域名', oneOrMoreOtherDomainsAreAlsoNamed: '发现了重复的域名',
thisWillCauseIssuesWithConfigGeneration: '这将导致生成配置出现问题。', thisWillCauseIssuesWithConfigGeneration: '这将导致生成配置出现问题。',
wwwSubdomain: 'www 子域名', wwwSubdomain: 'www 子域名',
cdnSubdomain: 'CDN 子域名', cdnSubdomain: 'CDN 子域名',
redirectSubdomains: '子域名重定向', redirectSubdomains: '子域名重定向',
routing: '路由设置',
server: '服务', server: '服务',
listen: '监听',
}; };

View File

@ -46,5 +46,5 @@ export default {
reverseProxy: '反向代理', reverseProxy: '反向代理',
reverseProxyLower: '反向代理', reverseProxyLower: '反向代理',
restrict: '限制', restrict: '限制',
listen: '監聽', path: '路徑',
}; };

View File

@ -29,6 +29,9 @@ import common from '../common';
export default { export default {
title: `${common.nginx} 配寘`, title: `${common.nginx} 配寘`,
description: `配寘高性能、安全、穩定的${common.nginx}服務器的最簡單方法。`, description: `配寘高性能、安全、穩定的${common.nginx}服務器的最簡單方法。`,
en: '英語',
zhCN: '簡體中文',
zhTW: '繁體中文',
singleColumnMode: '垂直模式', singleColumnMode: '垂直模式',
splitColumnMode: '水准模式', splitColumnMode: '水准模式',
perWebsiteConfig: '網站配寘', perWebsiteConfig: '網站配寘',

View File

@ -31,5 +31,4 @@ export default {
reverseProxyCannotBeEnabledWithPhp: `${common.reverseProxy}在啟用${common.php}時無法啟用。`, reverseProxyCannotBeEnabledWithPhp: `${common.reverseProxy}在啟用${common.php}時無法啟用。`,
reverseProxyCannotBeEnabledWithPython: `${common.reverseProxy}在啟用${common.python}時無法啟用。`, reverseProxyCannotBeEnabledWithPython: `${common.reverseProxy}在啟用${common.python}時無法啟用。`,
enableReverseProxy: `${common.enable} ${common.reverseProxyLower}`, enableReverseProxy: `${common.enable} ${common.reverseProxyLower}`,
path: '路徑',
}; };

View File

@ -31,6 +31,5 @@ export default {
fallbackRoutingPhpPath: `後備路由${common.php}路徑`, fallbackRoutingPhpPath: `後備路由${common.php}路徑`,
legacyPhpRouting: `傳統${common.php}路由`, legacyPhpRouting: `傳統${common.php}路由`,
enableLegacyRouting: `${common.enable}傳統路由`, enableLegacyRouting: `${common.enable}傳統路由`,
path: '路徑',
routing: '路由設定', routing: '路由設定',
}; };

View File

@ -26,13 +26,12 @@ THE SOFTWARE.
export default { export default {
domain: '網站', domain: '網站',
path: '路徑',
documentRoot: '運行目錄', documentRoot: '運行目錄',
oneOrMoreOtherDomainsAreAlsoNamed: '發現了重復的域名', oneOrMoreOtherDomainsAreAlsoNamed: '發現了重復的域名',
thisWillCauseIssuesWithConfigGeneration: '這將導致生成配置出現問題。', thisWillCauseIssuesWithConfigGeneration: '這將導致生成配置出現問題。',
wwwSubdomain: 'www 子域名', wwwSubdomain: 'www 子域名',
cdnSubdomain: 'CDN 子域名', cdnSubdomain: 'CDN 子域名',
redirectSubdomains: '子域名重定向', redirectSubdomains: '子域名重定向',
routing: '路由設定',
server: '服務', server: '服務',
listen: '監聽',
}; };

View File

@ -26,12 +26,21 @@ THE SOFTWARE.
import './scss/style.scss'; import './scss/style.scss';
import Vue from 'vue'; import Vue from 'vue';
import VueI18n from 'vue-i18n';
import './util/prism_bundle'; import './util/prism_bundle';
import App from './templates/app'; import App from './templates/app';
import i18n from './i18n'; import * as i18nPacks from './i18n';
import i18nDefault from './i18n/default';
document.head.title = i18n.templates.app.title; Vue.use(VueI18n);
const i18n = new VueI18n({
locale: i18nDefault,
fallbackLocale: i18nDefault,
messages: i18nPacks,
});
new Vue({ new Vue({
i18n,
render: h => h(App), render: h => h(App),
}).$mount('#app'); }).$mount('#app');

View File

@ -0,0 +1,47 @@
/*
Copyright 2020 DigitalOcean
This code is licensed under the MIT License.
You may obtain a copy of the License at
https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
.header {
padding: ($margin * 2) $margin ($margin * 1.5);
@media (min-width: $breakpoint) {
padding: ($margin * 3.75) 0 ($margin * .5);
}
.container {
form {
.input-container {
margin: 0;
}
.buttons {
> * {
margin: 0 0 1rem;
}
}
}
}
}

View File

@ -36,8 +36,15 @@ THE SOFTWARE.
box-shadow: 0 0 2px rgba($success, .5); box-shadow: 0 0 2px rgba($success, .5);
.vs__selected { .vs__selected {
height: $height;
position: unset;
top: .75em; top: .75em;
} }
.vs__search {
position: absolute;
width: 100%;
}
} }
} }
@ -60,6 +67,17 @@ THE SOFTWARE.
margin: 0; margin: 0;
padding: 0; padding: 0;
transition: opacity $transition; transition: opacity $transition;
.has-icon {
align-items: center;
display: flex;
.icon {
color: $dark-grey;
font-size: 1.25rem;
margin: 0 .5rem 0 0;
}
}
} }
.vs__search { .vs__search {
@ -76,7 +94,13 @@ THE SOFTWARE.
} }
.vs__actions { .vs__actions {
padding: 0; padding: 0 0 0 .25rem;
}
}
.vs__dropdown-menu {
.vs__dropdown-option {
white-space: normal;
} }
} }
} }

View File

@ -41,6 +41,7 @@ $highlight: #f2c94c;
$vs-state-active-bg: $primary; $vs-state-active-bg: $primary;
@import "~vue-select/src/scss/vue-select"; @import "~vue-select/src/scss/vue-select";
@import "header";
@import "tabs"; @import "tabs";
@import "panel"; @import "panel";
@import "fields"; @import "fields";

View File

@ -26,18 +26,30 @@ THE SOFTWARE.
<template> <template>
<div class="all do-bulma"> <div class="all do-bulma">
<Header :title="i18n.templates.app.title"> <Header :title="$t('templates.app.title')">
<template #description> <template #description>
{{ i18n.templates.app.description }} {{ $t('templates.app.description') }}
</template> </template>
<template #header> <template #header>
</template> </template>
<template #buttons> <template #buttons>
<VueSelect v-model="lang"
:options="i18nPacks"
:clearable="false"
:reduce="s => s.value"
>
<template #selected-option="{ label }">
<span class="has-icon">
<i class="icon fas fa-language"></i>
<span>{{ label }}</span>
</span>
</template>
</VueSelect>
<a v-if="splitColumn" class="button is-primary is-outline is-hidden-touch" @click="splitColumnToggle"> <a v-if="splitColumn" class="button is-primary is-outline is-hidden-touch" @click="splitColumnToggle">
{{ i18n.templates.app.singleColumnMode }} {{ $t('templates.app.singleColumnMode') }}
</a> </a>
<a v-else class="button is-primary is-hidden-touch" @click="splitColumnToggle"> <a v-else class="button is-primary is-hidden-touch" @click="splitColumnToggle">
{{ i18n.templates.app.splitColumnMode }} {{ $t('templates.app.splitColumnMode') }}
</a> </a>
</template> </template>
</Header> </Header>
@ -45,7 +57,7 @@ THE SOFTWARE.
<div class="main container" :style="{ display: ready ? undefined : 'none' }"> <div class="main container" :style="{ display: ready ? undefined : 'none' }">
<div class="columns is-multiline"> <div class="columns is-multiline">
<div :class="`column ${splitColumn ? 'is-half' : 'is-full'} is-full-touch`"> <div :class="`column ${splitColumn ? 'is-half' : 'is-full'} is-full-touch`">
<h2>{{ i18n.templates.app.perWebsiteConfig }}</h2> <h2>{{ $t('templates.app.perWebsiteConfig') }}</h2>
<div class="tabs"> <div class="tabs">
<ul> <ul>
@ -58,7 +70,7 @@ THE SOFTWARE.
</a> </a>
</li> </li>
<li> <li>
<a @click="add"><i class="fas fa-plus"></i> {{ i18n.templates.app.addSite }}</a> <a @click="add"><i class="fas fa-plus"></i> {{ $t('templates.app.addSite') }}</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -70,15 +82,15 @@ THE SOFTWARE.
></Domain> ></Domain>
</template> </template>
<h2>{{ i18n.templates.app.globalConfig }}</h2> <h2>{{ $t('templates.app.globalConfig') }}</h2>
<Global :data="global"></Global> <Global :data="global"></Global>
<h2>{{ i18n.templates.app.setup }}</h2> <h2>{{ $t('templates.app.setup') }}</h2>
<Setup :data="{ domains: domains.filter(d => d !== null), global, confFiles }"></Setup> <Setup :data="{ domains: domains.filter(d => d !== null), global, confFiles }"></Setup>
</div> </div>
<div :class="`column ${splitColumn ? 'is-half' : 'is-full'} is-full-touch`"> <div :class="`column ${splitColumn ? 'is-half' : 'is-full'} is-full-touch`">
<h2>{{ i18n.templates.app.configFiles }}</h2> <h2>{{ $t('templates.app.configFiles') }}</h2>
<div ref="files" class="columns is-multiline files"> <div ref="files" class="columns is-multiline files">
<template v-for="confContents in confFilesOutput"> <template v-for="confContents in confFilesOutput">
<component <component
@ -102,6 +114,7 @@ THE SOFTWARE.
import clone from 'clone'; import clone from 'clone';
import sha2_256 from 'simple-js-sha2-256'; import sha2_256 from 'simple-js-sha2-256';
import escape from 'escape-html'; import escape from 'escape-html';
import VueSelect from 'vue-select';
import Header from 'do-vue/src/templates/header'; import Header from 'do-vue/src/templates/header';
import diff from 'files-diff'; import diff from 'files-diff';
@ -109,8 +122,10 @@ THE SOFTWARE.
import importData from '../util/import_data'; import importData from '../util/import_data';
import isObject from '../util/is_object'; import isObject from '../util/is_object';
import analytics from '../util/analytics'; import analytics from '../util/analytics';
import browserLanguage from '../util/browser_language';
import i18n from '../i18n'; import * as i18nPacks from '../i18n';
import i18nDefault from '../i18n/default';
import generators from '../generators'; import generators from '../generators';
import Domain from './domain'; import Domain from './domain';
@ -124,6 +139,7 @@ THE SOFTWARE.
name: 'App', name: 'App',
components: { components: {
Header, Header,
VueSelect,
Footer, Footer,
Domain, Domain,
Global, Global,
@ -134,9 +150,18 @@ THE SOFTWARE.
}, },
data() { data() {
return { return {
i18n,
domains: [], domains: [],
global: Global.delegated, global: {
...Global.delegated,
app: {
lang: {
default: i18nDefault,
value: i18nDefault,
computed: i18nDefault,
enabled: true,
},
},
},
active: 0, active: 0,
ready: false, ready: false,
splitColumn: false, splitColumn: false,
@ -152,6 +177,23 @@ THE SOFTWARE.
confFiles() { confFiles() {
return generators(this.$data.domains.filter(d => d !== null), this.$data.global); return generators(this.$data.domains.filter(d => d !== null), this.$data.global);
}, },
lang: {
get() {
return this.$data.global.app.lang.value;
},
set (value) {
this.$data.global.app.lang.value = value;
this.$data.global.app.lang.computed = value;
},
},
i18nPacks() {
return Object.keys(i18nPacks).map(pack => ({
label: this.$t(`templates.app.${pack}`) + (pack === this.$i18n.locale
? ''
: ` - ${this.$t(`templates.app.${pack}`, pack)}`),
value: pack,
}));
},
}, },
watch: { watch: {
confFiles(newConf, oldConf) { confFiles(newConf, oldConf) {
@ -164,13 +206,29 @@ THE SOFTWARE.
// Check next tick to see if anything has changed again // Check next tick to see if anything has changed again
this.$nextTick(() => this.checkChange(newConf)); this.$nextTick(() => this.checkChange(newConf));
}, },
'$data.global.app.lang': {
handler(data) {
// Ensure valid pack
if (!(data.value in i18nPacks)) data.computed = data.default;
// Update the locale
this.$i18n.locale = data.computed;
},
deep: true,
},
}, },
mounted() { async mounted() {
// Import any data from the URL query params, defaulting to one domain // Import any data from the URL query params, defaulting to one domain
// Fallback to the window hash if no search query params, from the Angular version of nginxconfig // Fallback to the window hash if no search query params, from the Angular version of nginxconfig
// The config file watcher will handle setting the app as ready // The config file watcher will handle setting the app as ready
const query = window.location.search || window.location.hash.slice(1); const query = window.location.search || window.location.hash.slice(1);
importData(query, this.$data.domains, this.$data.global, this.$nextTick); const imported = await importData(query, this.$data.domains, this.$data.global, this.$nextTick);
// Apply browser language if not specified in query
if (!imported || !imported.global || !imported.global.app || !imported.global.app.lang) {
const language = browserLanguage();
if (language) this.lang = language;
}
// Send an initial GA event for column mode // Send an initial GA event for column mode
this.splitColumnEvent(true); this.splitColumnEvent(true);

View File

@ -34,7 +34,7 @@ THE SOFTWARE.
<div class="tabs"> <div class="tabs">
<ul> <ul>
<li v-for="tab in tabs" :class="tabClass(tab.key)"> <li v-for="tab in tabs" :class="tabClass(tab.key)">
<a @click="active = tab.key">{{ tab.display }}{{ changes(tab.key) }}</a> <a @click="active = tab.key">{{ $t(tab.display) }}{{ changes(tab.key) }}</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -49,10 +49,10 @@ THE SOFTWARE.
<div class="navigation-buttons"> <div class="navigation-buttons">
<a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab"> <a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab">
<i class="fas fa-long-arrow-alt-left"></i> <span>{{ i18n.common.back }}</span> <i class="fas fa-long-arrow-alt-left"></i> <span>{{ $t('common.back') }}</span>
</a> </a>
<a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab"> <a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab">
<span>{{ i18n.common.next }}</span> <i class="fas fa-long-arrow-alt-right"></i> <span>{{ $t('common.next') }}</span> <i class="fas fa-long-arrow-alt-right"></i>
</a> </a>
</div> </div>
</div> </div>
@ -60,7 +60,6 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../i18n';
import isChanged from '../util/is_changed'; import isChanged from '../util/is_changed';
import Presets from './domain_sections/presets'; import Presets from './domain_sections/presets';
import * as Sections from './domain_sections'; import * as Sections from './domain_sections';
@ -86,7 +85,6 @@ THE SOFTWARE.
}, },
data() { data() {
return { return {
i18n,
active: tabs[0].key, active: tabs[0].key,
tabs, tabs,
}; };

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
<div> <div>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.https }}</label> <label class="label">{{ $t('common.https') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -36,7 +36,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="https" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="https" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.https.enableEncryptedSslConnection }} {{ $t('templates.domainSections.https.enableEncryptedSslConnection') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -46,7 +46,7 @@ THE SOFTWARE.
<div v-if="http2Enabled" class="field is-horizontal"> <div v-if="http2Enabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.https.http2 }}</label> <label class="label">{{ $t('templates.domainSections.https.http2') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -54,7 +54,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="http2" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="http2" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.https.enableHttp2Connections }} {{ $t('templates.domainSections.https.enableHttp2Connections') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -64,7 +64,7 @@ THE SOFTWARE.
<div v-if="forceHttpsEnabled" class="field is-horizontal"> <div v-if="forceHttpsEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.https.forceHttps }}</label> <label class="label">{{ $t('templates.domainSections.https.forceHttps') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -84,7 +84,7 @@ THE SOFTWARE.
<div v-if="hstsEnabled" class="field is-horizontal is-aligned-top"> <div v-if="hstsEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.https.hsts }}</label> <label class="label">{{ $t('templates.domainSections.https.hsts') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -92,7 +92,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="hsts" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="hsts" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.https.enableStrictTransportSecurity }} {{ $t('templates.domainSections.https.enableStrictTransportSecurity') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -101,7 +101,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="hstsSubdomains" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="hstsSubdomains" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.https.enableIncludeSubDomains }} {{ $t('templates.domainSections.https.enableIncludeSubDomains') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -110,7 +110,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="hstsPreload" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="hstsPreload" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.https.enablePreload }} {{ $t('templates.domainSections.https.enablePreload') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -120,7 +120,7 @@ THE SOFTWARE.
<div v-if="certTypeEnabled" class="field is-horizontal is-aligned-top"> <div v-if="certTypeEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.https.certificationType }}</label> <label class="label">{{ $t('templates.domainSections.https.certificationType') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -130,7 +130,7 @@ THE SOFTWARE.
<div class="radio"> <div class="radio">
<PrettyRadio v-model="certType" :value="value" class="p-default p-round p-fill p-icon"> <PrettyRadio v-model="certType" :value="value" class="p-default p-round p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ name }} {{ $t(name) }}
</PrettyRadio> </PrettyRadio>
</div> </div>
</div> </div>
@ -140,7 +140,7 @@ THE SOFTWARE.
<div v-if="letsEncryptEmailEnabled" class="field is-horizontal"> <div v-if="letsEncryptEmailEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.https.letsEncryptEmail }}</label> <label class="label">{{ $t('templates.domainSections.https.letsEncryptEmail') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -194,7 +194,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import PrettyRadio from 'pretty-checkbox-vue/radio'; import PrettyRadio from 'pretty-checkbox-vue/radio';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -226,8 +225,8 @@ THE SOFTWARE.
certType: { certType: {
default: 'letsEncrypt', default: 'letsEncrypt',
options: { options: {
letsEncrypt: i18n.common.letsEncrypt, letsEncrypt: 'common.letsEncrypt', // i18n key
custom: i18n.templates.domainSections.https.customCertificate, custom: 'templates.domainSections.https.customCertificate', // i18n key
}, },
enabled: true, enabled: true,
}, },
@ -248,7 +247,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainHTTPS', // Component name name: 'DomainHTTPS', // Component name
display: i18n.common.https, // Display name for tab display: 'common.https', // Display name for tab (i18n key)
key: 'https', // Key for data in parent key: 'https', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -258,11 +257,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'https'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'https'), // Getters & setters for the delegated data
watch: { watch: {
// Disable everything if https is disabled // Disable everything if https is disabled

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
<div> <div>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">access_log {{ i18n.templates.domainSections.logging.byDomain }}</label> <label class="label">access_log {{ $t('templates.domainSections.logging.byDomain') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -36,7 +36,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="accessLog" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="accessLog" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.logging.enableForThisDomain }} {{ $t('templates.domainSections.logging.enableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -46,7 +46,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">error_log {{ i18n.templates.domainSections.logging.byDomain }}</label> <label class="label">error_log {{ $t('templates.domainSections.logging.byDomain') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -54,7 +54,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="errorLog" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="errorLog" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.logging.enableForThisDomain }} {{ $t('templates.domainSections.logging.enableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -66,7 +66,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -83,7 +82,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainLogging', // Component name name: 'DomainLogging', // Component name
display: i18n.common.logging, // Display name for tab display: 'common.logging', // Display name for tab (i18n key)
key: 'logging', // Key for data in parent key: 'logging', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -92,11 +91,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'logging'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'logging'), // Getters & setters for the delegated data
}; };
</script> </script>

View File

@ -28,18 +28,18 @@ THE SOFTWARE.
<div> <div>
<div v-if="!phpEnabled" class="field is-horizontal is-aligned-top"> <div v-if="!phpEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.php }}</label> <label class="label">{{ $t('common.php') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div class="control is-changed"> <div class="control is-changed">
<label class="text"> <label class="text">
{{ i18n.templates.domainSections.php.phpIsDisabled }} {{ $t('templates.domainSections.php.phpIsDisabled') }}
<template v-if="$parent.$props.data.reverseProxy.reverseProxy.computed"> <template v-if="$parent.$props.data.reverseProxy.reverseProxy.computed">
<br />{{ i18n.templates.domainSections.php.phpCannotBeEnabledWithReverseProxy }} <br />{{ $t('templates.domainSections.php.phpCannotBeEnabledWithReverseProxy') }}
</template> </template>
<template v-if="$parent.$props.data.python.python.computed"> <template v-if="$parent.$props.data.python.python.computed">
<br />{{ i18n.templates.domainSections.php.phpCannotBeEnabledWithPython }} <br />{{ $t('templates.domainSections.php.phpCannotBeEnabledWithPython') }}
</template> </template>
</label> </label>
</div> </div>
@ -49,7 +49,7 @@ THE SOFTWARE.
<div v-else class="field is-horizontal"> <div v-else class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.php }}</label> <label class="label">{{ $t('common.php') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -57,7 +57,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="php" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="php" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.php.enablePhp }} {{ $t('templates.domainSections.php.enablePhp') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -67,7 +67,7 @@ THE SOFTWARE.
<div v-if="wordPressRulesEnabled" class="field is-horizontal"> <div v-if="wordPressRulesEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.php.wordPressRules }}</label> <label class="label">{{ $t('templates.domainSections.php.wordPressRules') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -75,7 +75,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="wordPressRules" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="wordPressRules" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.php.enableWordPressRules }} {{ $t('templates.domainSections.php.enableWordPressRules') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -85,7 +85,7 @@ THE SOFTWARE.
<div v-if="drupalRulesEnabled" class="field is-horizontal"> <div v-if="drupalRulesEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.php.drupalRules }}</label> <label class="label">{{ $t('templates.domainSections.php.drupalRules') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -93,7 +93,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="drupalRules" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="drupalRules" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.php.enableDrupalRules }} {{ $t('templates.domainSections.php.enableDrupalRules') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -103,7 +103,7 @@ THE SOFTWARE.
<div v-if="magentoRulesEnabled" class="field is-horizontal"> <div v-if="magentoRulesEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.php.magentoRules }}</label> <label class="label">{{ $t('templates.domainSections.php.magentoRules') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -111,7 +111,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="magentoRules" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="magentoRules" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.php.enableMagentoRules }} {{ $t('templates.domainSections.php.enableMagentoRules') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -121,7 +121,7 @@ THE SOFTWARE.
<div v-if="joomlaRulesEnabled" class="field is-horizontal"> <div v-if="joomlaRulesEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.php.joomlaRules }}</label> <label class="label">{{ $t('templates.domainSections.php.joomlaRules') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -129,7 +129,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="joomlaRules" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="joomlaRules" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.php.enableJoomlaRules }} {{ $t('templates.domainSections.php.enableJoomlaRules') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -141,7 +141,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -170,7 +169,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainPHP', // Component name name: 'DomainPHP', // Component name
display: i18n.common.php, // Display name for tab display: 'common.php', // Display name for tab (i18n key)
key: 'php', // Key for data in parent key: 'php', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -179,11 +178,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'php'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'php'), // Getters & setters for the delegated data
watch: { watch: {
// If the Reverse proxy or Python is enabled, PHP will be forced off // If the Reverse proxy or Python is enabled, PHP will be forced off

View File

@ -27,7 +27,7 @@ THE SOFTWARE.
<template> <template>
<div class="container"> <div class="container">
<div class="header-group" :style="{ cursor: interacted ? 'pointer' : undefined }" @click="toggleCollapse"> <div class="header-group" :style="{ cursor: interacted ? 'pointer' : undefined }" @click="toggleCollapse">
<h3>{{ i18n.templates.domainSections.presets.presets }}</h3> <h3>{{ $t('templates.domainSections.presets.presets') }}</h3>
<a v-if="interacted" class="button is-tiny"> <a v-if="interacted" class="button is-tiny">
<i :class="`fas fa-angle-${expanded ? 'up' : 'down'}`"></i> <i :class="`fas fa-angle-${expanded ? 'up' : 'down'}`"></i>
</a> </a>
@ -36,7 +36,7 @@ THE SOFTWARE.
<template v-if="!$parent.$props.data.hasUserInteraction || expanded"> <template v-if="!$parent.$props.data.hasUserInteraction || expanded">
<div v-if="$parent.$props.data.hasUserInteraction" class="message is-warning"> <div v-if="$parent.$props.data.hasUserInteraction" class="message is-warning">
<div class="message-body"> <div class="message-body">
{{ i18n.templates.domainSections.presets.itLooksLikeYouCustomisedTheConfig }} {{ $t('templates.domainSections.presets.itLooksLikeYouCustomisedTheConfig') }}
</div> </div>
</div> </div>
@ -45,7 +45,7 @@ THE SOFTWARE.
:class="`button${preset.computed ? ' is-primary' : ''}`" :class="`button${preset.computed ? ' is-primary' : ''}`"
@click="setPreset(key)" @click="setPreset(key)"
> >
{{ preset.display }} {{ $t(preset.display) }}
</a> </a>
</div> </div>
</template> </template>
@ -53,7 +53,6 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
import analytics from '../../util/analytics'; import analytics from '../../util/analytics';
@ -62,7 +61,7 @@ THE SOFTWARE.
const defaults = { const defaults = {
frontend: { frontend: {
default: false, default: false,
display: i18n.templates.domainSections.presets.frontend, display: 'templates.domainSections.presets.frontend', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return !data.php.php.computed return !data.php.php.computed
@ -74,7 +73,7 @@ THE SOFTWARE.
}, },
php: { php: {
default: true, default: true,
display: i18n.common.php, display: 'common.php', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.php.php.computed return data.php.php.computed
@ -89,7 +88,7 @@ THE SOFTWARE.
}, },
django: { django: {
default: false, default: false,
display: i18n.common.django, display: 'common.django', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.python.python.computed return data.python.python.computed
@ -99,7 +98,7 @@ THE SOFTWARE.
}, },
nodejs: { nodejs: {
default: false, default: false,
display: i18n.templates.domainSections.presets.nodeJs, display: 'templates.domainSections.presets.nodeJs', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.reverseProxy.reverseProxy.computed return data.reverseProxy.reverseProxy.computed
@ -108,7 +107,7 @@ THE SOFTWARE.
}, },
singlePageApplication: { singlePageApplication: {
default: false, default: false,
display: i18n.templates.domainSections.presets.singlePageApplication, display: 'templates.domainSections.presets.singlePageApplication', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.php.php.computed return data.php.php.computed
@ -118,7 +117,7 @@ THE SOFTWARE.
}, },
wordPress: { wordPress: {
default: false, default: false,
display: i18n.common.wordPress, display: 'common.wordPress', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.routing.index.computed === 'index.php' return data.routing.index.computed === 'index.php'
@ -132,7 +131,7 @@ THE SOFTWARE.
}, },
drupal: { drupal: {
default: false, default: false,
display: i18n.common.drupal, display: 'common.drupal', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.routing.index.computed === 'index.php' return data.routing.index.computed === 'index.php'
@ -146,7 +145,7 @@ THE SOFTWARE.
}, },
magento: { magento: {
default: false, default: false,
display: i18n.common.magento, display: 'common.magento', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.routing.index.computed === 'index.php' return data.routing.index.computed === 'index.php'
@ -160,7 +159,7 @@ THE SOFTWARE.
}, },
joomla: { joomla: {
default: false, default: false,
display: i18n.common.joomla, display: 'common.joomla', // i18n key
enabled: true, enabled: true,
computedCheck(data) { computedCheck(data) {
return data.routing.index.computed === 'index.php' return data.routing.index.computed === 'index.php'
@ -176,7 +175,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainPresets', // Component name name: 'DomainPresets', // Component name
display: i18n.templates.domainSections.presets.presets, // Display name for tab display: 'templates.domainSections.presets.presets', // Display name for tab (i18n key)
key: 'presets', // Key for data in parent key: 'presets', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
props: { props: {
@ -184,7 +183,6 @@ THE SOFTWARE.
}, },
data() { data() {
return { return {
i18n,
expanded: false, expanded: false,
}; };
}, },

View File

@ -28,18 +28,18 @@ THE SOFTWARE.
<div> <div>
<div v-if="!pythonEnabled" class="field is-horizontal is-aligned-top"> <div v-if="!pythonEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.python }}</label> <label class="label">{{ $t('common.python') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.domainSections.python.pythonIsDisabled }} {{ $t('templates.domainSections.python.pythonIsDisabled') }}
<template v-if="$parent.$props.data.reverseProxy.reverseProxy.computed"> <template v-if="$parent.$props.data.reverseProxy.reverseProxy.computed">
<br />{{ i18n.templates.domainSections.python.pythonCannotBeEnabledWithReverseProxy }} <br />{{ $t('templates.domainSections.python.pythonCannotBeEnabledWithReverseProxy') }}
</template> </template>
<template v-if="$parent.$props.data.php.php.computed"> <template v-if="$parent.$props.data.php.php.computed">
<br />{{ i18n.templates.domainSections.python.pythonCannotBeEnabledWithPhp }} <br />{{ $t('templates.domainSections.python.pythonCannotBeEnabledWithPhp') }}
</template> </template>
</label> </label>
</div> </div>
@ -49,7 +49,7 @@ THE SOFTWARE.
<div v-else class="field is-horizontal"> <div v-else class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.python }}</label> <label class="label">{{ $t('common.python') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -57,7 +57,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="python" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="python" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.python.enablePython }} {{ $t('templates.domainSections.python.enablePython') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -67,7 +67,7 @@ THE SOFTWARE.
<div v-if="djangoRulesEnabled" class="field is-horizontal"> <div v-if="djangoRulesEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.python.djangoRules }}</label> <label class="label">{{ $t('templates.domainSections.python.djangoRules') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -75,7 +75,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="djangoRules" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="djangoRules" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.python.enableDjangoRules }} {{ $t('templates.domainSections.python.enableDjangoRules') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -87,7 +87,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -104,7 +103,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainPython', // Component name name: 'DomainPython', // Component name
display: i18n.common.python, // Display name for tab display: 'common.python', // Display name for tab (i18n key)
key: 'python', // Key for data in parent key: 'python', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -113,11 +112,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'python'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'python'), // Getters & setters for the delegated data
watch: { watch: {
// If the Reverse proxy or PHP is enabled, Python will be forced off // If the Reverse proxy or PHP is enabled, Python will be forced off

View File

@ -38,7 +38,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="getMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="getMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -55,7 +55,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="postMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="postMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -72,7 +72,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="putMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="putMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -89,7 +89,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="patchMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="patchMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -106,7 +106,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="deleteMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="deleteMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -125,7 +125,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="headMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="headMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -142,7 +142,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="connectMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="connectMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -159,7 +159,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="optionsMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="optionsMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -176,7 +176,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="traceMethod" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="traceMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }} {{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -187,7 +187,7 @@ THE SOFTWARE.
</div> </div>
<div v-if="hasAtLeastOneEnabled" class="field is-horizontal"> <div v-if="hasAtLeastOneEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.restrict.responseCode }}</label> <label class="label">{{ $t('templates.domainSections.restrict.responseCode') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -208,7 +208,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -256,24 +255,23 @@ THE SOFTWARE.
}; };
export default { export default {
name: 'DomainRestrict', // Component name name: 'DomainRestrict', // Component name
display: i18n.common.restrict, // Display name for tab display: 'common.restrict', // Display name for tab (i18n key)
key: 'restrict', // Key for data in parent key: 'restrict', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
PrettyCheck, PrettyCheck,
}, },
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () { data () {
return { return {
i18n,
validResponseCode: true, validResponseCode: true,
}; };
}, },
computed: { computed: {
...computedFromDefaults(defaults, 'restrict'), // Getters & setters for the delegated data ...computedFromDefaults(defaults, 'restrict'), // Getters & setters for the delegated data
hasAtLeastOneEnabled() { hasAtLeastOneEnabled() {
return (Object.keys(this.$props.data).filter(k => this.$props.data[k].computed && k !== 'responseCode')).length > 0; return (Object.keys(this.$props.data).filter(k => this.$props.data[k].computed && k !== 'responseCode')).length > 0;
}, },

View File

@ -28,18 +28,18 @@ THE SOFTWARE.
<div> <div>
<div v-if="!reverseProxyEnabled" class="field is-horizontal is-aligned-top"> <div v-if="!reverseProxyEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.reverseProxy }}</label> <label class="label">{{ $t('common.reverseProxy') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.domainSections.reverseProxy.reverseProxyIsDisabled }} {{ $t('templates.domainSections.reverseProxy.reverseProxyIsDisabled') }}
<template v-if="$parent.$props.data.php.php.computed"> <template v-if="$parent.$props.data.php.php.computed">
<br />{{ i18n.templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPhp }} <br />{{ $t('templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPhp') }}
</template> </template>
<template v-if="$parent.$props.data.python.python.computed"> <template v-if="$parent.$props.data.python.python.computed">
<br />{{ i18n.templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPython }} <br />{{ $t('templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPython') }}
</template> </template>
</label> </label>
</div> </div>
@ -49,7 +49,7 @@ THE SOFTWARE.
<div v-else class="field is-horizontal"> <div v-else class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.reverseProxy }}</label> <label class="label">{{ $t('common.reverseProxy') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div :class="`field${reverseProxyChanged ? ' is-changed' : ''}`"> <div :class="`field${reverseProxyChanged ? ' is-changed' : ''}`">
@ -57,7 +57,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="reverseProxy" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="reverseProxy" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.reverseProxy.enableReverseProxy }} {{ $t('templates.domainSections.reverseProxy.enableReverseProxy') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -67,7 +67,7 @@ THE SOFTWARE.
<div v-if="pathEnabled" class="field is-horizontal"> <div v-if="pathEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.reverseProxy.path }}</label> <label class="label">{{ $t('common.path') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div :class="`field${pathChanged ? ' is-changed' : ''}`"> <div :class="`field${pathChanged ? ' is-changed' : ''}`">
@ -103,7 +103,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -124,7 +123,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainReverseProxy', // Component name name: 'DomainReverseProxy', // Component name
display: i18n.common.reverseProxy, // Display name for tab display: 'common.reverseProxy', // Display name for tab (i18n key)
key: 'reverseProxy', // Key for data in parent key: 'reverseProxy', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -133,11 +132,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'reverseProxy'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'reverseProxy'), // Getters & setters for the delegated data
watch: { watch: {
// If the PHP or Python is enabled, the Reverse proxy will be forced off // If the PHP or Python is enabled, the Reverse proxy will be forced off

View File

@ -36,7 +36,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="root" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="root" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.common.enable }} {{ $t('common.enable') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -66,7 +66,7 @@ THE SOFTWARE.
<div v-if="fallbackHtmlEnabled || fallbackPhpEnabled" class="field is-horizontal is-aligned-top"> <div v-if="fallbackHtmlEnabled || fallbackPhpEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.routing.fallbackRouting }}</label> <label class="label">{{ $t('templates.domainSections.routing.fallbackRouting') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -92,7 +92,7 @@ THE SOFTWARE.
<div v-if="fallbackPhpPathEnabled" class="field is-horizontal"> <div v-if="fallbackPhpPathEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.routing.fallbackRoutingPhpPath }}</label> <label class="label">{{ $t('templates.domainSections.routing.fallbackRoutingPhpPath') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div :class="`field${fallbackPhpPathChanged ? ' is-changed' : ''}`"> <div :class="`field${fallbackPhpPathChanged ? ' is-changed' : ''}`">
@ -109,7 +109,7 @@ THE SOFTWARE.
<div v-if="legacyPhpRoutingEnabled" class="field is-horizontal"> <div v-if="legacyPhpRoutingEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.routing.legacyPhpRouting }}</label> <label class="label">{{ $t('templates.domainSections.routing.legacyPhpRouting') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -117,7 +117,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="legacyPhpRouting" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="legacyPhpRouting" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.routing.enableLegacyRouting }} {{ $t('templates.domainSections.routing.enableLegacyRouting') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -130,7 +130,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import PrettyRadio from 'pretty-checkbox-vue/radio'; import PrettyRadio from 'pretty-checkbox-vue/radio';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -164,7 +163,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainRouting', // Component name name: 'DomainRouting', // Component name
display: i18n.templates.domainSections.routing.routing, // Display name for tab display: 'templates.domainSections.routing.routing', // Display name for tab (i18n key)
key: 'routing', // Key for data in parent key: 'routing', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -174,12 +173,7 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () { computed: computedFromDefaults(defaults, 'routing'), // Getters & setters for the delegated data
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'routing'), // Getters & setters for the delegated data
watch: { watch: {
// Disable all options (expect legacy php) if root is disabled // Disable all options (expect legacy php) if root is disabled
'$props.data.root': { '$props.data.root': {

View File

@ -28,21 +28,21 @@ THE SOFTWARE.
<div> <div>
<div class="field-row"> <div class="field-row">
<div class="field"> <div class="field">
<label class="label">{{ i18n.templates.domainSections.server.domain }}</label> <label class="label">{{ $t('templates.domainSections.server.domain') }}</label>
<div :class="`control${domainChanged ? ' is-changed' : ''}`"> <div :class="`control${domainChanged ? ' is-changed' : ''}`">
<input v-model="domain" class="input" type="text" :placeholder="domainDefault" /> <input v-model="domain" class="input" type="text" :placeholder="domainDefault" />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">{{ i18n.templates.domainSections.server.path }}</label> <label class="label">{{ $t('common.path') }}</label>
<div :class="`control${pathChanged ? ' is-changed' : ''}`"> <div :class="`control${pathChanged ? ' is-changed' : ''}`">
<input v-model="path" class="input" type="text" :placeholder="`/var/www/${domain}`" /> <input v-model="path" class="input" type="text" :placeholder="`/var/www/${domain}`" />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">{{ i18n.templates.domainSections.server.documentRoot }}</label> <label class="label">{{ $t('templates.domainSections.server.documentRoot') }}</label>
<div :class="`control${documentRootChanged ? ' is-changed' : ''}`"> <div :class="`control${documentRootChanged ? ' is-changed' : ''}`">
<input v-model="documentRoot" class="input" type="text" :placeholder="documentRootDefault" /> <input v-model="documentRoot" class="input" type="text" :placeholder="documentRootDefault" />
</div> </div>
@ -53,16 +53,16 @@ THE SOFTWARE.
<br /> <br />
<div class="message is-warning"> <div class="message is-warning">
<div class="message-body"> <div class="message-body">
{{ i18n.templates.domainSections.server.oneOrMoreOtherDomainsAreAlsoNamed }} {{ $t('templates.domainSections.server.oneOrMoreOtherDomainsAreAlsoNamed') }}
<code class="slim">{{ $props.data.domain.computed }}</code>. <code class="slim">{{ $props.data.domain.computed }}</code>.
{{ i18n.templates.domainSections.server.thisWillCauseIssuesWithConfigGeneration }} {{ $t('templates.domainSections.server.thisWillCauseIssuesWithConfigGeneration') }}
</div> </div>
</div> </div>
</template> </template>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.server.wwwSubdomain }}</label> <label class="label">{{ $t('templates.domainSections.server.wwwSubdomain') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -80,7 +80,7 @@ THE SOFTWARE.
<div v-if="cdnSubdomainEnabled" class="field is-horizontal"> <div v-if="cdnSubdomainEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.server.cdnSubdomain }}</label> <label class="label">{{ $t('templates.domainSections.server.cdnSubdomain') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -98,7 +98,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.domainSections.server.redirectSubdomains }}</label> <label class="label">{{ $t('templates.domainSections.server.redirectSubdomains') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -118,7 +118,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.listen }}</label> <label class="label">{{ $t('templates.domainSections.server.listen') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field has-addons"> <div class="field has-addons">
@ -148,7 +148,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -190,7 +189,7 @@ THE SOFTWARE.
export default { export default {
name: 'DomainServer', // Component name name: 'DomainServer', // Component name
display: i18n.templates.domainSections.server.server, // Display name for tab display: 'templates.domainSections.server.server', // Display name for tab (i18n key)
key: 'server', // Key for data in parent key: 'server', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -199,11 +198,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: { computed: {
...computedFromDefaults(defaults, 'server'), // Getters & setters for the delegated data ...computedFromDefaults(defaults, 'server'), // Getters & setters for the delegated data
duplicateDomain() { duplicateDomain() {

View File

@ -28,27 +28,27 @@ THE SOFTWARE.
<div class="footer"> <div class="footer">
<div class="container"> <div class="container">
<p> <p>
<a href="#top" class="button is-primary is-small">{{ i18n.templates.footer.backToTop }}</a> <a href="#top" class="button is-primary is-small">{{ $t('templates.footer.backToTop') }}</a>
</p> </p>
<p> <p>
{{ i18n.templates.footer.thisToolIs }} {{ $t('templates.footer.thisToolIs') }}
<ExternalLink :text="i18n.templates.footer.openSourceOnGitHub" <ExternalLink :text="$t('templates.footer.openSourceOnGitHub')"
link="https://github.com/digitalocean/nginxconfig.io" link="https://github.com/digitalocean/nginxconfig.io"
></ExternalLink> ></ExternalLink>
{{ i18n.templates.footer.underThe }} {{ $t('templates.footer.underThe') }}
<ExternalLink :text="i18n.templates.footer.mit" <ExternalLink :text="$t('templates.footer.mit')"
link="https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE" link="https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE"
></ExternalLink> ></ExternalLink>
{{ i18n.templates.footer.license }} {{ $t('templates.footer.license') }}
{{ i18n.templates.footer.weWelcomeFeedbackAndContributions }} {{ $t('templates.footer.weWelcomeFeedbackAndContributions') }}
</p> </p>
<p> <p>
{{ i18n.templates.footer.originallyCreatedBy }} {{ $t('templates.footer.originallyCreatedBy') }}
<ExternalLink :text="i18n.templates.footer.balintSzekeres" <ExternalLink :text="$t('templates.footer.balintSzekeres')"
link="https://b4lint.hu/" link="https://b4lint.hu/"
></ExternalLink>, ></ExternalLink>,
{{ i18n.templates.footer.maintainedBy }} {{ $t('templates.footer.maintainedBy') }}
<ExternalLink :text="i18n.templates.footer.digitalOcean" <ExternalLink :text="$t('templates.footer.digitalOcean')"
link="https://github.com/digitalocean/nginxconfig.io" link="https://github.com/digitalocean/nginxconfig.io"
></ExternalLink>. ></ExternalLink>.
</p> </p>
@ -57,7 +57,6 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../i18n';
import ExternalLink from 'do-vue/src/templates/external_link'; import ExternalLink from 'do-vue/src/templates/external_link';
export default { export default {
@ -65,10 +64,5 @@ THE SOFTWARE.
components: { components: {
ExternalLink, ExternalLink,
}, },
data() {
return {
i18n,
};
},
}; };
</script> </script>

View File

@ -29,7 +29,7 @@ THE SOFTWARE.
<div class="tabs"> <div class="tabs">
<ul> <ul>
<li v-for="tab in tabs" :class="tabClass(tab.key)"> <li v-for="tab in tabs" :class="tabClass(tab.key)">
<a @click="active = tab.key">{{ tab.display }}{{ changes(tab.key) }}</a> <a @click="active = tab.key">{{ $t(tab.display) }}{{ changes(tab.key) }}</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -44,17 +44,16 @@ THE SOFTWARE.
<div class="navigation-buttons"> <div class="navigation-buttons">
<a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab"> <a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab">
<i class="fas fa-long-arrow-alt-left"></i> <span>{{ i18n.common.back }}</span> <i class="fas fa-long-arrow-alt-left"></i> <span>{{ $t('common.back') }}</span>
</a> </a>
<a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab"> <a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab">
<span>{{ i18n.common.next }}</span> <i class="fas fa-long-arrow-alt-right"></i> <span>{{ $t('common.next') }}</span> <i class="fas fa-long-arrow-alt-right"></i>
</a> </a>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import i18n from '../i18n';
import isChanged from '../util/is_changed'; import isChanged from '../util/is_changed';
import * as Sections from './global_sections'; import * as Sections from './global_sections';
@ -72,7 +71,6 @@ THE SOFTWARE.
}, },
data() { data() {
return { return {
i18n,
active: tabs[0].key, active: tabs[0].key,
tabs, tabs,
}; };

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
<div> <div>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.docker }}</label> <label class="label">{{ $t('common.docker') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -36,7 +36,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="dockerfile" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="dockerfile" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.docker.dockerfile }} {{ $t('templates.globalSections.docker.dockerfile') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -45,7 +45,7 @@ THE SOFTWARE.
</div> </div>
<div v-if="dockerfile" class="field is-horizontal"> <div v-if="dockerfile" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.dockerCompose }}</label> <label class="label">{{ $t('common.dockerCompose') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -53,7 +53,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="dockerCompose" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="dockerCompose" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.docker.dockerCompose }} {{ $t('templates.globalSections.docker.dockerCompose') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -64,10 +64,9 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n'; import PrettyCheck from 'pretty-checkbox-vue/check';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
import PrettyCheck from 'pretty-checkbox-vue/check';
const defaults = { const defaults = {
dockerfile: { dockerfile: {
@ -82,7 +81,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalDocker', // Component name name: 'GlobalDocker', // Component name
display: i18n.common.docker, // Display name for tab display: 'common.docker', // Display name for tab (i18n key)
key: 'docker', // Key for data in parent key: 'docker', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -91,11 +90,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'docker'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'docker'), // Getters & setters for the delegated data
watch: { watch: {
// Disable docker-compose if dockerfile is disabled // Disable docker-compose if dockerfile is disabled

View File

@ -28,13 +28,13 @@ THE SOFTWARE.
<div> <div>
<div v-if="!sslProfileEnabled" class="field is-horizontal is-aligned-top"> <div v-if="!sslProfileEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.https.sslProfile }}</label> <label class="label">{{ $t('templates.globalSections.https.sslProfile') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.globalSections.https.httpsMustBeEnabledOnOneSite }} {{ $t('templates.globalSections.https.httpsMustBeEnabledOnOneSite') }}
</label> </label>
</div> </div>
</div> </div>
@ -44,7 +44,7 @@ THE SOFTWARE.
<template v-else> <template v-else>
<div class="field is-horizontal is-aligned-top"> <div class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.https.sslProfile }}</label> <label class="label">{{ $t('templates.globalSections.https.sslProfile') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -55,7 +55,7 @@ THE SOFTWARE.
<div class="radio"> <div class="radio">
<PrettyRadio v-model="sslProfile" :value="value" class="p-default p-round p-fill p-icon"> <PrettyRadio v-model="sslProfile" :value="value" class="p-default p-round p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ name }} {{ $t(name) }}
</PrettyRadio> </PrettyRadio>
</div> </div>
</div> </div>
@ -66,7 +66,7 @@ THE SOFTWARE.
<div class="field is-horizontal is-aligned-top"> <div class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.https.ocspDnsResolvers }}</label> <label class="label">{{ $t('templates.globalSections.https.ocspDnsResolvers') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -74,7 +74,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="ocspCloudflare" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="ocspCloudflare" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.https.cloudflareResolver }} {{ $t('templates.globalSections.https.cloudflareResolver') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -85,7 +85,7 @@ THE SOFTWARE.
<div class="radio"> <div class="radio">
<PrettyRadio v-model="ocspCloudflareType" :value="value" class="p-default p-round p-fill p-icon"> <PrettyRadio v-model="ocspCloudflareType" :value="value" class="p-default p-round p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ name }} {{ $t(name) }}
</PrettyRadio> </PrettyRadio>
</div> </div>
</div> </div>
@ -95,7 +95,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="ocspGoogle" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="ocspGoogle" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.https.googlePublicDns }} {{ $t('templates.globalSections.https.googlePublicDns') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -106,7 +106,7 @@ THE SOFTWARE.
<div class="radio"> <div class="radio">
<PrettyRadio v-model="ocspGoogleType" :value="value" class="p-default p-round p-fill p-icon"> <PrettyRadio v-model="ocspGoogleType" :value="value" class="p-default p-round p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ name }} {{ $t(name) }}
</PrettyRadio> </PrettyRadio>
</div> </div>
</div> </div>
@ -116,7 +116,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="ocspOpenDns" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="ocspOpenDns" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.https.openDns }} {{ $t('templates.globalSections.https.openDns') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -127,7 +127,7 @@ THE SOFTWARE.
<div class="radio"> <div class="radio">
<PrettyRadio v-model="ocspOpenDnsType" :value="value" class="p-default p-round p-fill p-icon"> <PrettyRadio v-model="ocspOpenDnsType" :value="value" class="p-default p-round p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ name }} {{ $t(name) }}
</PrettyRadio> </PrettyRadio>
</div> </div>
</div> </div>
@ -137,7 +137,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="ocspQuad9" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="ocspQuad9" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.https.quad9 }} {{ $t('templates.globalSections.https.quad9') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -148,7 +148,7 @@ THE SOFTWARE.
<div class="radio"> <div class="radio">
<PrettyRadio v-model="ocspQuad9Type" :value="value" class="p-default p-round p-fill p-icon"> <PrettyRadio v-model="ocspQuad9Type" :value="value" class="p-default p-round p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ name }} {{ $t(name) }}
</PrettyRadio> </PrettyRadio>
</div> </div>
</div> </div>
@ -158,7 +158,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="ocspVerisign" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="ocspVerisign" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.https.verisign }} {{ $t('templates.globalSections.https.verisign') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -169,7 +169,7 @@ THE SOFTWARE.
<div class="radio"> <div class="radio">
<PrettyRadio v-model="ocspVerisignType" :value="value" class="p-default p-round p-fill p-icon"> <PrettyRadio v-model="ocspVerisignType" :value="value" class="p-default p-round p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ name }} {{ $t(name) }}
</PrettyRadio> </PrettyRadio>
</div> </div>
</div> </div>
@ -180,7 +180,7 @@ THE SOFTWARE.
<div v-if="letsEncryptRootEnabled" class="field is-horizontal"> <div v-if="letsEncryptRootEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.https.letsEncryptWebroot }}</label> <label class="label">{{ $t('templates.globalSections.https.letsEncryptWebroot') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -197,7 +197,7 @@ THE SOFTWARE.
<div v-if="letsEncryptCertRootEnabled" class="field is-horizontal"> <div v-if="letsEncryptCertRootEnabled" class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.https.letsEncryptCertRoot }}</label> <label class="label">{{ $t('templates.globalSections.https.letsEncryptCertRoot') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -219,16 +219,15 @@ THE SOFTWARE.
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import PrettyRadio from 'pretty-checkbox-vue/radio'; import PrettyRadio from 'pretty-checkbox-vue/radio';
import clone from 'clone'; import clone from 'clone';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
const ipType = { const ipType = {
default: 'ipv4', default: 'ipv4',
options: { options: {
ipv4: i18n.templates.globalSections.https.ipv4Only, ipv4: 'templates.globalSections.https.ipv4Only', // i18n key
ipv6: i18n.templates.globalSections.https.ipv6Only, ipv6: 'templates.globalSections.https.ipv6Only', // i18n key
both: i18n.templates.globalSections.https.ipv4AndIpv6, both: 'templates.globalSections.https.ipv4AndIpv6', // i18n key
}, },
enabled: true, enabled: true,
}; };
@ -243,9 +242,9 @@ THE SOFTWARE.
sslProfile: { sslProfile: {
default: 'intermediate', default: 'intermediate',
options: { options: {
modern: i18n.templates.globalSections.https.mozillaModern, modern: 'templates.globalSections.https.mozillaModern', // i18n key
intermediate: i18n.templates.globalSections.https.mozillaIntermediate, intermediate: 'templates.globalSections.https.mozillaIntermediate', // i18n key
old: i18n.templates.globalSections.https.mozillaOld, old: 'templates.globalSections.https.mozillaOld', // i18n key
}, },
enabled: true, enabled: true,
}, },
@ -286,7 +285,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalHTTPS', // Component name name: 'GlobalHTTPS', // Component name
display: i18n.common.https, // Display name for tab display: 'common.https', // Display name for tab (i18n key)
key: 'https', // Key for data in parent key: 'https', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -296,11 +295,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'https'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'https'), // Getters & setters for the delegated data
watch: { watch: {
// Check SSL profile is valid // Check SSL profile is valid

View File

@ -70,7 +70,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="logNotFound" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="logNotFound" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.enableFileNotFoundErrorLogging }} error_log {{ $t('templates.globalSections.logging.enableFileNotFoundErrorLogging') }} error_log
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -80,7 +80,7 @@ THE SOFTWARE.
<div class="field is-horizontal is-aligned-top"> <div class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.logging.logformat }}</label> <label class="label">{{ $t('templates.globalSections.logging.logformat') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -88,7 +88,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="cloudflare" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="cloudflare" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.enableCloudflare }} {{ $t('templates.globalSections.logging.enableCloudflare') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -96,7 +96,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="cfRay" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="cfRay" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.cfRay }} {{ $t('templates.globalSections.logging.cfRay') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -104,7 +104,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="cfConnectingIp" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="cfConnectingIp" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.cfConnectingIp }} {{ $t('templates.globalSections.logging.cfConnectingIp') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -112,7 +112,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="xForwardedFor" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="xForwardedFor" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.xForwardedFor }} {{ $t('templates.globalSections.logging.xForwardedFor') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -120,7 +120,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="xForwardedProto" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="xForwardedProto" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.xForwardedProto }} {{ $t('templates.globalSections.logging.xForwardedProto') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -128,7 +128,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="trueClientIp" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="trueClientIp" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.trueClientIp }} {{ $t('templates.globalSections.logging.trueClientIp') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -136,7 +136,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="cfIpCountry" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="cfIpCountry" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.cfIpCountry }} {{ $t('templates.globalSections.logging.cfIpCountry') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -144,7 +144,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="cfVisitor" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="cfVisitor" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.cfVisitor }} {{ $t('templates.globalSections.logging.cfVisitor') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -152,7 +152,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="cdnLoop" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="cdnLoop" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.logging.cdnLoop }} {{ $t('templates.globalSections.logging.cdnLoop') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -164,7 +164,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -221,7 +220,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalLogging', // Component name name: 'GlobalLogging', // Component name
display: i18n.common.logging, // Display name for tab display: 'common.logging', // Display name for tab (i18n key)
key: 'logging', // Key for data in parent key: 'logging', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -230,11 +229,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'logging'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'logging'), // Getters & setters for the delegated data
watch: { watch: {
// Show Cloudflare header options if Cloudflare is enabled // Show Cloudflare header options if Cloudflare is enabled

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
<div> <div>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.nginx.nginxConfigDirectory }}</label> <label class="label">{{ $t('templates.globalSections.nginx.nginxConfigDirectory') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -110,7 +110,7 @@ THE SOFTWARE.
</div> </div>
<div class="control"> <div class="control">
<a class="button is-static"> <a class="button is-static">
{{ i18n.templates.globalSections.nginx.mb }} {{ $t('templates.globalSections.nginx.mb') }}
</a> </a>
</div> </div>
</div> </div>
@ -121,7 +121,6 @@ THE SOFTWARE.
<script> <script>
import VueSelect from 'vue-select'; import VueSelect from 'vue-select';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -155,7 +154,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalNGINX', // Component name name: 'GlobalNGINX', // Component name
display: i18n.common.nginx, // Display name for tab display: 'common.nginx', // Display name for tab (i18n key)
key: 'nginx', // Key for data in parent key: 'nginx', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -164,11 +163,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'nginx'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'nginx'), // Getters & setters for the delegated data
watch: { watch: {
// Clean nginx directory of trailing slashes // Clean nginx directory of trailing slashes

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
<div> <div>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.performance.gzipCompression }}</label> <label class="label">{{ $t('templates.globalSections.performance.gzipCompression') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -36,7 +36,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="gzipCompression" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="gzipCompression" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.performance.enableGzipCompression }} {{ $t('templates.globalSections.performance.enableGzipCompression') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -46,7 +46,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.performance.brotliCompression }}</label> <label class="label">{{ $t('templates.globalSections.performance.brotliCompression') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -54,7 +54,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="brotliCompression" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="brotliCompression" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.performance.enableBrotliCompression }} {{ $t('templates.globalSections.performance.enableBrotliCompression') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -64,7 +64,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.performance.expirationForAssets }}</label> <label class="label">{{ $t('templates.globalSections.performance.expirationForAssets') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -81,7 +81,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.performance.expirationForMedia }}</label> <label class="label">{{ $t('templates.globalSections.performance.expirationForMedia') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -98,7 +98,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.performance.expirationForSvgs }}</label> <label class="label">{{ $t('templates.globalSections.performance.expirationForSvgs') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -115,7 +115,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.performance.expirationForFonts }}</label> <label class="label">{{ $t('templates.globalSections.performance.expirationForFonts') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -134,7 +134,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -167,7 +166,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalPerformance', // Component name name: 'GlobalPerformance', // Component name
display: i18n.templates.globalSections.performance.performance, // Display name for tab display: 'templates.globalSections.performance.performance', // Display name for tab (i18n key)
key: 'performance', // Key for data in parent key: 'performance', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -176,11 +175,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'performance'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'performance'), // Getters & setters for the delegated data
}; };
</script> </script>

View File

@ -28,13 +28,13 @@ THE SOFTWARE.
<div> <div>
<div v-if="!phpServerEnabled" class="field is-horizontal is-aligned-top"> <div v-if="!phpServerEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.php.phpServer }}</label> <label class="label">{{ $t('templates.globalSections.php.phpServer') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.globalSections.php.phpMustBeEnabledOnOneSite }} {{ $t('templates.globalSections.php.phpMustBeEnabledOnOneSite') }}
</label> </label>
</div> </div>
</div> </div>
@ -44,7 +44,7 @@ THE SOFTWARE.
<template v-else> <template v-else>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.php.phpServer }}</label> <label class="label">{{ $t('templates.globalSections.php.phpServer') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -61,12 +61,13 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.php.phpBackupServer }}</label> <label class="label">{{ $t('templates.globalSections.php.phpBackupServer') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div :class="`control${phpBackupServerChanged ? ' is-changed' : ''}`"> <div :class="`control${phpBackupServerChanged ? ' is-changed' : ''}`">
<VueSelect v-model="phpBackupServer" <VueSelect ref="phpBackupServerSelect"
v-model="phpBackupServer"
:options="phpBackupServerOptions" :options="phpBackupServerOptions"
:clearable="false" :clearable="false"
:reduce="s => s.value" :reduce="s => s.value"
@ -81,22 +82,22 @@ THE SOFTWARE.
<script> <script>
import VueSelect from 'vue-select'; import VueSelect from 'vue-select';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
// Value -> i18n key
const serverOptions = { const serverOptions = {
'127.0.0.1:9000': `${i18n.templates.globalSections.php.tcp}: 127.0.0.1:9000`, '127.0.0.1:9000': 'templates.globalSections.php.tcp',
'/var/run/hhvm/sock': `${i18n.templates.globalSections.php.hhvmSocket}: /var/run/hhvm/sock`, '/var/run/hhvm/sock': 'templates.globalSections.php.hhvmSocket',
'/var/run/hhvm/hhvm.sock': `${i18n.templates.globalSections.php.hhvmSocket}: /var/run/hhvm/hhvm.sock`, '/var/run/hhvm/hhvm.sock': 'templates.globalSections.php.hhvmSocket',
'/var/run/php5-fpm.sock': `${i18n.templates.globalSections.php.php5Socket}: /var/run/php5-fpm.sock`, '/var/run/php5-fpm.sock': 'templates.globalSections.php.php5Socket',
'/var/run/php/php7.1-fpm.sock': `${i18n.templates.globalSections.php.php71Socket}: /var/run/php/php7.1-fpm.sock`, '/var/run/php/php7.1-fpm.sock': 'templates.globalSections.php.php71Socket',
'/var/run/php/php7.2-fpm.sock': `${i18n.templates.globalSections.php.php72Socket}: /var/run/php/php7.2-fpm.sock`, '/var/run/php/php7.2-fpm.sock': 'templates.globalSections.php.php72Socket',
'/var/run/php/php7.0-fpm.sock': `${i18n.templates.globalSections.php.php70Socket}: /var/run/php/php7.0-fpm.sock`, '/var/run/php/php7.0-fpm.sock': 'templates.globalSections.php.php70Socket',
'/var/run/php/php7.3-fpm.sock': `${i18n.templates.globalSections.php.php73Socket}: /var/run/php/php7.3-fpm.sock`, '/var/run/php/php7.3-fpm.sock': 'templates.globalSections.php.php73Socket',
'/var/run/php/php7.4-fpm.sock': `${i18n.templates.globalSections.php.php74Socket}: /var/run/php/php7.4-fpm.sock`, '/var/run/php/php7.4-fpm.sock': 'templates.globalSections.php.php74Socket',
'/var/run/php/php8.0-fpm.sock': `${i18n.templates.globalSections.php.php80Socket}: /var/run/php/php8.0-fpm.sock`, '/var/run/php/php8.0-fpm.sock': 'templates.globalSections.php.php80Socket',
'/var/run/php/php-fpm.sock': `${i18n.templates.globalSections.php.phpSocket}: /var/run/php/php-fpm.sock`, '/var/run/php/php-fpm.sock': 'templates.globalSections.php.phpSocket',
}; };
const defaults = { const defaults = {
@ -107,14 +108,14 @@ THE SOFTWARE.
}, },
phpBackupServer: { phpBackupServer: {
default: '', default: '',
options: { '': i18n.templates.globalSections.php.disabled, ...serverOptions }, options: { '': 'templates.globalSections.php.disabled', ...serverOptions },
enabled: true, enabled: true,
}, },
}; };
export default { export default {
name: 'GlobalPHP', // Component name name: 'GlobalPHP', // Component name
display: i18n.common.php, // Display name for tab display: 'common.php', // Display name for tab (i18n key)
key: 'php', // Key for data in parent key: 'php', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -123,20 +124,15 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: { computed: {
...computedFromDefaults(defaults, 'php'), // Getters & setters for the delegated data ...computedFromDefaults(defaults, 'php'), // Getters & setters for the delegated data
phpServerOptions() { phpServerOptions() {
return Object.entries(this.$props.data.phpServer.options) return Object.entries(this.$props.data.phpServer.options)
.map(([key, value]) => ({ label: value, value: key })); .map(([key, value]) => ({ label: `${this.$t(value)}${key ? `: ${key}` : ''}`, value: key }));
}, },
phpBackupServerOptions() { phpBackupServerOptions() {
return Object.entries(this.$props.data.phpBackupServer.options) return Object.entries(this.$props.data.phpBackupServer.options)
.map(([key, value]) => ({ label: value, value: key })); .map(([key, value]) => ({ label: `${this.$t(value)}${key ? `: ${key}` : ''}`, value: key }));
}, },
}, },
watch: { watch: {
@ -179,6 +175,12 @@ THE SOFTWARE.
}, },
deep: true, deep: true,
}, },
// Ensure 'Disabled' gets translated in VueSelect on language switch
'$i18n.locale'() {
const updated = this.phpBackupServerOptions
.find(x => x.value === this.$refs.phpBackupServerSelect.$data._value.value);
if (updated) this.$refs.phpBackupServerSelect.$data._value = updated;
},
}, },
}; };
</script> </script>

View File

@ -28,13 +28,13 @@ THE SOFTWARE.
<div> <div>
<div v-if="!pythonServerEnabled" class="field is-horizontal is-aligned-top"> <div v-if="!pythonServerEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.python.pythonServer }}</label> <label class="label">{{ $t('templates.globalSections.python.pythonServer') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.globalSections.python.pythonMustBeEnabledOnOneSite }} {{ $t('templates.globalSections.python.pythonMustBeEnabledOnOneSite') }}
</label> </label>
</div> </div>
</div> </div>
@ -43,7 +43,7 @@ THE SOFTWARE.
<div v-else class="field is-horizontal"> <div v-else class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.python.pythonServer }}</label> <label class="label">{{ $t('templates.globalSections.python.pythonServer') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -61,7 +61,6 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -74,17 +73,12 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalPython', // Component name name: 'GlobalPython', // Component name
display: i18n.common.python, // Display name for tab display: 'common.python', // Display name for tab (i18n key)
key: 'python', // Key for data in parent key: 'python', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'python'), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'python'), // Getters & setters for the delegated data
watch: { watch: {
// Enable Python server settings if any site uses Python // Enable Python server settings if any site uses Python

View File

@ -28,13 +28,13 @@ THE SOFTWARE.
<div> <div>
<div v-if="!reverseProxyEnabled" class="field is-horizontal is-aligned-top"> <div v-if="!reverseProxyEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.common.reverseProxy }}</label> <label class="label">{{ $t('common.reverseProxy') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.globalSections.reverseProxy.reverseProxyMustBeEnabledOnOneSite }} {{ $t('templates.globalSections.reverseProxy.reverseProxyMustBeEnabledOnOneSite') }}
</label> </label>
</div> </div>
</div> </div>
@ -59,7 +59,7 @@ THE SOFTWARE.
</div> </div>
<div class="control"> <div class="control">
<a class="button is-static"> <a class="button is-static">
{{ i18n.templates.globalSections.reverseProxy.seconds }} {{ $t('templates.globalSections.reverseProxy.seconds') }}
</a> </a>
</div> </div>
</div> </div>
@ -83,7 +83,7 @@ THE SOFTWARE.
</div> </div>
<div class="control"> <div class="control">
<a class="button is-static"> <a class="button is-static">
{{ i18n.templates.globalSections.reverseProxy.seconds }} {{ $t('templates.globalSections.reverseProxy.seconds') }}
</a> </a>
</div> </div>
</div> </div>
@ -107,7 +107,7 @@ THE SOFTWARE.
</div> </div>
<div class="control"> <div class="control">
<a class="button is-static"> <a class="button is-static">
{{ i18n.templates.globalSections.reverseProxy.seconds }} {{ $t('templates.globalSections.reverseProxy.seconds') }}
</a> </a>
</div> </div>
</div> </div>
@ -118,7 +118,6 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -154,7 +153,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalReverseProxy', // Component name name: 'GlobalReverseProxy', // Component name
display: i18n.common.reverseProxy, // Display name for tab display: 'common.reverseProxy', // Display name for tab (i18n key)
key: 'reverseProxy', // Key for data in parent key: 'reverseProxy', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
props: { props: {
@ -162,7 +161,6 @@ THE SOFTWARE.
}, },
data() { data() {
return { return {
i18n,
reverseProxyEnabled: false, reverseProxyEnabled: false,
}; };
}, },

View File

@ -59,7 +59,7 @@ THE SOFTWARE.
<br /> <br />
<div class="message is-warning"> <div class="message is-warning">
<div class="message-body" <div class="message-body"
v-html="i18n.templates.globalSections.security.whenUsingWordPressUnsafeEvalIsOftenRequiredToAllowFunctionality" v-html="$t('templates.globalSections.security.whenUsingWordPressUnsafeEvalIsOftenRequiredToAllowFunctionality')"
></div> ></div>
</div> </div>
</template> </template>
@ -77,7 +77,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="serverTokens" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="serverTokens" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.common.enable }} {{ $t('common.enable') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -95,7 +95,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="limitReq" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="limitReq" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.common.enable }} {{ $t('common.enable') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -113,7 +113,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="securityTxt" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="securityTxt" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.common.enable }} {{ $t('common.enable') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -143,7 +143,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import VueSelect from 'vue-select'; import VueSelect from 'vue-select';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
@ -186,7 +185,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalSecurity', // Component name name: 'GlobalSecurity', // Component name
display: i18n.templates.globalSections.security.security, // Display name for tab display: 'templates.globalSections.security.security', // Display name for tab (i18n key)
key: 'security', // Key for data in parent key: 'security', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -196,11 +195,6 @@ THE SOFTWARE.
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () {
return {
i18n,
};
},
computed: { computed: {
...computedFromDefaults(defaults, 'security'), // Getters & setters for the delegated data ...computedFromDefaults(defaults, 'security'), // Getters & setters for the delegated data
hasWordPress() { hasWordPress() {

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
<div> <div>
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.tools.modularizedStructure }}</label> <label class="label">{{ $t('templates.globalSections.tools.modularizedStructure') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -36,7 +36,7 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="modularizedStructure" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="modularizedStructure" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.tools.enableModularizedConfigFiles }} {{ $t('templates.globalSections.tools.enableModularizedConfigFiles') }}
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -54,8 +54,8 @@ THE SOFTWARE.
<div class="checkbox"> <div class="checkbox">
<PrettyCheck v-model="symlinkVhost" class="p-default p-curve p-fill p-icon"> <PrettyCheck v-model="symlinkVhost" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i> <i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.globalSections.tools.enableSymLinksFrom }} sites-available/ {{ $t('templates.globalSections.tools.enableSymLinksFrom') }} sites-available/
{{ i18n.templates.globalSections.tools.to }} sites-enabled/ {{ $t('templates.globalSections.tools.to') }} sites-enabled/
</PrettyCheck> </PrettyCheck>
</div> </div>
</div> </div>
@ -65,7 +65,7 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.tools.shareConfiguration }}</label> <label class="label">{{ $t('templates.globalSections.tools.shareConfiguration') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field">
@ -83,23 +83,23 @@ THE SOFTWARE.
<div class="field is-horizontal"> <div class="field is-horizontal">
<div class="field-label"> <div class="field-label">
<label class="label">{{ i18n.templates.globalSections.tools.resetConfiguration }}</label> <label class="label">{{ $t('templates.globalSections.tools.resetConfiguration') }}</label>
</div> </div>
<div class="field-body"> <div class="field-body">
<div class="field is-grouped"> <div class="field is-grouped">
<div class="control"> <div class="control">
<a class="button is-danger is-outline is-mini" @click="resetGlobal"> <a class="button is-danger is-outline is-mini" @click="resetGlobal">
{{ i18n.templates.globalSections.tools.resetGlobalConfig }} {{ $t('templates.globalSections.tools.resetGlobalConfig') }}
</a> </a>
</div> </div>
<div v-if="hasDomain" class="control"> <div v-if="hasDomain" class="control">
<a class="button is-danger is-outline is-mini" @click="resetDomains"> <a class="button is-danger is-outline is-mini" @click="resetDomains">
{{ i18n.templates.globalSections.tools.resetAllDomains }} {{ $t('templates.globalSections.tools.resetAllDomains') }}
</a> </a>
</div> </div>
<div v-if="hasDomain" class="control"> <div v-if="hasDomain" class="control">
<a class="button is-danger is-outline is-mini" @click="removeDomains"> <a class="button is-danger is-outline is-mini" @click="removeDomains">
{{ i18n.templates.globalSections.tools.removeAllDomains }} {{ $t('templates.globalSections.tools.removeAllDomains') }}
</a> </a>
</div> </div>
</div> </div>
@ -118,12 +118,12 @@ THE SOFTWARE.
<div class="field is-grouped"> <div class="field is-grouped">
<div class="control"> <div class="control">
<a class="button is-danger is-outline is-mini" @click="resetDomain(domainData[1])"> <a class="button is-danger is-outline is-mini" @click="resetDomain(domainData[1])">
{{ i18n.templates.globalSections.tools.resetDomainConfig }} {{ $t('templates.globalSections.tools.resetDomainConfig') }}
</a> </a>
</div> </div>
<div class="control"> <div class="control">
<a class="button is-danger is-outline is-mini" @click="removeDomain(domainData[1])"> <a class="button is-danger is-outline is-mini" @click="removeDomain(domainData[1])">
{{ i18n.templates.globalSections.tools.removeDomain }} {{ $t('templates.globalSections.tools.removeDomain') }}
</a> </a>
</div> </div>
</div> </div>
@ -135,10 +135,10 @@ THE SOFTWARE.
<Modal ref="confirmModal" :title="confirmTitle"> <Modal ref="confirmModal" :title="confirmTitle">
<p>{{ confirmBody }}</p> <p>{{ confirmBody }}</p>
<a class="button is-danger is-outline" @click="doConfirmAction"> <a class="button is-danger is-outline" @click="doConfirmAction">
{{ i18n.templates.globalSections.tools.yesImSure }} {{ $t('templates.globalSections.tools.yesImSure') }}
</a> </a>
<a class="button is-outline" @click="$refs.confirmModal.close()"> <a class="button is-outline" @click="$refs.confirmModal.close()">
{{ i18n.templates.globalSections.tools.noCancel }} {{ $t('templates.globalSections.tools.noCancel') }}
</a> </a>
</Modal> </Modal>
</div> </div>
@ -147,7 +147,6 @@ THE SOFTWARE.
<script> <script>
import PrettyCheck from 'pretty-checkbox-vue/check'; import PrettyCheck from 'pretty-checkbox-vue/check';
import Modal from 'do-vue/src/templates/modal'; import Modal from 'do-vue/src/templates/modal';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults'; import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults'; import computedFromDefaults from '../../util/computed_from_defaults';
import shareQuery from '../../util/share_query'; import shareQuery from '../../util/share_query';
@ -166,7 +165,7 @@ THE SOFTWARE.
export default { export default {
name: 'GlobalTools', // Component name name: 'GlobalTools', // Component name
display: i18n.templates.globalSections.tools.tools, // Display name for tab display: 'templates.globalSections.tools.tools', // Display name for tab (i18n key)
key: 'tools', // Key for data in parent key: 'tools', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: { components: {
@ -178,7 +177,6 @@ THE SOFTWARE.
}, },
data() { data() {
return { return {
i18n,
confirmTitle: '', confirmTitle: '',
confirmBody: '', confirmBody: '',
confirmAction: () => {}, confirmAction: () => {},
@ -242,8 +240,8 @@ THE SOFTWARE.
}, },
resetGlobal() { resetGlobal() {
this.confirm( this.confirm(
i18n.templates.globalSections.tools.resetGlobalConfig, this.$t('templates.globalSections.tools.resetGlobalConfig'),
i18n.templates.globalSections.tools.resetGlobalConfigBody, this.$t('templates.globalSections.tools.resetGlobalConfigBody'),
() => { () => {
analytics('reset_global', 'Reset'); analytics('reset_global', 'Reset');
Object.values(this.$parent.$props.data).forEach(category => { Object.values(this.$parent.$props.data).forEach(category => {
@ -261,10 +259,10 @@ THE SOFTWARE.
if (!domain) return; if (!domain) return;
this.confirm( this.confirm(
i18n.templates.globalSections.tools.resetDomainConfig , this.$t('templates.globalSections.tools.resetDomainConfig'),
`${i18n.templates.globalSections.tools.areYouSureYouWantToResetAllConfigurationOptionsForThe} `${this.$t('templates.globalSections.tools.areYouSureYouWantToResetAllConfigurationOptionsForThe')}
${domain.server.domain.computed} ${domain.server.domain.computed}
${i18n.templates.globalSections.tools.domain}`, ${this.$t('templates.globalSections.tools.domain')}`,
() => { () => {
analytics('reset_domain', 'Reset', domain.server.domain.computed); analytics('reset_domain', 'Reset', domain.server.domain.computed);
this.doResetDomain(domain); this.doResetDomain(domain);
@ -277,10 +275,10 @@ THE SOFTWARE.
if (!domain) return; if (!domain) return;
this.confirm( this.confirm(
i18n.templates.globalSections.tools.removeDomain, this.$t('templates.globalSections.tools.removeDomain'),
`${i18n.templates.globalSections.tools.areYouSureYouWantToRemoveThe} `${this.$t('templates.globalSections.tools.areYouSureYouWantToRemoveThe')}
${domain.server.domain.computed} ${domain.server.domain.computed}
${i18n.templates.globalSections.tools.domainConfiguration}`, ${this.$t('templates.globalSections.tools.domainConfiguration')}`,
() => { () => {
analytics( analytics(
'remove_domain', 'remove_domain',
@ -295,8 +293,8 @@ THE SOFTWARE.
}, },
resetDomains() { resetDomains() {
this.confirm( this.confirm(
i18n.templates.globalSections.tools.resetAllDomainsConfig, this.$t('templates.globalSections.tools.resetAllDomainsConfig'),
i18n.templates.globalSections.tools.resetAllDomainsConfigBody, this.$t('templates.globalSections.tools.resetAllDomainsConfigBody'),
() => { () => {
analytics( analytics(
'reset_all', 'reset_all',
@ -313,8 +311,8 @@ THE SOFTWARE.
}, },
removeDomains() { removeDomains() {
this.confirm( this.confirm(
i18n.templates.globalSections.tools.removeAllDomains, this.$t('templates.globalSections.tools.removeAllDomains'),
i18n.templates.globalSections.tools.removeAllDomainsBody, this.$t('templates.globalSections.tools.removeAllDomainsBody'),
() => { () => {
analytics( analytics(
'remove_all', 'remove_all',

View File

@ -30,7 +30,7 @@ THE SOFTWARE.
<div class="tabs"> <div class="tabs">
<ul> <ul>
<li v-for="tab in tabs" :class="tabClass(tab.key)"> <li v-for="tab in tabs" :class="tabClass(tab.key)">
<a @click="active = tab.key">{{ tab.display }}</a> <a @click="active = tab.key">{{ $t(tab.display) }}</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -45,17 +45,17 @@ THE SOFTWARE.
<div class="navigation-buttons"> <div class="navigation-buttons">
<a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab"> <a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab">
<i class="fas fa-long-arrow-alt-left"></i> <span>{{ i18n.common.back }}</span> <i class="fas fa-long-arrow-alt-left"></i> <span>{{ $t('common.back') }}</span>
</a> </a>
<a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab"> <a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab">
<span>{{ i18n.common.next }}</span> <i class="fas fa-long-arrow-alt-right"></i> <span>{{ $t('common.next') }}</span> <i class="fas fa-long-arrow-alt-right"></i>
</a> </a>
</div> </div>
</div> </div>
<div class="buttons is-centered"> <div class="buttons is-centered">
<a class="button is-success" @click="downloadTar">{{ i18n.templates.setup.downloadConfig }}</a> <a class="button is-success" @click="downloadTar">{{ $t('templates.setup.downloadConfig') }}</a>
<a ref="copyTar" class="button is-primary">{{ i18n.templates.setup.copyBase64 }}</a> <a ref="copyTar" class="button is-primary">{{ $t('templates.setup.copyBase64') }}</a>
</div> </div>
</div> </div>
</template> </template>
@ -63,7 +63,6 @@ THE SOFTWARE.
<script> <script>
import Tar from 'memory-tar-create'; import Tar from 'memory-tar-create';
import ClipboardJS from 'clipboard'; import ClipboardJS from 'clipboard';
import i18n from '../i18n';
import analytics from '../util/analytics'; import analytics from '../util/analytics';
import * as Sections from './setup_sections'; import * as Sections from './setup_sections';
@ -76,7 +75,6 @@ THE SOFTWARE.
}, },
data() { data() {
return { return {
i18n,
active: tabs[0].key, active: tabs[0].key,
tabs, tabs,
}; };

View File

@ -29,7 +29,7 @@ THE SOFTWARE.
<ol v-if="letsEncryptActive"> <ol v-if="letsEncryptActive">
<li> <li>
<p> <p>
{{ i18n.templates.setupSections.certbot.commentOutSslDirectivesInConfiguration }} {{ $t('templates.setupSections.certbot.commentOutSslDirectivesInConfiguration') }}
<br /> <br />
</p> </p>
<BashPrism :key="sitesAvailable" <BashPrism :key="sitesAvailable"
@ -39,7 +39,7 @@ THE SOFTWARE.
<li> <li>
<p> <p>
{{ i18n.templates.setupSections.certbot.reloadYourNginxServer }} {{ $t('templates.setupSections.certbot.reloadYourNginxServer') }}
<br /> <br />
</p> </p>
<BashPrism cmd="sudo nginx -t && sudo systemctl reload nginx"></BashPrism> <BashPrism cmd="sudo nginx -t && sudo systemctl reload nginx"></BashPrism>
@ -47,7 +47,7 @@ THE SOFTWARE.
<li> <li>
<p> <p>
{{ i18n.templates.setupSections.certbot.obtainSslCertificatesFromLetsEncrypt }} {{ $t('templates.setupSections.certbot.obtainSslCertificatesFromLetsEncrypt') }}
<br /> <br />
</p> </p>
<BashPrism :key="certbotCmds" :cmd="certbotCmds"></BashPrism> <BashPrism :key="certbotCmds" :cmd="certbotCmds"></BashPrism>
@ -55,7 +55,7 @@ THE SOFTWARE.
<li> <li>
<p> <p>
{{ i18n.templates.setupSections.certbot.uncommentSslDirectivesInConfiguration }} {{ $t('templates.setupSections.certbot.uncommentSslDirectivesInConfiguration') }}
<br /> <br />
</p> </p>
<BashPrism :key="sitesAvailable" :cmd="`sed -i -r 's/#?;#//g' ${sitesAvailable}`"></BashPrism> <BashPrism :key="sitesAvailable" :cmd="`sed -i -r 's/#?;#//g' ${sitesAvailable}`"></BashPrism>
@ -63,7 +63,7 @@ THE SOFTWARE.
<li> <li>
<p> <p>
{{ i18n.templates.setupSections.certbot.reloadYourNginxServer }} {{ $t('templates.setupSections.certbot.reloadYourNginxServer') }}
<br /> <br />
</p> </p>
<BashPrism cmd="sudo nginx -t && sudo systemctl reload nginx"></BashPrism> <BashPrism cmd="sudo nginx -t && sudo systemctl reload nginx"></BashPrism>
@ -71,7 +71,7 @@ THE SOFTWARE.
<li> <li>
<p> <p>
{{ i18n.templates.setupSections.certbot.configureCertbotToReloadNginxOnCertificateRenewal }} {{ $t('templates.setupSections.certbot.configureCertbotToReloadNginxOnCertificateRenewal') }}
<br /> <br />
</p> </p>
<BashPrism cmd="echo -e '#!/bin/bash\nnginx -t && systemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh"></BashPrism> <BashPrism cmd="echo -e '#!/bin/bash\nnginx -t && systemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh"></BashPrism>
@ -84,7 +84,7 @@ THE SOFTWARE.
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.setupSections.certbot.certbotDoesNotNeedToBeSetupForYourConfiguration }} {{ $t('templates.setupSections.certbot.certbotDoesNotNeedToBeSetupForYourConfiguration') }}
</label> </label>
</div> </div>
</div> </div>
@ -94,12 +94,11 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n';
import BashPrism from '../prism/bash'; import BashPrism from '../prism/bash';
export default { export default {
name: 'SetupCertbot', name: 'SetupCertbot',
display: i18n.templates.setupSections.certbot.certbot, display: 'templates.setupSections.certbot.certbot', // i18n key
key: 'certbot', key: 'certbot',
components: { components: {
BashPrism, BashPrism,
@ -107,11 +106,6 @@ THE SOFTWARE.
props: { props: {
data: Object, data: Object,
}, },
data() {
return {
i18n,
};
},
computed: { computed: {
letsEncryptDir() { letsEncryptDir() {
return this.$props.data.global.https.letsEncryptRoot.computed.replace(/\/+$/, ''); return this.$props.data.global.https.letsEncryptRoot.computed.replace(/\/+$/, '');

View File

@ -29,26 +29,26 @@ THE SOFTWARE.
<ol> <ol>
<li> <li>
<p> <p>
<span v-html="i18n.templates.setupSections.download.downloadTheGeneratedConfig"></span> <span v-html="$t('templates.setupSections.download.downloadTheGeneratedConfig')"></span>
<b>&nbsp;<a @click="$parent.downloadTar">{{ $parent.tarName }}</a></b> <b>&nbsp;<a @click="$parent.downloadTar">{{ $parent.tarName }}</a></b>
<br /> <br />
<span v-html="i18n.templates.setupSections.download.andUploadItToYourServers"></span> <span v-html="$t('templates.setupSections.download.andUploadItToYourServers')"></span>
<code class="slim">{{ $props.data.global.nginx.nginxConfigDirectory.computed }}</code> <code class="slim">{{ $props.data.global.nginx.nginxConfigDirectory.computed }}</code>
{{ i18n.templates.setupSections.download.directory }} {{ $t('templates.setupSections.download.directory') }}
</p> </p>
<p> <p>
{{ i18n.templates.setupSections.download.or }} {{ $t('templates.setupSections.download.or') }}
<b> <b>
<a ref="copyTar"> <a ref="copyTar">
{{ i18n.templates.setupSections.download.copyBase64StringOfCompressedConfig }}</a> {{ $t('templates.setupSections.download.copyBase64StringOfCompressedConfig') }}</a>
</b> </b>
<span v-html="i18n.templates.setupSections.download.pasteItInYourServersCommandLineAndExecute"></span> <span v-html="$t('templates.setupSections.download.pasteItInYourServersCommandLineAndExecute')"></span>
</p> </p>
</li> </li>
<li> <li>
<p> <p>
<span v-html="i18n.templates.setupSections.download.navigateToYourNginxConfigurationDirectoryOnYourServer"></span> <span v-html="$t('templates.setupSections.download.navigateToYourNginxConfigurationDirectoryOnYourServer')"></span>
<br /> <br />
<BashPrism :key="$props.data.global.nginx.nginxConfigDirectory.computed" <BashPrism :key="$props.data.global.nginx.nginxConfigDirectory.computed"
:cmd="`cd ${$props.data.global.nginx.nginxConfigDirectory.computed}`" :cmd="`cd ${$props.data.global.nginx.nginxConfigDirectory.computed}`"
@ -58,7 +58,7 @@ THE SOFTWARE.
<li> <li>
<p> <p>
<span v-html="i18n.templates.setupSections.download.createABackupOfYourCurrentNginxConfiguration"></span> <span v-html="$t('templates.setupSections.download.createABackupOfYourCurrentNginxConfiguration')"></span>
<br /> <br />
<BashPrism cmd="tar -czvf nginx_$(date +'%F_%H-%M-%S').tar.gz nginx.conf sites-available/ sites-enabled/ nginxconfig.io/"></BashPrism> <BashPrism cmd="tar -czvf nginx_$(date +'%F_%H-%M-%S').tar.gz nginx.conf sites-available/ sites-enabled/ nginxconfig.io/"></BashPrism>
</p> </p>
@ -66,7 +66,7 @@ THE SOFTWARE.
<li> <li>
<p> <p>
<span v-html="i18n.templates.setupSections.download.extractTheNewCompressedConfigurationArchiveUsingTar"></span> <span v-html="$t('templates.setupSections.download.extractTheNewCompressedConfigurationArchiveUsingTar')"></span>
<br /> <br />
<BashPrism :key="$parent.tarName" :cmd="`tar -xzvf ${$parent.tarName}`"></BashPrism> <BashPrism :key="$parent.tarName" :cmd="`tar -xzvf ${$parent.tarName}`"></BashPrism>
</p> </p>
@ -76,12 +76,11 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n';
import BashPrism from '../prism/bash'; import BashPrism from '../prism/bash';
export default { export default {
name: 'SetupDownload', name: 'SetupDownload',
display: i18n.templates.setupSections.download.download, display: 'templates.setupSections.download.download', // i18n key
key: 'download', key: 'download',
components: { components: {
BashPrism, BashPrism,
@ -89,11 +88,6 @@ THE SOFTWARE.
props: { props: {
data: Object, data: Object,
}, },
data() {
return {
i18n,
};
},
mounted() { mounted() {
this.$parent.setupCopy(this.$refs.copyTar); this.$parent.setupCopy(this.$refs.copyTar);
}, },

View File

@ -27,10 +27,10 @@ THE SOFTWARE.
<template> <template>
<div> <div>
<p> <p>
<b>{{ i18n.templates.setupSections.goLive.letsGoLive }}</b> 🎉 <b>{{ $t('templates.setupSections.goLive.letsGoLive') }}</b> 🎉
</p> </p>
<p> <p>
{{ i18n.templates.setupSections.goLive.reloadNginxToLoadInYourNewConfiguration }} {{ $t('templates.setupSections.goLive.reloadNginxToLoadInYourNewConfiguration') }}
<br /> <br />
<BashPrism cmd="sudo nginx -t && sudo systemctl reload nginx"></BashPrism> <BashPrism cmd="sudo nginx -t && sudo systemctl reload nginx"></BashPrism>
</p> </p>
@ -38,12 +38,11 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n';
import BashPrism from '../prism/bash'; import BashPrism from '../prism/bash';
export default { export default {
name: 'SetupGoLive', name: 'SetupGoLive',
display: i18n.templates.setupSections.goLive.goLive, display: 'templates.setupSections.goLive.goLive', // i18n key
key: 'goLive', key: 'goLive',
components: { components: {
BashPrism, BashPrism,
@ -51,10 +50,5 @@ THE SOFTWARE.
props: { props: {
data: Object, data: Object,
}, },
data() {
return {
i18n,
};
},
}; };
</script> </script>

View File

@ -29,7 +29,7 @@ THE SOFTWARE.
<ol v-if="diffieHellmanValue || letsEncryptActive"> <ol v-if="diffieHellmanValue || letsEncryptActive">
<li v-if="diffieHellmanValue"> <li v-if="diffieHellmanValue">
<p> <p>
<span v-html="i18n.templates.setupSections.ssl.generateDiffieHellmanKeysByRunningThisCommandOnYourServer"></span> <span v-html="$t('templates.setupSections.ssl.generateDiffieHellmanKeysByRunningThisCommandOnYourServer')"></span>
<br /> <br />
<BashPrism :key="`${$props.data.global.nginx.nginxConfigDirectory.computed}-${diffieHellmanValue}`" <BashPrism :key="`${$props.data.global.nginx.nginxConfigDirectory.computed}-${diffieHellmanValue}`"
:cmd="`openssl dhparam -out ${$props.data.global.nginx.nginxConfigDirectory.computed}/dhparam.pem ${diffieHellmanValue}`" :cmd="`openssl dhparam -out ${$props.data.global.nginx.nginxConfigDirectory.computed}/dhparam.pem ${diffieHellmanValue}`"
@ -39,7 +39,7 @@ THE SOFTWARE.
<li v-if="letsEncryptActive"> <li v-if="letsEncryptActive">
<p> <p>
<span v-html="i18n.templates.setupSections.ssl.createACommonAcmeChallengeDirectoryForLetsEncrypt"></span> <span v-html="$t('templates.setupSections.ssl.createACommonAcmeChallengeDirectoryForLetsEncrypt')"></span>
<br /> <br />
<BashPrism :key="letsEncryptDir" :cmd="`mkdir -p ${letsEncryptDir}`"></BashPrism> <BashPrism :key="letsEncryptDir" :cmd="`mkdir -p ${letsEncryptDir}`"></BashPrism>
<BashPrism :key="`${nginxUser}-${letsEncryptDir}`" <BashPrism :key="`${nginxUser}-${letsEncryptDir}`"
@ -54,7 +54,7 @@ THE SOFTWARE.
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<label class="text"> <label class="text">
{{ i18n.templates.setupSections.ssl.noAdditionalStepsAreNeededToSetUpSslForNginx }} {{ $t('templates.setupSections.ssl.noAdditionalStepsAreNeededToSetUpSslForNginx') }}
</label> </label>
</div> </div>
</div> </div>
@ -64,12 +64,11 @@ THE SOFTWARE.
</template> </template>
<script> <script>
import i18n from '../../i18n';
import BashPrism from '../prism/bash'; import BashPrism from '../prism/bash';
export default { export default {
name: 'SetupSSL', name: 'SetupSSL',
display: i18n.templates.setupSections.ssl.sslInit, display: 'templates.setupSections.ssl.sslInit', // i18n key
key: 'ssl', key: 'ssl',
components: { components: {
BashPrism, BashPrism,
@ -77,11 +76,6 @@ THE SOFTWARE.
props: { props: {
data: Object, data: Object,
}, },
data() {
return {
i18n,
};
},
computed: { computed: {
letsEncryptDir() { letsEncryptDir() {
return this.$props.data.global.https.letsEncryptRoot.computed.replace(/\/+$/, ''); return this.$props.data.global.https.letsEncryptRoot.computed.replace(/\/+$/, '');

View File

@ -0,0 +1,59 @@
/*
Copyright 2020 DigitalOcean
This code is licensed under the MIT License.
You may obtain a copy of the License at
https://github.com/digitalocean/nginxconfig.io/blob/master/LICENSE or https://mit-license.org/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
import * as i18nPacks from '../i18n';
const toPack = locale => locale.split('-', 2)[0].toLowerCase() + (locale.split('-', 2)[1] || '').toUpperCase();
export default () => {
if (typeof window === 'object' && typeof window.navigator === 'object') {
const userLocales = new Set();
// Get the user languages
if (Array.isArray(window.navigator.languages))
window.navigator.languages.forEach(locale => userLocales.add(locale));
if (typeof window.navigator.language === 'string')
userLocales.add(window.navigator.language);
if (Intl && 'DateTimeFormat' in Intl)
userLocales.add(Intl.DateTimeFormat().resolvedOptions().locale);
// Try to find an exact region/language match
const i18nPackLocales = Object.keys(i18nPacks);
const exactMatch = [...userLocales.values()].find(locale => i18nPackLocales.includes(toPack(locale)));
if (exactMatch) return toPack(exactMatch);
// Build a map of languages to pack
const i18nPackLanguages = i18nPackLocales.reduce((map, pack) => {
const lang = pack.match(/^[a-z]+/)[0];
if (!(lang in map)) map[lang] = pack;
return map;
}, {});
// Try to match a user language to a pack language
const langMatch = [...userLocales.values()].find(x => i18nPackLanguages.includes(x.split('-')[0].toLowerCase()));
if (langMatch) return i18nPackLanguages[langMatch.split('-')[0].toLowerCase()];
}
};

View File

@ -60,7 +60,7 @@ const applyCategories = (categories, target) => {
} }
}; };
export default (query, domains, global, nextTick) => { export default (query, domains, global, nextTick) => new Promise(resolve => {
const data = qs.parse(query, { const data = qs.parse(query, {
ignoreQueryPrefix: true, ignoreQueryPrefix: true,
allowDots: true, allowDots: true,
@ -117,4 +117,7 @@ export default (query, domains, global, nextTick) => {
// If this is an object, apply any potential data // If this is an object, apply any potential data
if (isObject(data.global)) applyCategories(data.global, global); if (isObject(data.global)) applyCategories(data.global, global);
} }
};
// Resolve after everything has updated
nextTick(() => nextTick(() => resolve(data)));
});