From 76da48766c562c43a65db4e25030ea3acb16d34c Mon Sep 17 00:00:00 2001 From: IwanIDev Date: Sat, 21 Mar 2026 15:50:35 +0000 Subject: feat: integrate Openring for webring section and update related files --- README.md | 27 ++++++++++++++++++++- openring/feeds.txt | 3 +++ openring/out.html | 4 ++++ openring/template.html | 24 +++++++++++++++++++ package.json | 5 ++-- scripts/generate-openring.mjs | 56 +++++++++++++++++++++++++++++++++++++++++++ src/components/OpenRing.astro | 7 ++++++ src/pages/index.astro | 5 +++- 8 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 openring/feeds.txt create mode 100644 openring/out.html create mode 100644 openring/template.html create mode 100644 scripts/generate-openring.mjs create mode 100644 src/components/OpenRing.astro diff --git a/README.md b/README.md index 494ec00..4db02bf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,29 @@ # Astro Blog Site This is my blog site written with Astro, Tailwind CSS, and shadcn/ui. -**WORK IN PROGRESS** +## Openring integration + +This project integrates [`openring`](https://git.sr.ht/~sircmpwn/openring) to render a webring section on the homepage. + +### How it works + +- Feed sources are defined in `openring/feeds.txt`. +- The template is defined in `openring/template.html`. +- Generated output is written to `openring/out.html`. +- `bun run dev` and `bun run build` both run `bun run openring:generate` first. + +### Install openring + +Install the `openring` binary (example using Go): + +```bash +go install git.sr.ht/~sircmpwn/openring@latest +``` + +Make sure your Go bin directory is in `PATH`, then generate output: + +```bash +bun run openring:generate +``` + +If `openring` is not installed (or feed fetch fails), the generator writes a small fallback section so builds still succeed. diff --git a/openring/feeds.txt b/openring/feeds.txt new file mode 100644 index 0000000..40a9bf6 --- /dev/null +++ b/openring/feeds.txt @@ -0,0 +1,3 @@ +https://drewdevault.com/feed.xml +https://emersion.fr/blog/rss.xml +https://danluu.com/atom.xml diff --git a/openring/out.html b/openring/out.html new file mode 100644 index 0000000..df17628 --- /dev/null +++ b/openring/out.html @@ -0,0 +1,4 @@ +
+

Around the web

+

Install openring and run bun run openring:generate to render this section.

+
diff --git a/openring/template.html b/openring/template.html new file mode 100644 index 0000000..86ead2c --- /dev/null +++ b/openring/template.html @@ -0,0 +1,24 @@ +
+

Around the web

+

Recent posts from sites I follow.

+ +
+ {{range .Articles}} + + {{end}} +
+ +

+ Generated by openring +

+
diff --git a/package.json b/package.json index eaf439a..51033f8 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,11 @@ "version": "0.0.1", "private": true, "scripts": { - "dev": "astro dev", - "build": "astro build", + "dev": "bun run openring:generate && astro dev", + "build": "bun run openring:generate && astro build", "preview": "astro preview", "astro": "astro", + "openring:generate": "node scripts/generate-openring.mjs", "lint": "eslint .", "format": "prettier --write \"**/*.{ts,tsx,astro}\"", "typecheck": "astro check" diff --git a/scripts/generate-openring.mjs b/scripts/generate-openring.mjs new file mode 100644 index 0000000..7400831 --- /dev/null +++ b/scripts/generate-openring.mjs @@ -0,0 +1,56 @@ +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { spawnSync } from "node:child_process"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const repoRoot = path.resolve(__dirname, ".."); + +const openringDir = path.join(repoRoot, "openring"); +const feedsPath = path.join(openringDir, "feeds.txt"); +const templatePath = path.join(openringDir, "template.html"); +const outPath = path.join(openringDir, "out.html"); + +const fallbackHtml = `
+

Around the web

+

Install openring and run bun run openring:generate to render this section.

+
+`; + +await mkdir(openringDir, { recursive: true }); + +try { + const template = await readFile(templatePath, "utf8"); + + const result = spawnSync("openring", ["-S", feedsPath], { + input: template, + encoding: "utf8", + maxBuffer: 10 * 1024 * 1024, + }); + + if (result.error) { + if (result.error.code === "ENOENT") { + console.warn("[openring] binary not found; writing fallback HTML."); + await writeFile(outPath, fallbackHtml, "utf8"); + process.exit(0); + } + throw result.error; + } + + if (result.status !== 0) { + console.warn(`[openring] command failed (exit ${result.status}); writing fallback HTML.`); + if (result.stderr) { + console.warn(result.stderr.trim()); + } + await writeFile(outPath, fallbackHtml, "utf8"); + process.exit(0); + } + + await writeFile(outPath, result.stdout, "utf8"); + console.log("[openring] generated openring/out.html"); +} catch (error) { + console.warn("[openring] unexpected error; writing fallback HTML."); + console.warn(error instanceof Error ? error.message : String(error)); + await writeFile(outPath, fallbackHtml, "utf8"); +} diff --git a/src/components/OpenRing.astro b/src/components/OpenRing.astro new file mode 100644 index 0000000..8fbbf37 --- /dev/null +++ b/src/components/OpenRing.astro @@ -0,0 +1,7 @@ +--- +import openringHtml from "../../openring/out.html?raw"; +--- + +
+ +
diff --git a/src/pages/index.astro b/src/pages/index.astro index 9d04eae..5f7af3f 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,7 @@ --- import Layout from "@/layouts/main.astro" -import { Button } from "@/components/ui/button" import BlogPosts from "@/components/BlogPosts.astro" +import OpenRing from "@/components/OpenRing.astro" --- @@ -17,6 +17,9 @@ import BlogPosts from "@/components/BlogPosts.astro" + + + -- cgit