From 6ab002986a386e5fefd99b8add19bd0bc579fb7b Mon Sep 17 00:00:00 2001 From: Philipp Zerelles Date: Tue, 27 Jul 2021 14:54:02 +0200 Subject: [PATCH] Added i18n routes to default template demonstrating alternate pages --- .../templates/default/i18n.config.js | 37 +++++++++++++++ .../templates/default/locales.js | 1 + .../default/src/lib/header/Header.svelte | 47 +++++++++++++++++-- .../templates/default/src/lib/i18n.ts | 26 ++++++++++ .../templates/default/svelte.config.js | 5 +- 5 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 packages/create-svelte/templates/default/i18n.config.js create mode 100644 packages/create-svelte/templates/default/locales.js create mode 100644 packages/create-svelte/templates/default/src/lib/i18n.ts diff --git a/packages/create-svelte/templates/default/i18n.config.js b/packages/create-svelte/templates/default/i18n.config.js new file mode 100644 index 000000000000..177f39f81c72 --- /dev/null +++ b/packages/create-svelte/templates/default/i18n.config.js @@ -0,0 +1,37 @@ +import locales from './locales.js'; + +export const defaultLocale = locales[0]; + +/** @typedef {{ + * content: string; + * dynamic: boolean; + * spread: boolean; + * }} Part */ + +/** + * Create localized routes prefixed with locale + * @param {Part[][]} segments + * @param {'page' | 'endpoint'} type + * @returns {Part[][][]} + */ +export function localizeRoutes(segments, type) { + if (type === 'endpoint') return [segments]; + return locales.map((locale) => + locale === defaultLocale + ? segments + : [ + [{ content: locale, dynamic: false, spread: false }], + ...segments.map((segment) => segment.map((part) => translate(part))) + ] + ); +} + +/** + * Translate part of a route segment + * @param {Part} part + * @returns {Part} + */ +function translate(part) { + if (part.content === 'about') return { ...part, content: 'ueber' }; + return part; +} diff --git a/packages/create-svelte/templates/default/locales.js b/packages/create-svelte/templates/default/locales.js new file mode 100644 index 000000000000..0c7c8f3ed840 --- /dev/null +++ b/packages/create-svelte/templates/default/locales.js @@ -0,0 +1 @@ +export default ['en', 'de']; diff --git a/packages/create-svelte/templates/default/src/lib/header/Header.svelte b/packages/create-svelte/templates/default/src/lib/header/Header.svelte index bab8050a0cb1..a8060c379fad 100644 --- a/packages/create-svelte/templates/default/src/lib/header/Header.svelte +++ b/packages/create-svelte/templates/default/src/lib/header/Header.svelte @@ -1,8 +1,21 @@ + + {#if defaultPath} + + {/if} + {#each Object.entries(alternatePaths) as [locale, path]} + + {/each} + +
@@ -15,9 +28,13 @@
+
@@ -36,7 +58,7 @@ } .corner { - width: 3em; + display: flex; height: 3em; } @@ -46,6 +68,23 @@ justify-content: center; width: 100%; height: 100%; + text-transform: uppercase; + } + + .corner nav a { + position: relative; + } + + .corner a.active::before { + --size: 6px; + content: ''; + width: 0; + height: 0; + position: absolute; + top: 0; + left: calc(50% - var(--size)); + border: var(--size) solid transparent; + border-top: var(--size) solid var(--accent-color); } .corner img { diff --git a/packages/create-svelte/templates/default/src/lib/i18n.ts b/packages/create-svelte/templates/default/src/lib/i18n.ts new file mode 100644 index 000000000000..37ce3b88bb62 --- /dev/null +++ b/packages/create-svelte/templates/default/src/lib/i18n.ts @@ -0,0 +1,26 @@ +import { derived } from 'svelte/store'; +import { page } from '$app/stores'; +import { alternates } from '$app/navigation'; + +import locales from '../../locales'; + +export const defaultLocale = locales[0]; + +export const locale = derived( + page, + (page) => page.path.match(/^\/([a-z]{2})(\/|$)/)?.[1] || defaultLocale +); + +export const localizedPaths = derived(page, (page) => (path: string): Record => + alternates(path)?.reduce((result, alt) => { + result[alt.match(/^\/([a-z]{2})(\/|$)/)?.[1] || defaultLocale] = alt; + return result; + }, {}) +); + +export const l = derived( + [localizedPaths, locale], + ([localizedPaths, locale]) => (path: string): string => localizedPaths(path)?.[locale] || path +); + +export { l as localize }; diff --git a/packages/create-svelte/templates/default/svelte.config.js b/packages/create-svelte/templates/default/svelte.config.js index 3315cb538d64..a84d610428d0 100644 --- a/packages/create-svelte/templates/default/svelte.config.js +++ b/packages/create-svelte/templates/default/svelte.config.js @@ -1,4 +1,5 @@ import preprocess from 'svelte-preprocess'; +import { localizeRoutes } from './i18n.config.js'; const adapter = process.env.ADAPTER; const options = JSON.parse(process.env.OPTIONS || '{}'); @@ -11,7 +12,9 @@ const config = { kit: { // hydrate the
element in src/app.html - target: '#svelte' + target: '#svelte', + + alternateRoutes: localizeRoutes } };