diff --git a/changelog.md b/changelog.md index 81f8da1..cf847e7 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [1.24.6] - 2025-12-23 + +### Added + +- Homepage raw markdown index file (`/raw/index.md`) + - Automatically generated during `npm run sync` and `npm run sync:prod` + - Lists all published posts sorted by date (newest first) + - Lists all published pages sorted by order or alphabetically + - Includes post metadata: date, reading time, tags, description + - Provides direct links to all raw markdown files + - AI crawlers can now access homepage content as markdown + +### Technical + +- Updated `scripts/sync-posts.ts`: Added `generateHomepageIndex()` function to create `index.md` in `public/raw/` + ## [1.24.5] - 2025-12-23 ### Fixed diff --git a/scripts/sync-posts.ts b/scripts/sync-posts.ts index fcbaefd..3828786 100644 --- a/scripts/sync-posts.ts +++ b/scripts/sync-posts.ts @@ -374,6 +374,77 @@ function generateRawMarkdownFile( fs.writeFileSync(filePath, markdown); } +// Generate homepage index markdown file listing all posts +function generateHomepageIndex( + posts: ParsedPost[], + pages: ParsedPage[] +): void { + const publishedPosts = posts.filter((p) => p.published); + const publishedPages = pages.filter((p) => p.published); + + // Sort posts by date (newest first) + const sortedPosts = [...publishedPosts].sort((a, b) => { + return new Date(b.date).getTime() - new Date(a.date).getTime(); + }); + + // Build markdown content + let markdown = `# Homepage\n\n`; + markdown += `This is the homepage index of all published content.\n\n`; + + // Add posts section + if (sortedPosts.length > 0) { + markdown += `## Blog Posts (${sortedPosts.length})\n\n`; + for (const post of sortedPosts) { + markdown += `- **[${post.title}](/raw/${post.slug}.md)**`; + if (post.description) { + markdown += ` - ${post.description}`; + } + markdown += `\n - Date: ${post.date}`; + if (post.readTime) { + markdown += ` | Reading time: ${post.readTime}`; + } + if (post.tags && post.tags.length > 0) { + markdown += ` | Tags: ${post.tags.join(", ")}`; + } + markdown += `\n`; + } + markdown += `\n`; + } + + // Add pages section + if (publishedPages.length > 0) { + markdown += `## Pages (${publishedPages.length})\n\n`; + // Sort pages by order if available, otherwise alphabetically + const sortedPages = [...publishedPages].sort((a, b) => { + if (a.order !== undefined && b.order !== undefined) { + return a.order - b.order; + } + if (a.order !== undefined) return -1; + if (b.order !== undefined) return 1; + return a.title.localeCompare(b.title); + }); + + for (const page of sortedPages) { + markdown += `- **[${page.title}](/raw/${page.slug}.md)**`; + if (page.excerpt) { + markdown += ` - ${page.excerpt}`; + } + markdown += `\n`; + } + markdown += `\n`; + } + + // Add summary + markdown += `---\n\n`; + markdown += `**Total Content:** ${sortedPosts.length} posts, ${publishedPages.length} pages\n`; + markdown += `\nAll content is available as raw markdown files at \`/raw/{slug}.md\`\n`; + + // Write index.md file + const indexPath = path.join(RAW_OUTPUT_DIR, "index.md"); + fs.writeFileSync(indexPath, markdown); + console.log("Generated homepage index: index.md"); +} + // Generate all raw markdown files during sync function generateRawMarkdownFiles( posts: ParsedPost[], @@ -421,8 +492,11 @@ function generateRawMarkdownFiles( ); } + // Generate homepage index markdown file + generateHomepageIndex(posts, pages); + console.log( - `Generated ${publishedPosts.length} post files and ${publishedPages.length} page files` + `Generated ${publishedPosts.length} post files, ${publishedPages.length} page files, and 1 index file` ); }