diff options
Diffstat (limited to 'nuldoc-src/templates/post_list.ts')
| -rw-r--r-- | nuldoc-src/templates/post_list.ts | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/nuldoc-src/templates/post_list.ts b/nuldoc-src/templates/post_list.ts new file mode 100644 index 0000000..bd91840 --- /dev/null +++ b/nuldoc-src/templates/post_list.ts @@ -0,0 +1,143 @@ +import { Element } from "../dom.ts"; +import { Document } from "../docbook/document.ts"; +import { Config } from "../config.ts"; +import { el, stylesheetLinkElement, text } from "./utils.ts"; + +function metaElement(attrs: [string, string][]): Element { + return el("meta", attrs); +} + +function linkElement(rel: string, href: string, type: string | null): Element { + const attrs: [string, string][] = [["rel", rel], ["href", href]]; + if (type !== null) { + attrs.push(["type", type]); + } + return el("link", attrs); +} + +export default async function convertPostList( + posts: Document[], + config: Config, +): Promise<Document> { + const doc = { + root: el("__root__", []), + sourceFilePath: "<postList>", + link: "/posts/", + title: "投稿一覧", + summary: "投稿した記事の一覧", + tags: [], + revisions: [], + }; + + const head = el( + "head", + [], + metaElement([["charset", "UTF-8"]]), + metaElement([["name", "viewport"], [ + "content", + "width=device-width, initial-scale=1.0", + ]]), + metaElement([["name", "author"], ["content", config.blog.author]]), + metaElement([["name", "copyright"], [ + "content", + `© ${config.blog.siteCopyrightYear} ${config.blog.author}`, + ]]), + metaElement([["name", "description"], ["content", doc.summary]]), + linkElement("icon", "/favicon.svg", "image/svg+xml"), + el("title", [], text(`${doc.title} | ${config.blog.siteName}`)), + await stylesheetLinkElement("/hl.css", config), + await stylesheetLinkElement("/style.css", config), + await stylesheetLinkElement("/custom.css", config), + ); + const body = el( + "body", + [["class", "list"]], + el( + "header", + [["class", "header"]], + el( + "nav", + [["class", "nav"]], + el( + "p", + [["class", "logo"]], + el("a", [["href", "/"]], text(config.blog.siteName)), + ), + ), + ), + el( + "main", + [["class", "main"]], + el( + "header", + [["class", "page-header"]], + el( + "h1", + [], + text(doc.title), + ), + ), + ...Array.from(posts).sort((a, b) => { + const ta = a.revisions[0].date; + const tb = b.revisions[0].date; + if (ta > tb) return -1; + if (ta < tb) return 1; + return 0; + }).map((post) => + el( + "article", + [["class", "post-entry"]], + el( + "a", + [["href", post.link]], + el( + "header", + [["class", "entry-header"]], + el("h2", [], text(post.title)), + ), + el( + "section", + [["class", "entry-content"]], + el("p", [], text(post.summary)), + ), + el( + "footer", + [["class", "entry-footer"]], + text("Posted on"), + el( + "time", + [["datetime", post.revisions[0].date]], + text(post.revisions[0].date), + ), + ...(post.revisions.length > 1 + ? [ + text(", updated on "), + el("time", [[ + "datetime", + post.revisions[post.revisions.length - 1].date, + ]], text(post.revisions[post.revisions.length - 1].date)), + ] + : []), + ), + ), + ) + ), + ), + el( + "footer", + [["class", "footer"]], + text( + `© ${config.blog.siteCopyrightYear} ${config.blog.author}`, + ), + ), + ); + const html = el( + "html", + [["lang", "ja-JP"]], + head, + body, + ); + + doc.root.children = [html]; + return doc; +} |
