From 7007660a80585208e09ca4b003e8d58f897b025a Mon Sep 17 00:00:00 2001 From: Max Litruv Boonzaayer Date: Sun, 10 May 2026 23:33:29 +1000 Subject: [PATCH] feat: add extractDescription method and enhance renderPageTemplate with Open Graph metadata --- tools/StaticBlogGenerator.js | 54 +++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/tools/StaticBlogGenerator.js b/tools/StaticBlogGenerator.js index d70d4f5..4f5467e 100644 --- a/tools/StaticBlogGenerator.js +++ b/tools/StaticBlogGenerator.js @@ -84,6 +84,23 @@ class StaticBlogGenerator { return this.renderPageTemplate('Blog', content, '/blog.html'); } + /** + * Extracts a plain-text description from the first paragraph of markdown content. + * + * @param {string} content + * @returns {string} + */ + extractDescription(content) { + const lines = (content || '').split('\n'); + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('!') || trimmed.startsWith('>') || /^[-*_]{3,}$/.test(trimmed) || trimmed.startsWith('```')) continue; + const plain = trimmed.replace(/[*_`\[\]]/g, '').replace(/!?\[.*?\]\(.*?\)/g, '').trim(); + if (plain.length > 20) return plain.slice(0, 160); + } + return 'Read this post on lit.ruv.wtf'; + } + /** * @param {{slug: string, title: string, date: string | null, author: string | null, tags?: string[], content: string}} post * @param {{slug: string, title: string, date: string | null} | null} prev - Older post (lower index) @@ -161,7 +178,16 @@ class StaticBlogGenerator { '' ].join('\n'); - return this.renderPageTemplate(`${safeTitle} - Blog`, content, `/blog/${encodeURIComponent(post.slug)}/`); + const canonicalUrl = `https://lit.ruv.wtf/blog/${encodeURIComponent(post.slug)}/`; + return this.renderPageTemplate(`${safeTitle} - Blog`, content, `/blog/${encodeURIComponent(post.slug)}/`, { + description: this.extractDescription(post.content), + ogTitle: safeTitle, + ogType: 'article', + ogUrl: canonicalUrl, + articlePublishedTime: post.date || null, + articleAuthor: post.author || null, + articleTags: tags, + }); } /** @@ -170,8 +196,27 @@ class StaticBlogGenerator { * @param {string} canonicalPath * @returns {string} */ - renderPageTemplate(title, bodyHtml, canonicalPath) { + renderPageTemplate(title, bodyHtml, canonicalPath, og = {}) { const escapedTitle = this.escapeHtml(title); + const canonicalUrl = `https://lit.ruv.wtf${canonicalPath}`; + const description = this.escapeHtml(og.description || 'lit.ruv.wtf blog posts.'); + const ogTitle = this.escapeHtml(og.ogTitle || title); + const ogType = og.ogType || 'website'; + const ogUrl = og.ogUrl || canonicalUrl; + + const ogMeta = [ + ` `, + ` `, + ` `, + ` `, + ` `, + ` `, + ` `, + ` `, + og.articlePublishedTime ? ` ` : '', + og.articleAuthor ? ` ` : '', + ...(og.articleTags || []).map(t => ` `,), + ].filter(Boolean); return [ '', @@ -181,8 +226,9 @@ class StaticBlogGenerator { ' ', ' ', ` ${escapedTitle}`, - ' ', - ` `, + ` `, + ` `, + ...ogMeta, ' ', ' ', ' ',