diff --git a/package.json b/package.json index d0d5903..b7f4b8c 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,11 @@ "@inlang/paraglide-js": "1.1.0", "@inlang/paraglide-js-adapter-vite": "^1.2.0", "@sveltejs/adapter-static": "^3.0.1", - "@sveltejs/kit": "^2.0.7", + "@sveltejs/kit": "^2.0.8", "@sveltejs/vite-plugin-svelte": "^3.0.1", "@types/eslint": "8.56.0", - "@typescript-eslint/eslint-plugin": "^6.18.0", - "@typescript-eslint/parser": "^6.18.0", + "@typescript-eslint/eslint-plugin": "^6.18.1", + "@typescript-eslint/parser": "^6.18.1", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.35.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e80e5a..f1d38d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,10 +13,10 @@ devDependencies: version: 1.2.0(@sinclair/typebox@0.31.28) '@sveltejs/adapter-static': specifier: ^3.0.1 - version: 3.0.1(@sveltejs/kit@2.0.7) + version: 3.0.1(@sveltejs/kit@2.0.8) '@sveltejs/kit': - specifier: ^2.0.7 - version: 2.0.7(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@5.0.0-next.29)(vite@5.0.11) + specifier: ^2.0.8 + version: 2.0.8(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@5.0.0-next.29)(vite@5.0.11) '@sveltejs/vite-plugin-svelte': specifier: ^3.0.1 version: 3.0.1(svelte@5.0.0-next.29)(vite@5.0.11) @@ -24,11 +24,11 @@ devDependencies: specifier: 8.56.0 version: 8.56.0 '@typescript-eslint/eslint-plugin': - specifier: ^6.18.0 - version: 6.18.0(@typescript-eslint/parser@6.18.0)(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.18.1 + version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.18.0 - version: 6.18.0(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.18.1 + version: 6.18.1(eslint@8.56.0)(typescript@5.3.3) eslint: specifier: ^8.56.0 version: 8.56.0 @@ -910,16 +910,16 @@ packages: resolution: {integrity: sha512-/s55Jujywdw/Jpan+vsy6JZs1z2ZTGxTmbZTPiuSL2wz9mfzA2gN1zzaqmvfi4pq+uOt7Du85fkiwv5ymW84aQ==} dev: true - /@sveltejs/adapter-static@3.0.1(@sveltejs/kit@2.0.7): + /@sveltejs/adapter-static@3.0.1(@sveltejs/kit@2.0.8): resolution: {integrity: sha512-6lMvf7xYEJ+oGeR5L8DFJJrowkefTK6ZgA4JiMqoClMkKq0s6yvsd3FZfCFvX1fQ0tpCD7fkuRVHsnUVgsHyNg==} peerDependencies: '@sveltejs/kit': ^2.0.0 dependencies: - '@sveltejs/kit': 2.0.7(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@5.0.0-next.29)(vite@5.0.11) + '@sveltejs/kit': 2.0.8(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@5.0.0-next.29)(vite@5.0.11) dev: true - /@sveltejs/kit@2.0.7(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@5.0.0-next.29)(vite@5.0.11): - resolution: {integrity: sha512-qLoPLqdyMKASxAMFuMrv86l81YKhdioXLsa87+QFv2Rmh0GroFXfSIJMpxI4bHfVt8oXRa71G0/lXhJ/2wTPxQ==} + /@sveltejs/kit@2.0.8(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@5.0.0-next.29)(vite@5.0.11): + resolution: {integrity: sha512-44F3uE5NLwYoqDnfmX5s3cZf2SssyHpUh9vokJ3YKzf7N7nDiPZPE3sdSelLc6RT7DUr7X4HKAu72wKpw2eonw==} engines: {node: '>=18.13'} hasBin: true requiresBuild: true @@ -933,6 +933,7 @@ packages: cookie: 0.6.0 devalue: 4.3.2 esm-env: 1.0.0 + import-meta-resolve: 4.0.0 kleur: 4.1.5 magic-string: 0.30.5 mrmime: 2.0.0 @@ -1047,8 +1048,8 @@ packages: resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} dev: true - /@typescript-eslint/eslint-plugin@6.18.0(@typescript-eslint/parser@6.18.0)(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-3lqEvQUdCozi6d1mddWqd+kf8KxmGq2Plzx36BlkjuQe3rSTm/O98cLf0A4uDO+a5N1KD2SeEEl6fW97YHY+6w==} + /@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -1059,11 +1060,11 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.18.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 6.18.0 - '@typescript-eslint/type-utils': 6.18.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.18.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.18.0 + '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/type-utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.4 eslint: 8.56.0 graphemer: 1.4.0 @@ -1076,8 +1077,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.18.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-v6uR68SFvqhNQT41frCMCQpsP+5vySy6IdgjlzUWoo7ALCnpaWYcz/Ij2k4L8cEsL0wkvOviCMpjmtRtHNOKzA==} + /@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1086,10 +1087,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.18.0 - '@typescript-eslint/types': 6.18.0 - '@typescript-eslint/typescript-estree': 6.18.0(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.18.0 + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.4 eslint: 8.56.0 typescript: 5.3.3 @@ -1097,16 +1098,16 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@6.18.0: - resolution: {integrity: sha512-o/UoDT2NgOJ2VfHpfr+KBY2ErWvCySNUIX/X7O9g8Zzt/tXdpfEU43qbNk8LVuWUT2E0ptzTWXh79i74PP0twA==} + /@typescript-eslint/scope-manager@6.18.1: + resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.18.0 - '@typescript-eslint/visitor-keys': 6.18.0 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 dev: true - /@typescript-eslint/type-utils@6.18.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-ZeMtrXnGmTcHciJN1+u2CigWEEXgy1ufoxtWcHORt5kGvpjjIlK9MUhzHm4RM8iVy6dqSaZA/6PVkX6+r+ChjQ==} + /@typescript-eslint/type-utils@6.18.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1115,8 +1116,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.18.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.18.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4 eslint: 8.56.0 ts-api-utils: 1.0.3(typescript@5.3.3) @@ -1125,13 +1126,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types@6.18.0: - resolution: {integrity: sha512-/RFVIccwkwSdW/1zeMx3hADShWbgBxBnV/qSrex6607isYjj05t36P6LyONgqdUrNLl5TYU8NIKdHUYpFvExkA==} + /@typescript-eslint/types@6.18.1: + resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.18.0(typescript@5.3.3): - resolution: {integrity: sha512-klNvl+Ql4NsBNGB4W9TZ2Od03lm7aGvTbs0wYaFYsplVPhr+oeXjlPZCDI4U9jgJIDK38W1FKhacCFzCC+nbIg==} + /@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3): + resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -1139,8 +1140,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.18.0 - '@typescript-eslint/visitor-keys': 6.18.0 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -1152,8 +1153,8 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@6.18.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-wiKKCbUeDPGaYEYQh1S580dGxJ/V9HI7K5sbGAVklyf+o5g3O+adnS4UNJajplF4e7z2q0uVBaTdT/yLb4XAVA==} + /@typescript-eslint/utils@6.18.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1161,9 +1162,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 6.18.0 - '@typescript-eslint/types': 6.18.0 - '@typescript-eslint/typescript-estree': 6.18.0(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) eslint: 8.56.0 semver: 7.5.4 transitivePeerDependencies: @@ -1171,11 +1172,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@6.18.0: - resolution: {integrity: sha512-1wetAlSZpewRDb2h9p/Q8kRjdGuqdTAQbkJIOUMLug2LBLG+QOjiWoSj6/3B/hA9/tVTFFdtiKvAYoYnSRW/RA==} + /@typescript-eslint/visitor-keys@6.18.1: + resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.18.0 + '@typescript-eslint/types': 6.18.1 eslint-visitor-keys: 3.4.3 dev: true @@ -1912,6 +1913,10 @@ packages: resolve-from: 4.0.0 dev: true + /import-meta-resolve@4.0.0: + resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} + dev: true + /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} diff --git a/src/lib/i18n/handle.server.ts b/src/lib/i18n/handle.server.ts index 215788d..40991d4 100644 --- a/src/lib/i18n/handle.server.ts +++ b/src/lib/i18n/handle.server.ts @@ -5,9 +5,10 @@ import { link } from './link'; /** * Handle hook for: - * - setting SSR lang - * - transforming html lang attribute placeholder - * - rewriting unlocalized SSR redirects lang segment in location + * + * - Setting SSR lang. + * - Transforming html lang attribute placeholder. + * - Rewriting unlocalized SSR redirects lang segment in location. */ const handle = (async ({ event, resolve }) => { event.locals.lang = getEventLang(event); @@ -15,7 +16,7 @@ const handle = (async ({ event, resolve }) => { const response = await resolve(event, { transformPageChunk(input) { return input.html.replace('%lang%', event.locals.lang); - } + }, }); if (!isRedirect(response)) { return response; diff --git a/src/lib/i18n/link.ts b/src/lib/i18n/link.ts index 6827df6..bdece7b 100644 --- a/src/lib/i18n/link.ts +++ b/src/lib/i18n/link.ts @@ -4,9 +4,11 @@ import { sourceLanguageTag, type AvailableLanguageTag, } from '$translations/runtime'; -import type { HTMLAnchorAttributes } from 'svelte/elements'; -export function delang(location: L) { +/** + * Remove an app-oriented href's lang param. + */ +export function removeLang(location: L) { const [_, maybeLang, ...rest] = location.split('/'); if (availableLanguageTags.includes(maybeLang as AvailableLanguageTag)) { return `/${rest.join('/')}`; @@ -14,25 +16,58 @@ export function delang(location: L) { return location; } -export function link(location: L, lang: AvailableLanguageTag = languageTag()) { - const tail = delang(location); +/** + * Apply a lang param to an app-oriented href. + * + * **Attention**: If a lang param is included in the passed location string, it will be replaced. + */ +export function link( + /** + * Route location agnostic of lang segment. + */ + location: L, + /** + * Custom lang to apply when wishing to target a lang different than the current one. + */ + lang: AvailableLanguageTag = languageTag() +) { + const tail = removeLang(location); if (lang === sourceLanguageTag) { return tail; } return `/${lang}${location}`; } -export function linkAttributes

( - path: P, - { - lang = languageTag(), - }: { - lang?: AvailableLanguageTag; - } = {} -) { - const href = link(path, lang); - return { - href, - hreflang: lang, - } satisfies Partial; -} +/** + * Compose a set of attributes for a given link and language. + */ +// export function linkAttributes

( +// path: P, +// { +// lang = languageTag(), +// }: { +// lang?: AvailableLanguageTag; +// } = {} +// ) { +// const href = link(path, lang); +// return { +// href, +// hreflang: lang, +// } satisfies Partial; +// } + +/** + * ``` + * + * + * + * This is a link + * + * ``` + */ +// export function loadableLink() { +// return { +// attributes, +// spinner +// } +// } diff --git a/src/routes/[[lang=lang]]/+layout.svelte b/src/routes/[[lang=lang]]/+layout.svelte index 1a2a3d8..44171e9 100644 --- a/src/routes/[[lang=lang]]/+layout.svelte +++ b/src/routes/[[lang=lang]]/+layout.svelte @@ -1,25 +1,38 @@ {#each availableLanguageTags as lang} - + {/each}

+
{languageTag()} diff --git a/src/routes/[[lang=lang]]/+layout.ts b/src/routes/[[lang=lang]]/+layout.ts new file mode 100644 index 0000000..28627ab --- /dev/null +++ b/src/routes/[[lang=lang]]/+layout.ts @@ -0,0 +1,8 @@ +import { getEventLang } from '$lib/i18n/event'; + +export const load = async (event) => { + const lang = getEventLang(event); + return { + lang, + }; +}; diff --git a/static/admin/config.yml b/static/admin/config.yml index 79b3e38..d6a301d 100644 --- a/static/admin/config.yml +++ b/static/admin/config.yml @@ -2,3 +2,25 @@ backend: name: github repo: CUPUM/site branch: main + +publish_mode: editorial_workflow + +media_folder: 'static/media' +public_folder: '/media' + +i18n: + structure: multiple_folders + locales: [fr, en] + default_locale: fr + +collections: + - name: projects + label: Projects + folder: 'projects' + create: true + i18n: true + fields: + - { label: 'Title', name: 'title', widget: 'string', i18n: true } + - { label: 'Publish Date', name: 'date', widget: 'datetime', i18n: true } + - { label: 'Featured Image', name: 'thumbnail', widget: 'image', i18n: true } + - { label: 'Body', name: 'body', widget: 'markdown', i18n: true }