summaryrefslogtreecommitdiffhomepage
path: root/vhosts/blog/nuldoc-src/atom/generate.ts
blob: 7c8e2ea466dfd6a35936ab57b2e58f1944c0fec9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { Config } from "../config.ts";
import { el } 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", [], feed.id),
    el("title", [], feed.title),
    el("link", [["rel", "alternate"], ["href", feed.linkToAlternate]]),
    el("link", [["rel", "self"], ["href", feed.linkToSelf]]),
    el("author", [], el("name", [], feed.author)),
    el("updated", [], feed.updated),
    ...feed.entries.map(
      (entry) =>
        el(
          "entry",
          [],
          el("id", [], entry.id),
          el("link", [["rel", "alternate"], ["href", entry.linkToAlternate]]),
          el("title", [], entry.title),
          el("summary", [], entry.summary),
          el("published", [], entry.published),
          el("updated", [], entry.updated),
        ),
    ),
  );
}