Ein Blog erstellen

Auf dieser Seite

Diese Anleitung führt Sie durch die Erstellung eines Blogs mit EmDash – von der Definition Ihres Inhaltstyps bis zur Darstellung von Beiträgen mit Kategorien und Tags.

Voraussetzungen

  • Eine eingerichtete und laufende EmDash-Site (siehe Erste Schritte)
  • Grundkenntnisse in Astro-Komponenten

Die Posts-Collection definieren

EmDash legt bei der Einrichtung standardmäßig eine Collection „posts“ an. Zum Anpassen nutzen Sie das Admin-Dashboard oder die API.

Die Standard-Posts-Collection enthält:

  • title – Beitragstitel
  • slug – URL-freundlicher Bezeichner
  • content – Rich-Text-Textkörper
  • excerpt – Kurzbeschreibung
  • featured_image – Kopfbild (optional)
  • status – Entwurf, veröffentlicht oder geplant
  • publishedAt – Veröffentlichungsdatum (Systemfeld)

Ihren ersten Beitrag erstellen

  1. Öffnen Sie das Admin-Dashboard unter /_emdash/admin

  2. Klicken Sie in der Seitenleiste auf Posts

    EmDash-Beitragsliste mit Titeln, Status und Daten
  3. Klicken Sie auf New Post

    EmDash-Beitragseditor mit Titel, Inhalt und Veröffentlichungsoptionen
  4. Geben Sie einen Titel ein und schreiben Sie den Inhalt im Rich-Text-Editor

  5. Fügen Sie im Seitenleistenbereich Kategorien und Tags hinzu

  6. Setzen Sie den Status auf Published

  7. Klicken Sie auf Save

Ihr Beitrag ist jetzt live. Kein Rebuild nötig.

Beiträge auf der Site anzeigen

Alle Beiträge auflisten

Erstellen Sie eine Seite, die alle veröffentlichten Beiträge zeigt:

---
import { getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";

const { entries: posts } = await getEmDashCollection("posts", {
  status: "published",
});

// Sort by publication date, newest first
const sortedPosts = posts.sort(
  (a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0)
);
---

<Base title="Blog">
  <h1>Blog</h1>
  <ul>
    {sortedPosts.map((post) => (
      <li>
        <a href={`/blog/${post.data.slug}`}>
          <h2>{post.data.title}</h2>
          <p>{post.data.excerpt}</p>
          <time datetime={post.data.publishedAt?.toISOString()}>
            {post.data.publishedAt?.toLocaleDateString()}
          </time>
        </a>
      </li>
    ))}
  </ul>
</Base>

Einzelnen Beitrag anzeigen

Legen Sie eine dynamische Route für einzelne Beiträge an:

---
import { getEmDashCollection, getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "../../layouts/Base.astro";

export async function getStaticPaths() {
  const { entries: posts } = await getEmDashCollection("posts", {
    status: "published",
  });

  return posts.map((post) => ({
    params: { slug: post.data.slug },
  }));
}

const { slug } = Astro.params;
const { entry: post } = await getEmDashEntry("posts", slug);

if (!post) {
  return Astro.redirect("/404");
}
---

<Base title={post.data.title}>
  <article>
    {post.data.featured_image && (
      <img src={post.data.featured_image} alt="" />
    )}
    <h1>{post.data.title}</h1>
    <time datetime={post.data.publishedAt?.toISOString()}>
      {post.data.publishedAt?.toLocaleDateString()}
    </time>
    <PortableText value={post.data.content} />
  </article>
</Base>

Kategorien und Tags hinzufügen

EmDash enthält eingebaute Kategorie- und Tag-Taxonomien. Siehe Taxonomien zum Anlegen und Verwalten von Begriffen.

Beiträge nach Kategorie filtern

---
import { getEmDashCollection, getTerm, getTaxonomyTerms } from "emdash";
import Base from "../../layouts/Base.astro";

export async function getStaticPaths() {
  const categories = await getTaxonomyTerms("category");

  // Flatten hierarchical categories
  const flatten = (terms) => terms.flatMap((t) => [t, ...flatten(t.children)]);

  return flatten(categories).map((cat) => ({
    params: { slug: cat.slug },
    props: { category: cat },
  }));
}

const { category } = Astro.props;

const { entries: posts } = await getEmDashCollection("posts", {
  status: "published",
  where: { category: category.slug },
});
---

<Base title={category.label}>
  <h1>{category.label}</h1>
  {category.description && <p>{category.description}</p>}

  <ul>
    {posts.map((post) => (
      <li>
        <a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
      </li>
    ))}
  </ul>
</Base>

Kategorien am Beitrag anzeigen

Zeigen Sie Kategorien bei einzelnen Beiträgen:

---
import { getEntryTerms } from "emdash";

interface Props {
  postId: string;
}

const { postId } = Astro.props;
const categories = await getEntryTerms("posts", postId, "category");
const tags = await getEntryTerms("posts", postId, "tag");
---

<div class="post-meta">
  {categories.length > 0 && (
    <div class="categories">
      <span>Categories:</span>
      {categories.map((cat) => (
        <a href={`/category/${cat.slug}`}>{cat.label}</a>
      ))}
    </div>
  )}

  {tags.length > 0 && (
    <div class="tags">
      <span>Tags:</span>
      {tags.map((tag) => (
        <a href={`/tag/${tag.slug}`}>{tag.label}</a>
      ))}
    </div>
  )}
</div>

Paginierung hinzufügen

Bei Blogs mit vielen Beiträgen Paginierung ergänzen:

---
import { getEmDashCollection } from "emdash";
import Base from "../../../layouts/Base.astro";

const POSTS_PER_PAGE = 10;

export async function getStaticPaths() {
  const { entries: allPosts } = await getEmDashCollection("posts", {
    status: "published",
  });

  const totalPages = Math.ceil(allPosts.length / POSTS_PER_PAGE);

  return Array.from({ length: totalPages }, (_, i) => ({
    params: { page: String(i + 1) },
    props: { currentPage: i + 1, totalPages },
  }));
}

const { currentPage, totalPages } = Astro.props;

const { entries: allPosts } = await getEmDashCollection("posts", {
  status: "published",
});

const sortedPosts = allPosts.sort(
  (a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0)
);

const start = (currentPage - 1) * POSTS_PER_PAGE;
const posts = sortedPosts.slice(start, start + POSTS_PER_PAGE);
---

<Base title={`Blog - Page ${currentPage}`}>
  <h1>Blog</h1>

  <ul>
    {posts.map((post) => (
      <li>
        <a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
      </li>
    ))}
  </ul>

  <nav>
    {currentPage > 1 && (
      <a href={`/blog/page/${currentPage - 1}`}>Previous</a>
    )}
    <span>Page {currentPage} of {totalPages}</span>
    {currentPage < totalPages && (
      <a href={`/blog/page/${currentPage + 1}`}>Next</a>
    )}
  </nav>
</Base>

RSS-Feed hinzufügen

Erstellen Sie einen RSS-Feed für Ihr Blog:

import rss from "@astrojs/rss";
import { getEmDashCollection } from "emdash";

export async function GET(context) {
	const { entries: posts } = await getEmDashCollection("posts", {
		status: "published",
	});

	return rss({
		title: "My Blog",
		description: "A blog built with EmDash",
		site: context.site,
		items: posts.map((post) => ({
			title: post.data.title,
			pubDate: post.data.publishedAt,
			description: post.data.excerpt,
			link: `/blog/${post.data.slug}`,
		})),
	});
}

Installieren Sie das RSS-Paket, falls noch nicht geschehen:

npm install @astrojs/rss

Nächste Schritte