A CLI for publishing standard.site documents to ATProto sequoia.pub

Slug and Frontmatter Updates #110

Closed stevedylan.dev
targeting main from chore/frontmatter-config-updates
Closed opened by and assigned to stevedylan.dev
targeting main from chore/frontmatter-config-updates

Overview #

This PR fixes issues raised in #3

UX Changes #

  • Subdirectory support: Posts in nested folders like a/b/post.md can now preserve their full path in URLs (set slugSource: "path")
  • Frontmatter slug support: Use a field from your frontmatter (like slug or url) to define the path (set slugSource: "frontmatter")
  • Hugo index.md support: Remove /index suffix from paths automatically (set removeIndexFromSlug: true)
  • Custom text content: Use a frontmatter field like summary for the AT Protocol textContent instead of the full markdown body (set textContentField: "summary")
  • Description now works: The description field from frontmatter is now actually published to AT Protocol records (was a bug , never added to records before)

Example config using frontmatter slugs:

  {
    "siteUrl": "https://example.com",
    "contentDir": "content/posts",
    "pathPrefix": "/blog",
    "publicationUri": "at://did:plc:.../site.standard.publication/...",
    "slugSource": "frontmatter",
    "slugField": "url"
  }

Example frontmatter:

---
title: "My Post Title"
date: 2024-01-15
url: "2024/my-custom-slug"
summary: "A brief description of this post"
---

This would create a document with path /blog/2024/my-custom-slug

File Updates #

  1. src/lib/types.ts
  • Added new config options to PublisherConfig:
  • slugSource: "filename" | "path" | "frontmatter" (default: "filename")
  • slugField: string for frontmatter field when using slugSource: "frontmatter"
  • removeIndexFromSlug: boolean to strip /index or /_index suffixes
  • textContentField: frontmatter field to use for textContent instead of markdown body
  • Added rawFrontmatter: Record<string, unknown> to BlogPost
  1. src/lib/markdown.ts
  • Updated parseFrontmatter() to return rawFrontmatter
  • Added getSlugFromOptions() function supporting three modes (filename, path, frontmatter)
  • Added ScanOptions interface for cleaner option passing
  • Updated scanContentDirectory() to accept new slug options and pass rawFrontmatter
  1. src/lib/atproto.ts
  • Added description field to DocumentRecord interface
  • Fixed createDocument() to add description to record when available
  • Fixed updateDocument() to add description to record when available
  • Added textContentField support to both functions
  1. src/commands/publish.ts
  • Updated to pass new config options to scanContentDirectory()
  1. src/commands/sync.ts
  • Updated to pass new config options to scanContentDirectory()
  • Fixed path matching to use configured pathPrefix
  1. src/lib/config.ts
  • Updated generateConfigTemplate() to include new options
Commits 0