diff --git a/scripts/lib/renderers.mjs b/scripts/lib/renderers.mjs new file mode 100644 index 0000000..b8e9d35 --- /dev/null +++ b/scripts/lib/renderers.mjs @@ -0,0 +1,225 @@ +import { SITE_URL } from "./constants.mjs"; +import { footer, nav, shellHead } from "./templates.mjs"; +import { escapeHtml, escapeXml, fmtDate, renderAuthorInline, toISODate } from "./utils.mjs"; + +export const renderHome = (articles) => ` +${shellHead({ + title: "apophenia.news — The news outlet for pattern seekers", + desc: "Signals, anomalies, civilization trajectories, and deep pattern analysis.", + image: "https://direct-img.link/constellation+data+points+minimal+white+background", + url: `${SITE_URL}/`, + type: "website" +})} +${nav} +
+
+

Pattern Intelligence Journalism

+

The news outlet for pattern seekers

+

High-agency analysis at the intersection of AGI, consciousness, geopolitics, and first-contact logic.

+
+ +
+
+

Latest Articles

+ ${articles.length} published +
+ +
+ ${articles + .map( + (a) => ` + ` + ) + .join("")} +
+
+
+${footer} +`; + +export const renderArticle = (article) => ` +${shellHead({ + title: `${article.title} — apophenia.news`, + desc: article.description, + image: article.header_image, + url: `${SITE_URL}/${article.slug}/`, + type: "article" +})} +${nav} +
+
+ ${escapeHtml(article.title)} +
+

${fmtDate(article.date)} • ${renderAuthorInline(article.author)}

+

${escapeHtml(article.title)}

+

${escapeHtml(article.description || "")}

+
+ ${(article.tags || []).map((t) => `#${escapeHtml(t)}`).join("")} +
+
+
${article.html}
+
+
+ +
+ + Back to Home + +
+
+${footer} +`; + +export const renderWritePage = () => ` +${shellHead({ + title: "Become a writer for apophenia.news", + desc: "Pitch your pattern analysis. Email your story as a Markdown file for review and publication.", + image: "https://direct-img.link/writer+typing+cosmic+newsroom+editorial", + url: `${SITE_URL}/write/`, + type: "website" +})} +${nav} +
+
+

Contributor Program

+

Become a writer for apophenia.news

+

+ Have a strong pattern-based story, analysis, or investigation? Send it to us. +

+ +
+

How to submit

+
    +
  • Write your article in a .md (Markdown) file.
  • +
  • Email it to planetrenox@pm.me.
  • +
  • If approved, your story will be published on apophenia.news.
  • +
  • Your byline can use your real name or an alias.
  • +
+ +

Submission tips

+
    +
  • Lead with a clear thesis and strong evidence.
  • +
  • Use links/citations when making factual claims.
  • +
  • Include a short author bio line if you want one shown.
  • +
  • Add a suggested title, slug, description, and tags at the top (frontmatter preferred).
  • +
+ +

Frontmatter template (optional)

+
---
+title: "Your headline"
+slug: your-slug
+date: 2026-03-01
+author: Your Name or Alias
+description: "1-2 sentence summary"
+header_image: https://direct-img.link/your+image+query
+tags:
+  - your-tag
+  - another-tag
+---
+
+
+
+${footer} +`; + +export const renderAuthorPage = (author) => ` +${shellHead({ + title: `${author.name} — apophenia.news`, + desc: author.bio, + image: author.image || "https://direct-img.link/author+profile+minimal+portrait+placeholder", + url: `${SITE_URL}/author/${author.slug}/`, + type: "profile" +})} +${nav} +
+
+

Author

+

${escapeHtml(author.name)}

+ +
+
+ Photo coming soon +
+ +
+

${escapeHtml(author.bio)}

+

Contact: ${escapeHtml(author.contact)}

+
+
+
+
+${footer} +`; + +export const renderRss = (articles) => { + const lastBuildDate = new Date().toUTCString(); + const items = articles + .map((a) => { + const link = `${SITE_URL}/${a.slug}/`; + return ` + ${escapeXml(a.title || "")} + ${escapeXml(link)} + ${escapeXml(link)} + ${new Date(a.date).toUTCString()} + ${escapeXml(a.description || "")} +`; + }) + .join("\n"); + + return ` + + + apophenia.news + ${SITE_URL}/ + Signals, anomalies, civilization trajectories, and deep pattern analysis. + en-us + ${lastBuildDate} + ${items} + + +`; +}; + +export const renderSitemap = (articles, authors = []) => { + const now = toISODate(new Date()); + const urls = [ + { loc: `${SITE_URL}/`, lastmod: now }, + { loc: `${SITE_URL}/write/`, lastmod: now }, + ...authors.map((a) => ({ loc: `${SITE_URL}/author/${a.slug}/`, lastmod: now })), + ...articles.map((a) => ({ loc: `${SITE_URL}/${a.slug}/`, lastmod: toISODate(a.date || new Date()) })) + ]; + + return ` + +${urls + .map( + (u) => ` + ${escapeXml(u.loc)} + ${u.lastmod} + ` + ) + .join("\n")} + +`; +}; + +export const renderRobots = () => `User-agent: * +Allow: / + +Sitemap: ${SITE_URL}/sitemap.xml +`;