Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
177 lines
3.5 KiB
Plaintext
177 lines
3.5 KiB
Plaintext
---
|
|
/**
|
|
* Individual post page with PortableText rendering
|
|
*
|
|
* This demonstrates the embeds plugin auto-registering components
|
|
* for YouTube, Vimeo, etc. with the PortableText renderer.
|
|
*/
|
|
import { getEmDashEntry, decodeSlug } from "emdash";
|
|
import { PortableText } from "emdash/ui";
|
|
import { embedComponents } from "@emdash-cms/plugin-embeds/astro";
|
|
|
|
const slug = decodeSlug(Astro.params.slug);
|
|
|
|
const { entry: post } = slug
|
|
? await getEmDashEntry("posts", slug)
|
|
: { entry: null };
|
|
|
|
if (!post) {
|
|
return Astro.redirect("/404");
|
|
}
|
|
|
|
const title = post.data.title;
|
|
const content = post.data.content;
|
|
const metaDescription = post.data.excerpt;
|
|
---
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width" />
|
|
<title>{title || "Post"} - EmDash Plugins Demo</title>
|
|
{metaDescription && <meta name="description" content={metaDescription} />}
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
body {
|
|
font-family:
|
|
system-ui,
|
|
-apple-system,
|
|
sans-serif;
|
|
line-height: 1.6;
|
|
color: #1a1a1a;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 2rem;
|
|
}
|
|
h1 {
|
|
font-size: 2rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.meta {
|
|
font-size: 0.875rem;
|
|
color: #6b7280;
|
|
margin-bottom: 2rem;
|
|
}
|
|
.back {
|
|
display: inline-block;
|
|
margin-bottom: 1rem;
|
|
color: #2563eb;
|
|
}
|
|
|
|
/* Content styles */
|
|
.content {
|
|
margin-top: 2rem;
|
|
}
|
|
.content h1 {
|
|
font-size: 1.75rem;
|
|
margin-top: 2rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.content h2 {
|
|
font-size: 1.5rem;
|
|
margin-top: 2rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.content h3 {
|
|
font-size: 1.25rem;
|
|
margin-top: 1.5rem;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
.content p {
|
|
margin-bottom: 1rem;
|
|
}
|
|
.content ul,
|
|
.content ol {
|
|
margin-bottom: 1rem;
|
|
padding-left: 1.5rem;
|
|
}
|
|
.content li {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.content blockquote {
|
|
border-left: 4px solid #e5e7eb;
|
|
padding-left: 1rem;
|
|
margin: 1rem 0;
|
|
color: #4b5563;
|
|
font-style: italic;
|
|
}
|
|
.content pre {
|
|
background: #f3f4f6;
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
overflow-x: auto;
|
|
margin: 1rem 0;
|
|
}
|
|
.content code {
|
|
background: #f3f4f6;
|
|
padding: 0.125rem 0.375rem;
|
|
border-radius: 4px;
|
|
font-size: 0.875em;
|
|
}
|
|
.content pre code {
|
|
background: none;
|
|
padding: 0;
|
|
}
|
|
.content img {
|
|
max-width: 100%;
|
|
height: auto;
|
|
border-radius: 8px;
|
|
margin: 1rem 0;
|
|
}
|
|
.content a {
|
|
color: #2563eb;
|
|
}
|
|
|
|
/* Embed styles */
|
|
.content iframe {
|
|
max-width: 100%;
|
|
border-radius: 8px;
|
|
margin: 1rem 0;
|
|
}
|
|
|
|
footer {
|
|
margin-top: 3rem;
|
|
padding-top: 1rem;
|
|
border-top: 1px solid #e5e7eb;
|
|
font-size: 0.875rem;
|
|
}
|
|
footer a {
|
|
color: #2563eb;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<a href="/posts" class="back">← Back to posts</a>
|
|
|
|
<article>
|
|
<h1>{title || "Untitled"}</h1>
|
|
<div class="meta">
|
|
{post.data.status === "draft" && <span>Draft</span>}
|
|
</div>
|
|
|
|
<div class="content">
|
|
{
|
|
Array.isArray(content) && content.length > 0 ? (
|
|
<PortableText
|
|
value={content}
|
|
components={{ type: embedComponents }}
|
|
/>
|
|
) : typeof content === "string" && content ? (
|
|
<p>{content}</p>
|
|
) : (
|
|
<p style="color: #6b7280; font-style: italic;">No content yet.</p>
|
|
)
|
|
}
|
|
</div>
|
|
</article>
|
|
|
|
<footer>
|
|
<a href={`/_emdash/admin/content/posts/${post.id}`}>Edit in Admin</a>
|
|
</footer>
|
|
</body>
|
|
</html>
|