import { computed, createTextVNode, defineComponent, h, type VNode } from "vue"; import useHead from "@/useHead.ts"; import useAsyncState from "@/useAsyncState.ts"; import getDjAPI from "@/api.ts"; import getDomParser from "@/domParse.ts"; import { addCSS, css } from "../util.ts"; const style = css` .byline { font-style: italic; color: gray; } h1 { color: var(--dj-palette1); } p { margin-bottom: 30px; } `; export default defineComponent({ name: "DjBlogEntry", props: { slug: { type: String, required: true, }, }, async setup(props) { addCSS('DjBlogEntry', style); const parseDom = getDomParser(); const blogpostContent = useAsyncState( `dj-blog-article-content-${ props.slug }`, async ({ hostUrl }) => { const blogpostResponse = await fetch(`${hostUrl}/blog/content/${ props.slug }.html`); const result = await blogpostResponse.text(); return result; }, ); const blogpostsMetadata = useAsyncState('article-metadata', ({ hostUrl }) => getDjAPI(hostUrl, '/blog-entries')); const blogpostMetadata = computed(() => blogpostsMetadata.result.value?.find(_ => _.slug === props.slug)); useHead({ title: () => blogpostMetadata.value?.title ?? '', metatags: () => blogpostMetadata.value ? [ { name: 'title', content: blogpostMetadata.value.title }, { name: 'author', content: 'Daniel Ledda' }, ] : [], }); function transformPostNode(node: Node): VNode | string { if (node.nodeType === node.ELEMENT_NODE) { const el = node as Element; const attrs: Record = {}; const children = [...node.childNodes].map((_) => transformPostNode(_)); for (let i = 0; i < el.attributes.length; i++) { const item = el.attributes.item(i); if (item) { attrs[item.name] = item.value; } } return h((node as Element).tagName, attrs, children); } else { return createTextVNode(node.textContent ?? ""); } } function PostContentTransformed() { if (blogpostContent.result.value) { const dom = parseDom(blogpostContent.result.value); return h("div", {}, [...dom.children].map((_) => transformPostNode(_))); } return
Blog post loading...
; } await Promise.allSettled([ blogpostContent.done, blogpostsMetadata.done ]); return () => <> { blogpostMetadata.value ? <>

{ blogpostMetadata.value.title }

by Daniel Ledda, first published { new Date(blogpostMetadata.value.createdAt).toLocaleDateString() }
: "Sorry, this blog post doesn't seem to exist." } ; } });