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>
This commit is contained in:
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==",
"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": {
"version": "15.9.3",
"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",
"string-similarity": "^4.0.2",
"vue": "^2.6.12",
"vue-i18n": "^8.22.2",
"vue-select": "^3.10.8"
},
"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',
reverseProxyLower: 'reverse proxy',
restrict: 'Restrict',
listen: 'listen',
path: 'Path',
};

View file

@ -29,6 +29,9 @@ import common from '../common';
export default {
title: `${common.nginx}Config`,
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',
splitColumnMode: 'Split column mode',
perWebsiteConfig: 'Per-website config',

View file

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

View file

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

View file

@ -26,13 +26,12 @@ THE SOFTWARE.
export default {
domain: 'Domain',
path: 'Path',
documentRoot: 'Document root',
oneOrMoreOtherDomainsAreAlsoNamed: 'One or more other domains are also named',
thisWillCauseIssuesWithConfigGeneration: 'This will cause issues with config generation.',
wwwSubdomain: 'www subdomain',
cdnSubdomain: 'CDN subdomain',
redirectSubdomains: 'Redirect subdomains',
routing: 'Routing',
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.
*/
import en from './en';
const lang = 'en';
const packs = { en };
export default packs[lang];
export { default as en } from './en';
export { default as zhCN } from './zh-cn';
export { default as zhTW } from './zh-tw';

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -26,12 +26,21 @@ THE SOFTWARE.
import './scss/style.scss';
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import './util/prism_bundle';
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({
i18n,
render: h => h(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);
.vs__selected {
height: $height;
position: unset;
top: .75em;
}
.vs__search {
position: absolute;
width: 100%;
}
}
}
@ -60,6 +67,17 @@ THE SOFTWARE.
margin: 0;
padding: 0;
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 {
@ -76,7 +94,13 @@ THE SOFTWARE.
}
.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;
@import "~vue-select/src/scss/vue-select";
@import "header";
@import "tabs";
@import "panel";
@import "fields";

View file

@ -26,18 +26,30 @@ THE SOFTWARE.
<template>
<div class="all do-bulma">
<Header :title="i18n.templates.app.title">
<Header :title="$t('templates.app.title')">
<template #description>
{{ i18n.templates.app.description }}
{{ $t('templates.app.description') }}
</template>
<template #header>
</template>
<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">
{{ i18n.templates.app.singleColumnMode }}
{{ $t('templates.app.singleColumnMode') }}
</a>
<a v-else class="button is-primary is-hidden-touch" @click="splitColumnToggle">
{{ i18n.templates.app.splitColumnMode }}
{{ $t('templates.app.splitColumnMode') }}
</a>
</template>
</Header>
@ -45,7 +57,7 @@ THE SOFTWARE.
<div class="main container" :style="{ display: ready ? undefined : 'none' }">
<div class="columns is-multiline">
<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">
<ul>
@ -58,7 +70,7 @@ THE SOFTWARE.
</a>
</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>
</ul>
</div>
@ -70,15 +82,15 @@ THE SOFTWARE.
></Domain>
</template>
<h2>{{ i18n.templates.app.globalConfig }}</h2>
<h2>{{ $t('templates.app.globalConfig') }}</h2>
<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>
</div>
<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">
<template v-for="confContents in confFilesOutput">
<component
@ -102,6 +114,7 @@ THE SOFTWARE.
import clone from 'clone';
import sha2_256 from 'simple-js-sha2-256';
import escape from 'escape-html';
import VueSelect from 'vue-select';
import Header from 'do-vue/src/templates/header';
import diff from 'files-diff';
@ -109,8 +122,10 @@ THE SOFTWARE.
import importData from '../util/import_data';
import isObject from '../util/is_object';
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 Domain from './domain';
@ -124,6 +139,7 @@ THE SOFTWARE.
name: 'App',
components: {
Header,
VueSelect,
Footer,
Domain,
Global,
@ -134,9 +150,18 @@ THE SOFTWARE.
},
data() {
return {
i18n,
domains: [],
global: Global.delegated,
global: {
...Global.delegated,
app: {
lang: {
default: i18nDefault,
value: i18nDefault,
computed: i18nDefault,
enabled: true,
},
},
},
active: 0,
ready: false,
splitColumn: false,
@ -152,6 +177,23 @@ THE SOFTWARE.
confFiles() {
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: {
confFiles(newConf, oldConf) {
@ -164,13 +206,29 @@ THE SOFTWARE.
// Check next tick to see if anything has changed again
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
// 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
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
this.splitColumnEvent(true);

View file

@ -34,7 +34,7 @@ THE SOFTWARE.
<div class="tabs">
<ul>
<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>
</ul>
</div>
@ -49,10 +49,10 @@ THE SOFTWARE.
<div class="navigation-buttons">
<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 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>
</div>
</div>
@ -60,7 +60,6 @@ THE SOFTWARE.
</template>
<script>
import i18n from '../i18n';
import isChanged from '../util/is_changed';
import Presets from './domain_sections/presets';
import * as Sections from './domain_sections';
@ -86,7 +85,6 @@ THE SOFTWARE.
},
data() {
return {
i18n,
active: tabs[0].key,
tabs,
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -38,7 +38,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="getMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -55,7 +55,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="postMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -72,7 +72,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="putMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -89,7 +89,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="patchMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -106,7 +106,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="deleteMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -125,7 +125,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="headMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -142,7 +142,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="connectMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -159,7 +159,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="optionsMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -176,7 +176,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="traceMethod" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.restrict.disableForThisDomain }}
{{ $t('templates.domainSections.restrict.disableForThisDomain') }}
</PrettyCheck>
</div>
</div>
@ -187,7 +187,7 @@ THE SOFTWARE.
</div>
<div v-if="hasAtLeastOneEnabled" class="field is-horizontal">
<div class="field-label">
<label class="label">{{ i18n.templates.domainSections.restrict.responseCode }}</label>
<label class="label">{{ $t('templates.domainSections.restrict.responseCode') }}</label>
</div>
<div class="field-body">
<div class="field">
@ -208,7 +208,6 @@ THE SOFTWARE.
<script>
import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults';
@ -256,24 +255,23 @@ THE SOFTWARE.
};
export default {
name: 'DomainRestrict', // Component name
display: i18n.common.restrict, // Display name for tab
key: 'restrict', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
name: 'DomainRestrict', // Component name
display: 'common.restrict', // Display name for tab (i18n key)
key: 'restrict', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: {
PrettyCheck,
},
props: {
data: Object, // Data delegated back to us from parent
data: Object, // Data delegated back to us from parent
},
data () {
return {
i18n,
validResponseCode: true,
};
},
computed: {
...computedFromDefaults(defaults, 'restrict'), // Getters & setters for the delegated data
...computedFromDefaults(defaults, 'restrict'), // Getters & setters for the delegated data
hasAtLeastOneEnabled() {
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 v-if="!reverseProxyEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label">
<label class="label">{{ i18n.common.reverseProxy }}</label>
<label class="label">{{ $t('common.reverseProxy') }}</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<label class="text">
{{ i18n.templates.domainSections.reverseProxy.reverseProxyIsDisabled }}
{{ $t('templates.domainSections.reverseProxy.reverseProxyIsDisabled') }}
<template v-if="$parent.$props.data.php.php.computed">
<br />{{ i18n.templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPhp }}
<br />{{ $t('templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPhp') }}
</template>
<template v-if="$parent.$props.data.python.python.computed">
<br />{{ i18n.templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPython }}
<br />{{ $t('templates.domainSections.reverseProxy.reverseProxyCannotBeEnabledWithPython') }}
</template>
</label>
</div>
@ -49,7 +49,7 @@ THE SOFTWARE.
<div v-else class="field is-horizontal">
<div class="field-label">
<label class="label">{{ i18n.common.reverseProxy }}</label>
<label class="label">{{ $t('common.reverseProxy') }}</label>
</div>
<div class="field-body">
<div :class="`field${reverseProxyChanged ? ' is-changed' : ''}`">
@ -57,7 +57,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="reverseProxy" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.reverseProxy.enableReverseProxy }}
{{ $t('templates.domainSections.reverseProxy.enableReverseProxy') }}
</PrettyCheck>
</div>
</div>
@ -67,7 +67,7 @@ THE SOFTWARE.
<div v-if="pathEnabled" class="field is-horizontal">
<div class="field-label">
<label class="label">{{ i18n.templates.domainSections.reverseProxy.path }}</label>
<label class="label">{{ $t('common.path') }}</label>
</div>
<div class="field-body">
<div :class="`field${pathChanged ? ' is-changed' : ''}`">
@ -103,7 +103,6 @@ THE SOFTWARE.
<script>
import PrettyCheck from 'pretty-checkbox-vue/check';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults';
@ -124,7 +123,7 @@ THE SOFTWARE.
export default {
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
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: {
@ -133,11 +132,6 @@ THE SOFTWARE.
props: {
data: Object, // Data delegated back to us from parent
},
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'reverseProxy'), // Getters & setters for the delegated data
watch: {
// 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">
<PrettyCheck v-model="root" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.common.enable }}
{{ $t('common.enable') }}
</PrettyCheck>
</div>
</div>
@ -66,7 +66,7 @@ THE SOFTWARE.
<div v-if="fallbackHtmlEnabled || fallbackPhpEnabled" class="field is-horizontal is-aligned-top">
<div class="field-label">
<label class="label">{{ i18n.templates.domainSections.routing.fallbackRouting }}</label>
<label class="label">{{ $t('templates.domainSections.routing.fallbackRouting') }}</label>
</div>
<div class="field-body">
<div class="field">
@ -92,7 +92,7 @@ THE SOFTWARE.
<div v-if="fallbackPhpPathEnabled" class="field is-horizontal">
<div class="field-label">
<label class="label">{{ i18n.templates.domainSections.routing.fallbackRoutingPhpPath }}</label>
<label class="label">{{ $t('templates.domainSections.routing.fallbackRoutingPhpPath') }}</label>
</div>
<div class="field-body">
<div :class="`field${fallbackPhpPathChanged ? ' is-changed' : ''}`">
@ -109,7 +109,7 @@ THE SOFTWARE.
<div v-if="legacyPhpRoutingEnabled" class="field is-horizontal">
<div class="field-label">
<label class="label">{{ i18n.templates.domainSections.routing.legacyPhpRouting }}</label>
<label class="label">{{ $t('templates.domainSections.routing.legacyPhpRouting') }}</label>
</div>
<div class="field-body">
<div class="field">
@ -117,7 +117,7 @@ THE SOFTWARE.
<div class="checkbox">
<PrettyCheck v-model="legacyPhpRouting" class="p-default p-curve p-fill p-icon">
<i slot="extra" class="icon fas fa-check"></i>
{{ i18n.templates.domainSections.routing.enableLegacyRouting }}
{{ $t('templates.domainSections.routing.enableLegacyRouting') }}
</PrettyCheck>
</div>
</div>
@ -130,7 +130,6 @@ THE SOFTWARE.
<script>
import PrettyCheck from 'pretty-checkbox-vue/check';
import PrettyRadio from 'pretty-checkbox-vue/radio';
import i18n from '../../i18n';
import delegatedFromDefaults from '../../util/delegated_from_defaults';
import computedFromDefaults from '../../util/computed_from_defaults';
@ -164,7 +163,7 @@ THE SOFTWARE.
export default {
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
delegated: delegatedFromDefaults(defaults), // Data the parent will present here
components: {
@ -174,12 +173,7 @@ THE SOFTWARE.
props: {
data: Object, // Data delegated back to us from parent
},
data () {
return {
i18n,
};
},
computed: computedFromDefaults(defaults, 'routing'), // Getters & setters for the delegated data
computed: computedFromDefaults(defaults, 'routing'), // Getters & setters for the delegated data
watch: {
// Disable all options (expect legacy php) if root is disabled
'$props.data.root': {

View file

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

View file

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

View file

@ -29,7 +29,7 @@ THE SOFTWARE.
<div class="tabs">
<ul>
<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>
</ul>
</div>
@ -44,17 +44,16 @@ THE SOFTWARE.
<div class="navigation-buttons">
<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 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>
</div>
</div>
</template>
<script>
import i18n from '../i18n';
import isChanged from '../util/is_changed';
import * as Sections from './global_sections';
@ -72,7 +71,6 @@ THE SOFTWARE.
},
data() {
return {
i18n,
active: tabs[0].key,
tabs,
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -30,7 +30,7 @@ THE SOFTWARE.
<div class="tabs">
<ul>
<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>
</ul>
</div>
@ -45,17 +45,17 @@ THE SOFTWARE.
<div class="navigation-buttons">
<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 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>
</div>
</div>
<div class="buttons is-centered">
<a class="button is-success" @click="downloadTar">{{ i18n.templates.setup.downloadConfig }}</a>
<a ref="copyTar" class="button is-primary">{{ i18n.templates.setup.copyBase64 }}</a>
<a class="button is-success" @click="downloadTar">{{ $t('templates.setup.downloadConfig') }}</a>
<a ref="copyTar" class="button is-primary">{{ $t('templates.setup.copyBase64') }}</a>
</div>
</div>
</template>
@ -63,7 +63,6 @@ THE SOFTWARE.
<script>
import Tar from 'memory-tar-create';
import ClipboardJS from 'clipboard';
import i18n from '../i18n';
import analytics from '../util/analytics';
import * as Sections from './setup_sections';
@ -76,7 +75,6 @@ THE SOFTWARE.
},
data() {
return {
i18n,
active: tabs[0].key,
tabs,
};

View file

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

View file

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

View file

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

View file

@ -29,7 +29,7 @@ THE SOFTWARE.
<ol v-if="diffieHellmanValue || letsEncryptActive">
<li v-if="diffieHellmanValue">
<p>
<span v-html="i18n.templates.setupSections.ssl.generateDiffieHellmanKeysByRunningThisCommandOnYourServer"></span>
<span v-html="$t('templates.setupSections.ssl.generateDiffieHellmanKeysByRunningThisCommandOnYourServer')"></span>
<br />
<BashPrism :key="`${$props.data.global.nginx.nginxConfigDirectory.computed}-${diffieHellmanValue}`"
:cmd="`openssl dhparam -out ${$props.data.global.nginx.nginxConfigDirectory.computed}/dhparam.pem ${diffieHellmanValue}`"
@ -39,7 +39,7 @@ THE SOFTWARE.
<li v-if="letsEncryptActive">
<p>
<span v-html="i18n.templates.setupSections.ssl.createACommonAcmeChallengeDirectoryForLetsEncrypt"></span>
<span v-html="$t('templates.setupSections.ssl.createACommonAcmeChallengeDirectoryForLetsEncrypt')"></span>
<br />
<BashPrism :key="letsEncryptDir" :cmd="`mkdir -p ${letsEncryptDir}`"></BashPrism>
<BashPrism :key="`${nginxUser}-${letsEncryptDir}`"
@ -54,7 +54,7 @@ THE SOFTWARE.
<div class="field">
<div class="control">
<label class="text">
{{ i18n.templates.setupSections.ssl.noAdditionalStepsAreNeededToSetUpSslForNginx }}
{{ $t('templates.setupSections.ssl.noAdditionalStepsAreNeededToSetUpSslForNginx') }}
</label>
</div>
</div>
@ -64,12 +64,11 @@ THE SOFTWARE.
</template>
<script>
import i18n from '../../i18n';
import BashPrism from '../prism/bash';
export default {
name: 'SetupSSL',
display: i18n.templates.setupSections.ssl.sslInit,
display: 'templates.setupSections.ssl.sslInit', // i18n key
key: 'ssl',
components: {
BashPrism,
@ -77,11 +76,6 @@ THE SOFTWARE.
props: {
data: Object,
},
data() {
return {
i18n,
};
},
computed: {
letsEncryptDir() {
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, {
ignoreQueryPrefix: true,
allowDots: true,
@ -117,4 +117,7 @@ export default (query, domains, global, nextTick) => {
// If this is an object, apply any potential data
if (isObject(data.global)) applyCategories(data.global, global);
}
};
// Resolve after everything has updated
nextTick(() => nextTick(() => resolve(data)));
});