🎨 Adds locale to all URLs
This commit is contained in:
parent
3c1177a4d7
commit
e2cfc20341
|
@ -1,4 +1,4 @@
|
|||
import { getTranslatedTitles } from '@/helper/content'
|
||||
import { getTranslatedTitles } from '@/i18n/helper'
|
||||
import i18n from './i18n'
|
||||
|
||||
export default [
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { DEFAULT_LOCALE } from '@/config'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/helper/content'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/i18n/helper'
|
||||
import i18n from './i18n'
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/' + i18n[DEFAULT_LOCALE].about.url,
|
||||
path: i18n[DEFAULT_LOCALE].about.url,
|
||||
alias: getTranslatedAliases(i18n, 'about'),
|
||||
name: 'about',
|
||||
component: () => import('./components/index' /* webpackChunkName: "about" */),
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
<script>
|
||||
import '@/assets/icons/european-stars'
|
||||
import { GA_COOKIE_NAME } from '@/config/analytics'
|
||||
import { LOCALES } from '@/config'
|
||||
import { SUPPORTED_LOCALES } from '@/config'
|
||||
import { setCookie, getCookie } from '@/helper/cookies'
|
||||
import { getTranslatedUrl } from '@/i18n/helper'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
|
@ -41,7 +42,7 @@
|
|||
showConsentLayer: getCookie(GA_COOKIE_NAME) === null,
|
||||
euromatLogo: require('@/assets/svg/euromat-logo.svg'),
|
||||
logoSize: 220,
|
||||
languages: LOCALES.map(([locale, language]) => ({
|
||||
languages: SUPPORTED_LOCALES.map(([locale, language]) => ({
|
||||
icon: require(`@/assets/svg/flag-${locale}.svg`),
|
||||
locale,
|
||||
language
|
||||
|
@ -50,26 +51,23 @@
|
|||
},
|
||||
|
||||
computed: {
|
||||
isGermanLocale () {
|
||||
return this.$i18n.locale === 'de'
|
||||
},
|
||||
topMenu () {
|
||||
return [
|
||||
{
|
||||
label: this.$t('meta.topMenu.index'),
|
||||
route: { path: '/' }
|
||||
route: { path: `/${this.$i18n.locale}/` }
|
||||
},
|
||||
{
|
||||
label: this.$t('meta.topMenu.faq'),
|
||||
route: { path: '/faq' }
|
||||
route: { path: getTranslatedUrl('faq') }
|
||||
},
|
||||
{
|
||||
label: this.$t('meta.topMenu.about'),
|
||||
route: { path: this.isGermanLocale ? '/uber-uns' : '/about-us' }
|
||||
route: { path: getTranslatedUrl('about') }
|
||||
},
|
||||
{
|
||||
label: this.$t('meta.topMenu.press'),
|
||||
route: { path: this.isGermanLocale ? '/presse' : '/press' }
|
||||
route: { path: getTranslatedUrl('press') }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -77,11 +75,11 @@
|
|||
return [
|
||||
{
|
||||
label: this.$t('meta.footerMenu.imprint'),
|
||||
route: { path: this.isGermanLocale ? '/impressum' : '/imprint' }
|
||||
route: { path: getTranslatedUrl('imprint') }
|
||||
},
|
||||
{
|
||||
label: this.$t('meta.footerMenu.privacy'),
|
||||
route: { path: this.isGermanLocale ? '/datenschutz' : '/privacy' }
|
||||
route: { path: getTranslatedUrl('privacy') }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -10,8 +10,8 @@ function hasAnswers (to, from, next) {
|
|||
|
||||
export default [
|
||||
{
|
||||
path: '/thesen',
|
||||
alias: '/theses',
|
||||
path: 'thesen',
|
||||
alias: 'theses',
|
||||
component: () => import('./components/index' /* webpackChunkName: "euromat" */),
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { getTranslatedTitles } from '@/helper/content'
|
||||
import { getTranslatedTitles } from '@/i18n/helper'
|
||||
import i18n from './i18n'
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/faq',
|
||||
// alias: getTranslatedAliases(i18n, 'faq'),
|
||||
path: 'faq',
|
||||
// alias: getTranslatedAliases('faq'),
|
||||
name: 'faq',
|
||||
component: () => import('./components/index' /* webpackChunkName: "faq" */),
|
||||
meta: {
|
||||
|
|
|
@ -2,8 +2,8 @@ import i18n from './i18n'
|
|||
|
||||
export default [
|
||||
{
|
||||
path: '/impressum',
|
||||
alias: '/imprint',
|
||||
path: 'impressum',
|
||||
alias: 'imprint',
|
||||
name: 'imprint',
|
||||
component: () => import('./components/index' /* webpackChunkName: "misc" */),
|
||||
meta: {
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
computed: {
|
||||
thesesPath () {
|
||||
return this.$i18n.locale === 'de'
|
||||
? '/thesen'
|
||||
: '/theses'
|
||||
? `/${this.$i18n.locale}/thesen`
|
||||
: `/${this.$i18n.locale}/theses`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { DEFAULT_LOCALE } from '@/config'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/helper/content'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/i18n/helper'
|
||||
import i18n from './i18n'
|
||||
|
||||
export default [
|
||||
{
|
||||
path: `/${i18n[DEFAULT_LOCALE].party.url}/:token`,
|
||||
path: `${i18n[DEFAULT_LOCALE].party.url}/:token`,
|
||||
alias: getTranslatedAliases(i18n, 'party').map(alias => `${alias}/:token`),
|
||||
name: 'party',
|
||||
component: () => import('./components/index' /* webpackChunkName: "party" */),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { DEFAULT_LOCALE } from '@/config'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/helper/content'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/i18n/helper'
|
||||
import i18n from './i18n'
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/' + i18n[DEFAULT_LOCALE].press.url,
|
||||
path: i18n[DEFAULT_LOCALE].press.url,
|
||||
alias: getTranslatedAliases(i18n, 'press'),
|
||||
name: 'press',
|
||||
component: () => import('./components/index' /* webpackChunkName: "press" */),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { DEFAULT_LOCALE } from '@/config'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/helper/content'
|
||||
import { getTranslatedTitles, getTranslatedAliases } from '@/i18n/helper'
|
||||
import i18n from './i18n'
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/' + i18n[DEFAULT_LOCALE].privacy.url,
|
||||
path: i18n[DEFAULT_LOCALE].privacy.url,
|
||||
alias: getTranslatedAliases(i18n, 'privacy'),
|
||||
name: 'privacy',
|
||||
component: () => import('./components/index' /* webpackChunkName: "misc" */),
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { setCurrentLocale } from '@/i18n/helper'
|
||||
export default {
|
||||
name: 'AppMenu',
|
||||
|
||||
|
@ -76,10 +77,8 @@
|
|||
this.languageMenuSelected = false
|
||||
},
|
||||
changeLanguage (locale) {
|
||||
this.$i18n.locale = locale
|
||||
if (this.$browser.supports('localStorage')) {
|
||||
localStorage.setItem('euromat-locale', locale)
|
||||
}
|
||||
setCurrentLocale(locale)
|
||||
// this.$i18n.locale = locale
|
||||
this.hideLanguageSelection()
|
||||
}
|
||||
}
|
||||
|
|
9
src/components/base-locale-router.vue
Normal file
9
src/components/base-locale-router.vue
Normal file
|
@ -0,0 +1,9 @@
|
|||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'BaseLocaleRouter'
|
||||
}
|
||||
</script>
|
|
@ -4,7 +4,7 @@ export const LOCALE_FRENCH = 'fr'
|
|||
export const LOCALE_POLISH = 'pl'
|
||||
export const DEFAULT_LOCALE = LOCALE_ENGLISH
|
||||
|
||||
export const LOCALES = [
|
||||
export const SUPPORTED_LOCALES = [
|
||||
[LOCALE_ENGLISH, 'English'],
|
||||
[LOCALE_GERMAN, 'Deutsch'],
|
||||
[LOCALE_FRENCH, 'Français'],
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { DEFAULT_LOCALE } from '@/config'
|
||||
|
||||
export function loadContent (prefix, requireContent) {
|
||||
if (!prefix || !requireContent) {
|
||||
throw new Error('loadContent: prefix and requireContent are both required!')
|
||||
|
@ -13,26 +11,3 @@ export function loadContent (prefix, requireContent) {
|
|||
return accumulator
|
||||
}, {})
|
||||
}
|
||||
|
||||
export function getTranslatedTitles (data, section) {
|
||||
return {
|
||||
title: Object.keys(data).reduce((acc, cur) => {
|
||||
const title = data[cur][section].title
|
||||
if (!title) {
|
||||
console.warning(`Property "title" doesn't exist on i18n.de.${section}`)
|
||||
}
|
||||
|
||||
acc[cur] = title
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
}
|
||||
|
||||
export function getTranslatedAliases (data, section) {
|
||||
return [...new Set(
|
||||
Object.keys(data)
|
||||
.filter(lang => lang !== DEFAULT_LOCALE)
|
||||
.map(lang => '/' + data[lang][section].url)
|
||||
.filter(Boolean)
|
||||
)]
|
||||
}
|
||||
|
|
57
src/i18n/helper.js
Normal file
57
src/i18n/helper.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '@/config'
|
||||
import i18n from './index'
|
||||
|
||||
export const isLangSupported = lang =>
|
||||
SUPPORTED_LOCALES.some(([locale]) => locale === lang)
|
||||
|
||||
export const getCurrentLocale = () => i18n.locale
|
||||
export const setCurrentLocale = (locale) => {
|
||||
i18n.locale = locale
|
||||
if (document && document.documentElement) {
|
||||
document.documentElement.setAttribute('lang', locale)
|
||||
}
|
||||
}
|
||||
|
||||
export function getUserLanguage () {
|
||||
const lang = (
|
||||
window.navigator.language ||
|
||||
window.navigator.userLanguage ||
|
||||
DEFAULT_LOCALE
|
||||
)
|
||||
return lang.split('-')[0]
|
||||
}
|
||||
|
||||
export function getUserSupportedLanguage () {
|
||||
const language = getUserLanguage()
|
||||
return isLangSupported(language)
|
||||
? language
|
||||
: DEFAULT_LOCALE
|
||||
}
|
||||
|
||||
export function getTranslatedTitles (data, section) {
|
||||
return {
|
||||
title: Object.keys(data).reduce((acc, cur) => {
|
||||
const title = data[cur][section].title
|
||||
if (!title) {
|
||||
console.warning(`Property "title" doesn't exist on i18n.de.${section}`)
|
||||
}
|
||||
|
||||
acc[cur] = title
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
}
|
||||
|
||||
export function getTranslatedAliases (data, section) {
|
||||
return [...new Set(
|
||||
Object.keys(data)
|
||||
.filter(lang => lang !== DEFAULT_LOCALE)
|
||||
.map(lang => '/' + data[lang][section].url)
|
||||
.filter(Boolean)
|
||||
)]
|
||||
}
|
||||
|
||||
export function getTranslatedUrl (section) {
|
||||
const url = i18n.messages[getCurrentLocale()][section].url
|
||||
return `/${i18n.locale}/${url}`
|
||||
}
|
|
@ -12,7 +12,7 @@ import { i18n as imprint } from '@/app/imprint'
|
|||
import { i18n as privacy } from '@/app/privacy'
|
||||
import { i18n as meta } from '@/data'
|
||||
|
||||
import { DEFAULT_LOCALE, LOCALES } from '@/config'
|
||||
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '@/config'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
|
@ -30,11 +30,13 @@ function getLanguage (locale) {
|
|||
}), {})
|
||||
}
|
||||
|
||||
export default new VueI18n({
|
||||
locale: localStorage.getItem('euromat-locale') || DEFAULT_LOCALE,
|
||||
const i18n = new VueI18n({
|
||||
locale: DEFAULT_LOCALE,
|
||||
fallbackLocale: DEFAULT_LOCALE,
|
||||
messages: LOCALES.reduce((acc, [locale]) => ({
|
||||
messages: SUPPORTED_LOCALES.reduce((acc, [locale]) => ({
|
||||
...acc,
|
||||
[locale]: getLanguage(locale)
|
||||
}), {})
|
||||
})
|
||||
|
||||
export default i18n
|
||||
|
|
|
@ -25,8 +25,8 @@ Vue.use(VueAnalytics, {
|
|||
})
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
i18n,
|
||||
router,
|
||||
data: {
|
||||
backupStorage: {
|
||||
answers: undefined,
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import { DEFAULT_LOCALE } from '@/config'
|
||||
|
||||
export default function getPageTitle (i18n = {}) {
|
||||
const locale = localStorage.getItem('euromat-locale') || DEFAULT_LOCALE
|
||||
const title = window.document.title.split('—')[0].trim()
|
||||
return `${title} — ${i18n[locale]}`
|
||||
}
|
20
src/router/helper.js
Normal file
20
src/router/helper.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import * as i18n from '@/i18n/helper'
|
||||
|
||||
export function getPageTitle (data = {}) {
|
||||
const locale = i18n.getUserSupportedLanguage()
|
||||
const title = window.document.title.split('—')[0].trim()
|
||||
return locale && data.title && data.title[locale]
|
||||
? `${title} — ${data.title[locale]}`
|
||||
: title
|
||||
}
|
||||
|
||||
export function beforeEnter (to, from, next) {
|
||||
const lang = to.params.locale
|
||||
if (!i18n.isLangSupported(lang)) {
|
||||
return next(i18n.getUserLanguage())
|
||||
}
|
||||
|
||||
i18n.setCurrentLocale(lang)
|
||||
|
||||
return next()
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
|
||||
import getPageTitle from './getPageTitle'
|
||||
import * as i18n from '@/i18n/helper'
|
||||
import BaseLocaleRouter from '@/components/base-locale-router'
|
||||
import { getPageTitle, beforeEnter } from '@/router/helper'
|
||||
|
||||
import { routes as intro } from '@/app/intro'
|
||||
import { routes as euromat } from '@/app/euromat'
|
||||
import { routes as party } from '@/app/party'
|
||||
|
@ -17,20 +20,33 @@ Vue.use(Router)
|
|||
const router = new Router({
|
||||
mode: 'history',
|
||||
routes: [
|
||||
...intro,
|
||||
...euromat,
|
||||
...party,
|
||||
...about,
|
||||
...faq,
|
||||
...press,
|
||||
...imprint,
|
||||
...privacy,
|
||||
...fourzerofour
|
||||
{
|
||||
path: '/:locale',
|
||||
component: BaseLocaleRouter,
|
||||
beforeEnter,
|
||||
children: [
|
||||
...intro,
|
||||
...euromat,
|
||||
...party,
|
||||
...about,
|
||||
...faq,
|
||||
...press,
|
||||
...imprint,
|
||||
...privacy,
|
||||
...fourzerofour
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
redirect (to) {
|
||||
return i18n.getUserSupportedLanguage()
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.meta.title && to.meta.title.de && to.meta.title.en) {
|
||||
if (to.meta.title) {
|
||||
window.document.title = getPageTitle(to.meta.title)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue