diff --git a/src/.env.example b/src/.env.example
--- a/src/.env.example
+++ b/src/.env.example
@@ -6,6 +6,7 @@
APP_PUBLIC_URL=
APP_DOMAIN=kolabnow.com
APP_THEME=default
+APP_LOCALE=en
ASSET_URL=http://127.0.0.1:8000
diff --git a/src/app/Http/Kernel.php b/src/app/Http/Kernel.php
--- a/src/app/Http/Kernel.php
+++ b/src/app/Http/Kernel.php
@@ -21,6 +21,7 @@
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\DevelConfig::class,
+ \App\Http\Middleware\Locale::class,
// FIXME: CORS handling added here, I didn't find a nice way
// to add this only to the API routes
// \App\Http\Middleware\Cors::class,
diff --git a/src/app/Http/Middleware/Locale.php b/src/app/Http/Middleware/Locale.php
new file mode 100644
--- /dev/null
+++ b/src/app/Http/Middleware/Locale.php
@@ -0,0 +1,43 @@
+getLanguages()
+ );
+
+ $default = config('app.locale');
+ $lang = null;
+
+ foreach ($preferences as $pref) {
+ if (!empty($pref) && ($pref == $default || file_exists("$langDir/$pref"))) {
+ $lang = $pref;
+ break;
+ }
+ }
+
+ if ($lang != $default) {
+ app()->setLocale($lang);
+ }
+
+ return $next($request);
+ }
+}
diff --git a/src/config/app.php b/src/config/app.php
--- a/src/config/app.php
+++ b/src/config/app.php
@@ -98,7 +98,7 @@
|
*/
- 'locale' => 'en',
+ 'locale' => env('APP_LOCALE', 'en'),
/*
|--------------------------------------------------------------------------
diff --git a/src/package.json b/src/package.json
--- a/src/package.json
+++ b/src/package.json
@@ -33,6 +33,7 @@
"stylelint": "^13.8.0",
"stylelint-config-standard": "^20.0.0",
"vue": "^2.6.12",
+ "vue-i18n": "^8.24.1",
"vue-router": "^3.4.9",
"vue-template-compiler": "^2.6.12",
"vuex": "^3.6.0"
diff --git a/src/resources/js/app.js b/src/resources/js/app.js
--- a/src/resources/js/app.js
+++ b/src/resources/js/app.js
@@ -10,6 +10,7 @@
import MenuComponent from '../vue/Widgets/Menu'
import SupportForm from '../vue/Widgets/SupportForm'
import store from './store'
+import { loadLanguageAsync, i18n } from './locale'
const loader = '
'
@@ -53,7 +54,7 @@
loadingRoute = to.name
}
- next()
+ loadLanguageAsync().then(() => next())
})
window.router.afterEach((to, from) => {
@@ -74,6 +75,7 @@
AppComponent,
MenuComponent,
},
+ i18n,
store,
router: window.router,
data() {
diff --git a/src/resources/js/locale.js b/src/resources/js/locale.js
new file mode 100644
--- /dev/null
+++ b/src/resources/js/locale.js
@@ -0,0 +1,56 @@
+import Vue from 'vue'
+import VueI18n from 'vue-i18n'
+import messages from '../lang-js/en'
+
+Vue.use(VueI18n)
+
+export const i18n = new VueI18n({
+ locale: 'en',
+ fallbackLocale: 'en',
+ messages: { en: messages },
+ silentFallbackWarn: true
+})
+
+let currentLanguage
+
+const loadedLanguages = [ 'en' ] // our default language that is preloaded
+
+const setI18nLanguage = (lang) => {
+ i18n.locale = lang
+ window.axios.defaults.headers.common['Accept-Language'] = lang
+ document.querySelector('html').setAttribute('lang', lang)
+
+ return lang
+}
+
+export const getLang = () => {
+ // TODO: On init get the current user language from the browser?
+ if (!currentLanguage) {
+ currentLanguage = document.querySelector('html').getAttribute('lang') || 'en'
+ }
+
+ return currentLanguage
+}
+
+export const setLang = lang => {
+ // TODO: Save the selected language in the browser?
+ currentLanguage = lang
+ loadLanguageAsync()
+}
+
+export function loadLanguageAsync() {
+ const lang = getLang()
+
+ // If the language was already loaded
+ if (loadedLanguages.includes(lang)) {
+ return Promise.resolve(setI18nLanguage(lang))
+ }
+
+ // If the language hasn't been loaded yet
+ return import(/* webpackChunkName: "locale/[request]" */ `../lang-js/${lang}`)
+ .then(messages => {
+ i18n.setLocaleMessage(lang, messages.default)
+ loadedLanguages.push(lang)
+ return setI18nLanguage(lang)
+ })
+}
diff --git a/src/resources/lang-js/de.js b/src/resources/lang-js/de.js
new file mode 100644
--- /dev/null
+++ b/src/resources/lang-js/de.js
@@ -0,0 +1,18 @@
+export default {
+ buttons: {
+ cancel: "Stornieren",
+ save: "Speichern"
+ },
+ menu: {
+ cockpit: "Cockpit",
+ login: "Einloggen",
+ logout: "Ausloggen",
+ signup: "Signup",
+ toggle: "Navigation umschalten"
+ },
+ login: {
+ forgot_password: "Passwort vergessen?",
+ sign_in: "Anmelden",
+ webmail: "Webmail"
+ }
+}
diff --git a/src/resources/lang-js/en.js b/src/resources/lang-js/en.js
new file mode 100644
--- /dev/null
+++ b/src/resources/lang-js/en.js
@@ -0,0 +1,18 @@
+export default {
+ buttons: {
+ cancel: "Cancel",
+ save: "Save"
+ },
+ menu: {
+ cockpit: "Cockpit",
+ login: "Login",
+ logout: "Logout",
+ signup: "Signup",
+ toggle: "Toggle navigation"
+ },
+ login: {
+ forgot_password: "Forgot password?",
+ sign_in: "Sign in",
+ webmail: "Webmail"
+ }
+}
diff --git a/src/resources/themes/menu.scss b/src/resources/themes/menu.scss
--- a/src/resources/themes/menu.scss
+++ b/src/resources/themes/menu.scss
@@ -56,6 +56,17 @@
}
}
+#language-selector {
+ width: auto;
+ position: absolute;
+ right: 0;
+ top: 0;
+ border: 0;
+ background-color: transparent;
+ padding-right: 1.4rem;
+ margin: 0.25em;
+}
+
@include media-breakpoint-up(lg) {
#header-menu {
a.menulogin {
diff --git a/src/resources/vue/Login.vue b/src/resources/vue/Login.vue
--- a/src/resources/vue/Login.vue
+++ b/src/resources/vue/Login.vue
@@ -35,7 +35,7 @@
@@ -43,8 +43,8 @@
diff --git a/src/resources/vue/Widgets/Menu.vue b/src/resources/vue/Widgets/Menu.vue
--- a/src/resources/vue/Widgets/Menu.vue
+++ b/src/resources/vue/Widgets/Menu.vue
@@ -4,7 +4,7 @@
@@ -22,16 +22,16 @@
- Signup
+ {{ $t('menu.signup') }}
- Cockpit
+ {{ $t('menu.cockpit') }}
-
+
-
+
+