39 lines
1.2 KiB
Vue
39 lines
1.2 KiB
Vue
|
|
import type { ContentNavigation } from '#build/components';
|
|
<script setup lang="ts">
|
|
const props = defineProps({
|
|
href: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
target: {
|
|
type: String,
|
|
default: undefined,
|
|
required: false
|
|
}
|
|
})
|
|
|
|
function sluggify(s: string): string {
|
|
return s
|
|
.split("/")
|
|
.map((segment) => segment.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/^\d\. */g, '').replace(/\s/g, "-").replace(/%/g, "-percent").replace(/\?/g, "-q").toLowerCase()) // slugify all segments
|
|
.filter(e => !!e)
|
|
.join("/") // always use / as sep
|
|
.replace(/\/$/, "")
|
|
}
|
|
|
|
const href = (props.href.includes('#') ? props.href.substring(0, props.href.indexOf('#')) : props.href).replace(/\..*$/, '');
|
|
const anchor = props.href.includes('#') ? props.href.substring(props.href.indexOf('#'), props.href.length) : '';
|
|
let content: any;
|
|
try {
|
|
content = await queryContent().where({ _path: new RegExp(sluggify(href) + '$', 'i') }).findOne();
|
|
} catch(e) {
|
|
|
|
}
|
|
</script>
|
|
|
|
<template >
|
|
<NuxtLink :href="(content?._path ?? href + anchor) ?? href" :target="target">
|
|
<slot />
|
|
</NuxtLink>
|
|
</template> |