🎨 Adds locale to all URLs

This commit is contained in:
Moritz Kröger 2019-04-12 22:29:36 +02:00
parent 3c1177a4d7
commit e2cfc20341
20 changed files with 151 additions and 82 deletions

View file

@ -1,4 +1,4 @@
import { getTranslatedTitles } from '@/helper/content'
import { getTranslatedTitles } from '@/i18n/helper'
import i18n from './i18n'
export default [

View file

@ -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" */),

View file

@ -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') }
}
]
},

View file

@ -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: [
{

View file

@ -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: {

View file

@ -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: {

View file

@ -27,8 +27,8 @@
computed: {
thesesPath () {
return this.$i18n.locale === 'de'
? '/thesen'
: '/theses'
? `/${this.$i18n.locale}/thesen`
: `/${this.$i18n.locale}/theses`
}
}
}

View file

@ -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" */),

View file

@ -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" */),

View file

@ -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" */),

View file

@ -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()
}
}

View file

@ -0,0 +1,9 @@
<template>
<router-view />
</template>
<script>
export default {
name: 'BaseLocaleRouter'
}
</script>

View file

@ -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'],

View file

@ -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
View 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}`
}

View file

@ -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

View file

@ -25,8 +25,8 @@ Vue.use(VueAnalytics, {
})
new Vue({
router,
i18n,
router,
data: {
backupStorage: {
answers: undefined,

View file

@ -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
View 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()
}

View file

@ -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)
}