diff --git a/src/lib/blog.ts b/src/lib/blog.ts index 567ae70..15bb6e2 100644 --- a/src/lib/blog.ts +++ b/src/lib/blog.ts @@ -1,20 +1,41 @@ +/** + * Blog Post Management Service + * Zentrale Verwaltung aller Blog-Beiträge mit automatischer Kategorie-Erkennung + */ + import fs from 'fs'; import path from 'path'; +/** + * Blog Post Interface + * Definiert die Struktur eines Blog-Beitrags + */ export interface BlogPost { + /** URL-freundlicher Slug */ slug: string; + /** Titel des Beitrags */ title: string; + /** Veröffentlichungsdatum (ISO 8601) */ date: string; + /** Kurze Zusammenfassung */ excerpt: string; + /** Pfad zum Cover-Bild */ coverImage: string; + /** Kategorie des Beitrags */ category?: string; + /** Schlagwörter/Tags */ tags?: string[]; + /** Vollständiger Markdown-Inhalt */ content?: string; } +// Verzeichnis der Blog-Beiträge const BLOG_POSTS_DIR = path.join(process.cwd(), 'blog-posts'); -// Category mapping based on filename patterns +/** + * Kategorie-Mapping basierend auf Dateinamen- und Inhaltsmustern + * Ordnet Keywords automatisch passenden Kategorien zu + */ const categoryMap: Record = { 'agentic': 'KI-Agenten', 'ai-agent': 'KI-Agenten', @@ -58,6 +79,13 @@ const categoryMap: Record = { 'home-assistant': 'Smart Home', }; +/** + * Erkennt automatisch die Kategorie eines Blog-Posts + * Analysiert Dateiname und Inhalt auf Keywords + * @param filename - Dateiname des Blog-Posts + * @param content - Inhalt des Blog-Posts + * @returns Die erkannte Kategorie oder 'Technologie' als Fallback + */ function detectCategory(filename: string, content: string): string { const lowerFilename = filename.toLowerCase(); const lowerContent = content.toLowerCase().slice(0, 500); @@ -70,6 +98,13 @@ function detectCategory(filename: string, content: string): string { return 'Technologie'; } +/** + * Parst einen Markdown-Blog-Post und extrahiert alle Metadaten + * Extrahiert Titel, Meta-Description, Keywords, Kategorie und generiert Slug + * @param filename - Dateiname des Markdown-Posts + * @param content - Vollständiger Markdown-Inhalt + * @returns BlogPost-Objekt oder null bei Fehler + */ function parseMarkdownPost(filename: string, content: string): BlogPost | null { try { // Extract title from first H1 @@ -129,6 +164,11 @@ function parseMarkdownPost(filename: string, content: string): BlogPost | null { } } +/** + * Lädt alle Blog-Posts aus dem Dateisystem + * Posts werden nach Datum absteigend sortiert (neueste zuerst) + * @returns Array aller Blog-Posts + */ export function getAllBlogPosts(): BlogPost[] { if (!fs.existsSync(BLOG_POSTS_DIR)) { console.warn('Blog posts directory not found:', BLOG_POSTS_DIR); @@ -154,11 +194,21 @@ export function getAllBlogPosts(): BlogPost[] { return posts.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); } +/** + * Sucht einen Blog-Post anhand seines Slugs + * @param slug - Der URL-Slug des gesuchten Posts + * @returns Der gefundene Blog-Post oder null + */ export function getBlogPostBySlug(slug: string): BlogPost | null { const posts = getAllBlogPosts(); return posts.find(post => post.slug === slug) || null; } +/** + * Gibt alle verfügbaren Blog-Post Slugs zurück + * Nützlich für statische Seitengenerierung + * @returns Array aller Post-Slugs + */ export function getBlogPostSlugs(): string[] { return getAllBlogPosts().map(post => post.slug); }