summaryrefslogtreecommitdiffhomepage
path: root/vhosts/blog/nuldoc-src/atom
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-02-22 01:51:21 +0900
committernsfisis <nsfisis@gmail.com>2024-02-24 14:24:15 +0900
commit7c81d7bf5bcb6fb9578ae4ae54684742bf9ae35d (patch)
tree4534959896de4ba5492f8f35417fd45670296574 /vhosts/blog/nuldoc-src/atom
parentb72e1bd7b40f1c9c3558b6ed50367a2b7fc11d62 (diff)
downloadnsfisis.dev-7c81d7bf5bcb6fb9578ae4ae54684742bf9ae35d.tar.gz
nsfisis.dev-7c81d7bf5bcb6fb9578ae4ae54684742bf9ae35d.tar.zst
nsfisis.dev-7c81d7bf5bcb6fb9578ae4ae54684742bf9ae35d.zip
feat(blog/nuldoc): implement generating Atom feed
Diffstat (limited to 'vhosts/blog/nuldoc-src/atom')
-rw-r--r--vhosts/blog/nuldoc-src/atom/generate.ts86
-rw-r--r--vhosts/blog/nuldoc-src/atom/types.ts19
2 files changed, 105 insertions, 0 deletions
diff --git a/vhosts/blog/nuldoc-src/atom/generate.ts b/vhosts/blog/nuldoc-src/atom/generate.ts
new file mode 100644
index 00000000..cb425aba
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/atom/generate.ts
@@ -0,0 +1,86 @@
+import { Config } from "../config.ts";
+import { el, text } from "../dom.ts";
+import { Page } from "../page.ts";
+import { Entry, Feed } from "./types.ts";
+import { PostPage } from "../pages/post.ts";
+import { SlidePage } from "../pages/slide.ts";
+import { dateToRfc3339String } from "../revision.ts";
+
+const BASE_NAME = "atom.xml";
+
+export function generateFeedPageFromEntries(
+ alternateLink: string,
+ feedSlug: string,
+ feedTitle: string,
+ entries: Array<PostPage | SlidePage>,
+ config: Config,
+): Page {
+ const entries_: Entry[] = [];
+ for (const entry of entries) {
+ entries_.push({
+ id: `urn:uuid:${entry.uuid}`,
+ linkToAlternate: `https://${config.blog.fqdn}${entry.href}`,
+ title: entry.title,
+ summary: entry.description,
+ published: dateToRfc3339String(entry.published),
+ updated: dateToRfc3339String(entry.updated),
+ });
+ }
+ // Sort by published date in ascending order.
+ entries_.sort((a, b) => {
+ if (a.published < b.published) {
+ return 1;
+ } else if (a.published > b.published) {
+ return -1;
+ }
+ return 0;
+ });
+ const feedPath = `${alternateLink}${BASE_NAME}`;
+ const feed: Feed = {
+ author: config.blog.author,
+ icon: `https://${config.blog.fqdn}/favicon.svg`,
+ id: `tag:${config.blog.fqdn},${config.blog.siteCopyrightYear}:${feedSlug}`,
+ linkToSelf: `https://${config.blog.fqdn}${feedPath}`,
+ linkToAlternate: `https://${config.blog.fqdn}${alternateLink}`,
+ title: feedTitle,
+ updated: entries_.reduce(
+ (latest, entry) => entry.updated > latest ? entry.updated : latest,
+ entries_[0].updated,
+ ),
+ entries: entries_,
+ };
+
+ const xml = buildXmlTree(feed);
+ return {
+ root: el("__root__", [], xml),
+ renderer: "xml",
+ destFilePath: feedPath,
+ href: feedPath,
+ };
+}
+
+function buildXmlTree(feed: Feed) {
+ return el(
+ "feed",
+ [["xmlns", "http://www.w3.org/2005/Atom"]],
+ el("id", [], text(feed.id)),
+ el("title", [], text(feed.title)),
+ el("link", [["rel", "alternate"], ["href", feed.linkToAlternate]]),
+ el("link", [["rel", "self"], ["href", feed.linkToSelf]]),
+ el("author", [], el("name", [], text(feed.author))),
+ el("updated", [], text(feed.updated)),
+ ...feed.entries.map(
+ (entry) =>
+ el(
+ "entry",
+ [],
+ el("id", [], text(entry.id)),
+ el("link", [["rel", "alternate"], ["href", entry.linkToAlternate]]),
+ el("title", [], text(entry.title)),
+ el("summary", [], text(entry.summary)),
+ el("published", [], text(entry.published)),
+ el("updated", [], text(entry.updated)),
+ ),
+ ),
+ );
+}
diff --git a/vhosts/blog/nuldoc-src/atom/types.ts b/vhosts/blog/nuldoc-src/atom/types.ts
new file mode 100644
index 00000000..66fde5ba
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/atom/types.ts
@@ -0,0 +1,19 @@
+export type Feed = {
+ author: string;
+ icon: string;
+ id: string;
+ linkToSelf: string;
+ linkToAlternate: string;
+ title: string;
+ updated: string;
+ entries: Entry[];
+};
+
+export type Entry = {
+ id: string;
+ linkToAlternate: string;
+ published: string;
+ summary: string;
+ title: string;
+ updated: string;
+};