feat: replace Cusdis with own comment plugin
Drops the Cusdis embed (postCommentSlot in pageConfig) in favour of the new RustyCMS comment plugin. New Comments.svelte renders the thread, form, replies and inline edit/delete via /api/comments. Count-badge near the post date links to the accordion and uses /api/comments/:id/count. Accordion gets a `lazy` mode so the comment iframe / fetch happens only on first open (avoids the previous "empty on first render" issue with hidden details). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getPostBySlug, getPageConfigBySlug, getPageConfigs } from '$lib/cms';
|
||||
import { getPostBySlug } from '$lib/cms';
|
||||
import {
|
||||
resolveContentImages,
|
||||
ensureTransformedImage,
|
||||
@@ -135,16 +135,6 @@ export const load: PageServerLoad = async ({ params, locals, url, setHeaders })
|
||||
? `https://www.openstreetmap.org/search?query=${encodeURIComponent(eventLocation.text)}`
|
||||
: null;
|
||||
|
||||
const pageConfig =
|
||||
(await getPageConfigBySlug('page-config-default', { locale: 'de' })) ??
|
||||
(await getPageConfigs({ locale: 'de', per_page: 1 }))[0] ??
|
||||
null;
|
||||
const commentSlotRaw =
|
||||
(pageConfig as { postCommentSlot?: string } | null)?.postCommentSlot ?? '';
|
||||
const commentSlot = commentSlotRaw
|
||||
.replace(/\{\{PAGE_ID\}\}/g, slug)
|
||||
.replace(/\{\{PAGE_URL\}\}/g, url.href)
|
||||
.replace(/\{\{PAGE_TITLE\}\}/g, post.headline ?? post.linkName ?? slug);
|
||||
const showCommentSection = (post as { showCommentSection?: boolean }).showCommentSection !== false;
|
||||
|
||||
const jsonLd: Record<string, unknown>[] = [];
|
||||
@@ -263,7 +253,7 @@ export const load: PageServerLoad = async ({ params, locals, url, setHeaders })
|
||||
eventLocationText: eventLocation?.text ?? null,
|
||||
mapEmbedUrl,
|
||||
mapLinkUrl,
|
||||
commentSlot: showCommentSection ? commentSlot : '',
|
||||
commentPageId: showCommentSection ? slug : null,
|
||||
translations,
|
||||
seoTitle: post.seoTitle ?? postHeadline,
|
||||
seoDescription: postDescription,
|
||||
|
||||
@@ -5,21 +5,13 @@
|
||||
import EventBadges from '$lib/components/EventBadges.svelte';
|
||||
import EventMap from '$lib/components/EventMap.svelte';
|
||||
import Accordion from '$lib/components/Accordion.svelte';
|
||||
import CommentCountBadge from '$lib/components/CommentCountBadge.svelte';
|
||||
import Comments from '$lib/components/Comments.svelte';
|
||||
import RustyImage from '$lib/components/RustyImage.svelte';
|
||||
import { t, T } from '$lib/translations';
|
||||
import type { PageData } from './$types';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
function executeScripts(node: HTMLElement) {
|
||||
const scripts = node.querySelectorAll("script");
|
||||
scripts.forEach((old) => {
|
||||
const s = document.createElement("script");
|
||||
for (const { name, value } of old.attributes) s.setAttribute(name, value);
|
||||
s.text = old.textContent ?? "";
|
||||
old.replaceWith(s);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -34,7 +26,7 @@
|
||||
|
||||
<div class="md:flex gap-2 items-end">
|
||||
{#if data.rawPostImageUrl}
|
||||
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg">
|
||||
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg aspect-square">
|
||||
<RustyImage
|
||||
src={data.rawPostImageUrl}
|
||||
focal={data.postImageFocal}
|
||||
@@ -49,7 +41,7 @@
|
||||
/>
|
||||
</div>
|
||||
{:else if data.postImageUrl}
|
||||
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg">
|
||||
<div class="overflow-hidden inline-block my-4 border border-white self-start ring-1 ring-black/50 shadow-lg aspect-square">
|
||||
<img
|
||||
src={data.postImageUrl}
|
||||
alt=""
|
||||
@@ -62,9 +54,14 @@
|
||||
</div>
|
||||
{/if}
|
||||
<div class="mt-2 mb-4! md:mb-1 min-w-0 gap-2">
|
||||
{#if data.postDate}
|
||||
{#if data.postDate || data.commentPageId}
|
||||
<div class="flex flex-nowrap gap-2 items-center shrink-0 mb-2">
|
||||
<Tag label={data.postDate} variant="date" />
|
||||
{#if data.postDate}
|
||||
<Tag label={data.postDate} variant="date" />
|
||||
{/if}
|
||||
{#if data.commentPageId}
|
||||
<CommentCountBadge pageId={data.commentPageId} targetId="comments-section" />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex flex-nowrap gap-2 items-center shrink-0 p-1 pb-4 -ml-1 overflow-x-auto overflow-y-hidden">
|
||||
@@ -148,10 +145,10 @@
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if data.commentSlot}
|
||||
<Accordion label={t(data.translations, T.post_comments)} class="mt-6">
|
||||
<div class="p-8 border border-zinc-200 rounded-lg" use:executeScripts>
|
||||
{@html data.commentSlot}
|
||||
{#if data.commentPageId}
|
||||
<Accordion id="comments-section" label={t(data.translations, T.post_comments)} lazy class="mt-6">
|
||||
<div class="p-8 border border-zinc-200 rounded-lg">
|
||||
<Comments pageId={data.commentPageId} />
|
||||
</div>
|
||||
</Accordion>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user