Emdash source with visual editor image upload fix
Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
176
demos/plugins-demo/src/pages/posts/[slug].astro
Normal file
176
demos/plugins-demo/src/pages/posts/[slug].astro
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
/**
|
||||
* 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>
|
||||
Reference in New Issue
Block a user