webapps/packages/layers/content/composables/useContentInjected.ts
Dominik Milacher 73083ded58
Some checks failed
Build and deploy updated apps / Build & deploy (push) Failing after 1m7s
Overhaul content management
2025-10-22 19:31:38 +02:00

99 lines
3.2 KiB
TypeScript

import {type JsonValue} from '../utils/content-canonical'
import {buildContent, expandContent} from '../utils/content-reduced'
import {useContentPreference} from "./useContentPreference"
import config from 'virtual:content/content.config'
import shortcuts from 'virtual:content/shortcuts'
export function useContentInjected(slug?: string, global?: JsonValue, local?: JsonValue) {
if (!slug) {
throw new Error('useContentInjected called without arguments, there might be a problem with the Vite plugin')
}
const route = useRoute()
const {preferredLocale, preferredVariant} = useContentPreference()
const lo = computed(() => (route.params.locale as string | undefined) ?? preferredLocale.value)
const va = computed(() => (route.params.variant as string | undefined) ?? preferredVariant.value)
const g = computed(() => getContent('content.global', lo.value, va.value, global, local))
const l = computed(() => getContent(slug, lo.value, va.value, global, local))
function path(page?: string, options?: {locale?: string, variant?: string}) {
return computed(() => {
let result: string // don't touch page, this will mess with reactivity
if (page === undefined) {
result = route.fullPath
function replace(what: string, value: string) { // replaces only the first occurrence
const expression = new RegExp(`/${what}(?=[/?#]|$)`)
return result.replace(expression, `/${value}`)
}
result = lo.value ? replace(lo.value, '[locale]') : result
result = va.value ? replace(va.value, '[variant]') : result
} else {
const index = page.search(/[?#]/)
const path = index === -1 ? page : page.slice(0, index)
if (path in shortcuts) {
result = shortcuts[path] + page.slice(index === -1 ? page.length : index)
} else {
result = page
}
}
if (!result.startsWith('/')) {
result = '/' + result
}
result = lo.value ? result.replace('[locale]', options?.locale ?? lo.value ?? '') : result
result = va.value ? result.replace('[variant]', options?.variant ?? va.value ?? '') : result
return result
})
}
return {
locale: lo,
variant: va,
global: g,
local: l,
g: g,
l: l,
path: path,
p: path
}
}
const cache = new Map<string, JsonValue | undefined>()
function getContent(slug: string, locale?: string, variant?: string, global?: JsonValue, local?: JsonValue): JsonValue | undefined {
const key = `${slug}${locale}${variant}`
const hit = cache.get(key)
if (hit !== undefined) {
return hit
}
const locales: string[] = config.locale?.list.map(l => l.code) ?? []
const variants: string[] = config.variant?.list.map(v => v.code) ?? []
const content = slug === 'content.global' ? global : local
let [reduced, expand] =
content === undefined ? [undefined, false] : buildContent(locale, locales, variant, variants, content)
if (reduced && expand) {
if (slug === 'content.global') {
reduced = expandContent(reduced, [reduced])
} else {
const g = getContent('content.global', locale, variant, global, local)
reduced = expandContent(reduced, g ? [reduced, g] : [reduced])
}
}
cache.set(key, reduced)
return reduced
}