Communitygithub.com

timerise-ai/blog-markdown

Agent-Fähigkeit: Ein dateibasiertes mehrsprachiges Markdown-Blog aufbauen – mit sprachspezifischen Beiträgen, lokalen Slugs, die über einen gemeinsamen translationKey verbunden sind, Tags-Seiten mit Slug-Identität, verwandten Beiträgen, Titelbildern, RSS, Sitemap, hreflang und CI-Content-Validator – in Next.js App Router, ohne CMS

Was ist blog-markdown?

Diese Fähigkeit ermöglicht es einem KI-Agenten, ein vollständig statisch generiertes, mehrsprachiges Markdown-Blog in Next.js App Router zu erstellen. Das zentrale Konzept ist der `translationKey`, der die Identität eines Beitrags definiert und nicht der Slug – damit sind die Slugs pro Sprache für SEO optimierbar, während der Key die Verknüpfung zwischen Übersetzungen, hreflang, Sprachumschalter und verwandten Beiträgen herstellt. Die Fähigkeit unterstützt Tag-Seiten, RSS-Feeds, Sitemaps, Titelbilder und einen CI-Validator zur Inhaltsprüfung. Sie eignet sich für Blogs mit mehr als 10 Beiträgen und mehreren Sprachen, die ohne CMS auskommen. Der implementierte Code enthält harte Regeln (z.B. keine Abhängigkeit von Slug-Ähnlichkeit über Sprachen hinweg) und kritische Fakten (z.B. Umgang mit fehlerhaften YAML-Parses durch `gray-matter`), die durch Tests abgesichert sind. Die Fähigkeit verweist auf eine Reihe von Referenzdokumenten (content-model.md, content-loader.md, i18n-and-routing.md, tags.md usw.), die die Implementierung detailliert beschreiben.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add timerise-ai/blog-markdown

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Markdown-Blog (mehrsprachig, getaggt)

Ein Blog, dessen Inhalt in Dateien und nicht in Datenbankzeilen liegt. Das gesamte Design dreht sich um eine Idee: Die Identität eines Beitrags ist sein translationKey, nicht sein Slug. Slugs werden für SEO lokalisiert und unterscheiden sich pro Sprache; der Schlüssel macht aus drei Dateien einen Artikel und ermöglicht hreflang, den Sprachumschalter, verwandte Beiträge und sprachübergreifende Weiterleitungen. Wenn Sie dieses eine Feld korrekt setzen, ist alles andere nur noch eine Frage der Nachschlageoperationen.

Geschrieben von dem Ingenieur, der dieses Modul bereits ausgeliefert hat. Die frühere Implementierung, gegen die es geprüft wurde, war ein mehrsprachiger, statisch generierter Marketing-Blog mit Sitemap und SEO-Oberfläche. Die folgenden Fakten und Regeln sind das, was die Content-Layer-Suite und der Build verifizieren; references/provenance.md enthält die Aufzeichnung.

Wann verwenden

  • Inhalt wird als Markdown im Repository erstellt und mit der App bereitgestellt
  • Mehr als eine Sprache, mit unterschiedlichen Slugs pro Sprache
  • Tag-Seiten, verwandte Beiträge, Feeds oder hreflang sind im Umfang enthalten
  • Sie möchten alles zur Build-Zeit statisch generieren

Wann NICHT verwenden

StattdessenVerwenden Sie
Ein gehostetes CMS ist die Wahrheitsquelledas SDK des CMS; behalten Sie nur references/content-model.md
Eine Dokumentationsseite / Hilfe-Center (Kategorien, Seitenleiste, Suche)eine Hilfe-Center-Fähigkeit – anderes Navigationsmodell
Ein einsprachiger Blog mit <10 Beiträgenfs + gray-matter inline; dies ist Overhead
Rendern von benutzereingereichtem Markdowneinen bereinigenden Renderer; siehe den XSS-Hinweis in references/rendering.md

Architektur

content/blog/<locale>/<localized-slug>.md   # Frontmatter + Body
        |
        v
 parseFrontmatter  --YAML, fällt bei fehlerhaften Anführungszeichen auf einen Zeilenparser zurück
        |
        v
   getAllPosts(locale)  <-- in der Produktion pro Sprache memoisiert
        |
        +--> translationKey ----> Alternativen / hreflang / Sprachumschalter
        +--> tags -> Tag-SLUG ---> Tag-Seiten (der Slug ist die Identität, nicht das Label)
        +--> related (EN-Slugs) -> verwandte Beiträge, mit EN-Fallback
        |
        v
  /blog   /blog/[slug]   /blog/tag/[slug]   sitemap.xml   feed.xml

Kritische Fakten

  1. Beziehungen werden einmal in der Standardsprache als Slugs der Standardsprache angegeben. Eine übersetzte Datei kann related ganz weglassen und erhält trotzdem die richtigen verwandten Beiträge, aufgelöst über translationKey, sodass jede Übersetzung denselben Bereich mit verwandten Beiträgen rendert. Der Fallback-Test sichert dies.
  2. Die Identität eines Tags ist sein Slug, nicht sein Label. "KI-Agenten" und "KI agenten" führen zum selben Slug und damit zur selben URL. Gruppieren Sie nach Slug und gleichen Sie Beiträge nach Slug ab, sodass alle Rechtschreibvarianten auf einer einzigen Tag-Seite erscheinen. Zwei Tests sichern dies.
  3. gray-matter wirft einen Fehler bei einem doppelt-an-geführten YAML-Skalar, der rohe Anführungszeichen enthält – typografische Anführungszeichen in einem übersetzten Auszug tun dies. Ohne einen Fallback-Parser stoppt der Build an dieser einen Datei; der zeilenweise Fallback hält den Build am Laufen. Gegen die Bibliothek verifiziert und durch einen Test abgedeckt.
  4. gray-matter cached ein fehlgeschlagenes Parsen als leeres Ergebnis. Es schreibt seinen Cache-Eintrag vor dem Parsen, sodass der zweite und jeder weitere Parse einer Datei, die einen Fehler warf, {} zurückgibt – kein Fehler, kein Frontmatter. Rufen Sie immer matter(contents, {}) auf; jedes Optionsobjekt deaktiviert den Cache.
  5. Das Laden ist O(Beiträge x Sprachen) pro Seite, wenn Sie nicht memoieren. Memoisieren Sie pro Sprache, sodass jede Inhaltsdatei einmal pro Build gelesen wird; das Auflösen von Alternativen in generateMetadata führt sonst zu einer 71-fachen Dateilese-Verstärkung, gemessen an der früheren Implementierung.
  6. getPostSlugs muss .md filtern. Der Filter verhindert, dass eine versehentliche .DS_Store zu einem .DS_Store.md-Leseversuch und einem ENOENT wird. Ein Test sichert dies.
  7. Tag-Seiten haben keine sprachübergreifende Identität. Tags sind sprachspezifischer Freitext, daher muss der Sprachumschalter auf einer Tag-URL auf das Blog-Index zurückfallen, anstatt eine URL zu bauen, die 404 ergibt.

Harte Regeln

Verwenden Sie niemals den Slug für sprachübergreifende Nachschlageoperationen. Slugs werden absichtlich lokalisiert. translationKey ist die Verbindungsspalte; eine Slug-Übereinstimmung über Sprachen hinweg ist ein Zufall, keine Beziehung.

Lassen Sie getPostBySlug niemals implizit über die Sichtbarkeit von Entwürfen entscheiden. Filtern Sie Entwürfe im Loader; dynamicParams = false verbirgt sie nur als Nebeneffekt und hört damit auf, sobald das Flag sich ändert. Der Entwurfs-Test sichert den Filter.

Rendern Sie niemals eine Konstante wie "5 Min. Lesezeit". Berechnen Sie sie aus dem Body; es kostet ein split, und der Lesezeit-Test sichert dies.

Leiten Sie niemals die URL einer Tag-Seite aus dem Label zur Lesezeit und das Label aus der URL zur Renderzeit ab, ohne auf Kollisionen zu prüfen. Dieser Rundgang ist nur verlustfrei, solange jedes Label eindeutig slugt.

Schnellstart

  1. Legen Sie den Locale-Vertrag und das Frontmatter-Schema fest – content-model.md
  2. Bauen Sie den Loader (memoisiert, .md-gefiltert, Fallback-Parser) – content-loader.md
  3. Verdrahten Sie Locales, Alternativen und sprachübergreifende Weiterleitungen – i18n-and-routing.md
  4. Fügen Sie Tag-Gruppierung und Tag-Seiten hinzu – tags.md
  5. Bauen Sie die drei Routen, Metadaten und JSON-LD – pages-and-seo.md
  6. Rendern Sie Body und Titelbilder – rendering.md
  7. Fügen Sie das Validierungsskript hinzu und lesen Sie die Betriebslücken – operations.md
  8. Führen Sie die Testdaten und Tests aus – testing.md

Portieren Sie dies in eine bestehende App? Füllen Sie zuerst die Nahtstellentabelle in adaptation.md aus – das dauert zehn Minuten und spart eine Umbenennung.

Referenzverzeichnis

SzenarioAuslösende SchlüsselwörterReferenz
Frontmatter-Felder, Entwürfe, Übersetzungsschlüssel, Beziehungenfrontmatter, schema, translationKey, draft, related, excerptcontent-model.md
Dateien lesen, Caching, YAML-Fehler, Lesezeitgray-matter, fs, cache, memoize, ENOENT, YAMLException, parsecontent-loader.md
Locales, hreflang, Alternativen, Links in falscher Sprachei18n, locale, hreflang, alternates, canonical, language switcher, redirecti18n-and-routing.md
Tag-URLs, Kollisionen, dünne Tag-Seitentag, slug, diacritics, collision, tag page, taxonomytags.md
Die Routen, Metadaten, JSON-LD, Sitemap, RSSpage.tsx, generateStaticParams, generateMetadata, dynamicParams, sitemap, RSS, feed, BlogPostingpages-and-seo.md
Markdown zu React, Codeblöcke, Titelbilderreact-markdown, remark-gfm, syntax highlighting, cover, motif, accent, XSSrendering.md
Inhalte validieren, Build-Kosten, Editor-Workflowvalidation, CI check, build time, drafts, authoring, operatoroperations.md
Testdaten und die erfolgreiche Testsuitetest, fixture, vitest, node:test, regression, asserttesting.md
Einpassen in eine Host-App: Nahtstellen, Umbenennungen, Prüfungadapt, port, host, seam, rename, CMS, integrateadaptation.md
Das Audit-Ledger: Was geändert, beibehalten und hinzugefügt wurde im Vergleich zur früheren Implementierungprovenance, deviations, fidelity, audit, ledgerprovenance.md

Verwandte Skills