From 940eae61767214eb1ee573284dc8b5876d536fb3 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 12 Jan 2025 19:44:19 +0900 Subject: refactor(blog/nuldoc): convert pages/*.ts to TSX --- vhosts/blog/nuldoc-src/atom/generate.ts | 4 +- vhosts/blog/nuldoc-src/commands/build.ts | 18 ++-- vhosts/blog/nuldoc-src/pages/about.ts | 156 ---------------------------- vhosts/blog/nuldoc-src/pages/about.tsx | 106 +++++++++++++++++++ vhosts/blog/nuldoc-src/pages/home.ts | 97 ----------------- vhosts/blog/nuldoc-src/pages/home.tsx | 65 ++++++++++++ vhosts/blog/nuldoc-src/pages/not_found.ts | 47 --------- vhosts/blog/nuldoc-src/pages/not_found.tsx | 39 +++++++ vhosts/blog/nuldoc-src/pages/post.ts | 145 -------------------------- vhosts/blog/nuldoc-src/pages/post.tsx | 123 ++++++++++++++++++++++ vhosts/blog/nuldoc-src/pages/post_list.ts | 61 ----------- vhosts/blog/nuldoc-src/pages/post_list.tsx | 53 ++++++++++ vhosts/blog/nuldoc-src/pages/slide.ts | 137 ------------------------ vhosts/blog/nuldoc-src/pages/slide.tsx | 110 ++++++++++++++++++++ vhosts/blog/nuldoc-src/pages/slide_list.ts | 62 ----------- vhosts/blog/nuldoc-src/pages/slide_list.tsx | 54 ++++++++++ vhosts/blog/nuldoc-src/pages/tag.ts | 65 ------------ vhosts/blog/nuldoc-src/pages/tag.tsx | 64 ++++++++++++ vhosts/blog/nuldoc-src/pages/tag_list.ts | 85 --------------- vhosts/blog/nuldoc-src/pages/tag_list.tsx | 69 ++++++++++++ vhosts/blog/nuldoc-src/pages/tagged_page.ts | 4 +- 21 files changed, 696 insertions(+), 868 deletions(-) delete mode 100644 vhosts/blog/nuldoc-src/pages/about.ts create mode 100644 vhosts/blog/nuldoc-src/pages/about.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/home.ts create mode 100644 vhosts/blog/nuldoc-src/pages/home.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/not_found.ts create mode 100644 vhosts/blog/nuldoc-src/pages/not_found.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/post.ts create mode 100644 vhosts/blog/nuldoc-src/pages/post.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/post_list.ts create mode 100644 vhosts/blog/nuldoc-src/pages/post_list.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/slide.ts create mode 100644 vhosts/blog/nuldoc-src/pages/slide.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/slide_list.ts create mode 100644 vhosts/blog/nuldoc-src/pages/slide_list.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/tag.ts create mode 100644 vhosts/blog/nuldoc-src/pages/tag.tsx delete mode 100644 vhosts/blog/nuldoc-src/pages/tag_list.ts create mode 100644 vhosts/blog/nuldoc-src/pages/tag_list.tsx (limited to 'vhosts/blog') diff --git a/vhosts/blog/nuldoc-src/atom/generate.ts b/vhosts/blog/nuldoc-src/atom/generate.ts index ee659211..d98c4c18 100644 --- a/vhosts/blog/nuldoc-src/atom/generate.ts +++ b/vhosts/blog/nuldoc-src/atom/generate.ts @@ -2,8 +2,8 @@ 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 { PostPage } from "../pages/post.tsx"; +import { SlidePage } from "../pages/slide.tsx"; import { dateToRfc3339String } from "../revision.ts"; const BASE_NAME = "atom.xml"; diff --git a/vhosts/blog/nuldoc-src/commands/build.ts b/vhosts/blog/nuldoc-src/commands/build.ts index 1ad08825..a542b4f8 100644 --- a/vhosts/blog/nuldoc-src/commands/build.ts +++ b/vhosts/blog/nuldoc-src/commands/build.ts @@ -7,20 +7,20 @@ import { parseNulDocFile } from "../ndoc/parse.ts"; import { Page } from "../page.ts"; import { render } from "../render.ts"; import { dateToString } from "../revision.ts"; -import { generateAboutPage } from "../pages/about.ts"; -import { generateHomePage } from "../pages/home.ts"; -import { generateNotFoundPage } from "../pages/not_found.ts"; +import { generateAboutPage } from "../pages/about.tsx"; +import { generateHomePage } from "../pages/home.tsx"; +import { generateNotFoundPage } from "../pages/not_found.tsx"; import { generatePostPage, getPostPublishedDate, PostPage, -} from "../pages/post.ts"; -import { generatePostListPage } from "../pages/post_list.ts"; -import { generateSlidePage, SlidePage } from "../pages/slide.ts"; -import { generateSlideListPage } from "../pages/slide_list.ts"; -import { generateTagPage, TagPage } from "../pages/tag.ts"; +} from "../pages/post.tsx"; +import { generatePostListPage } from "../pages/post_list.tsx"; +import { generateSlidePage, SlidePage } from "../pages/slide.tsx"; +import { generateSlideListPage } from "../pages/slide_list.tsx"; +import { generateTagPage, TagPage } from "../pages/tag.tsx"; import { TaggedPage } from "../pages/tagged_page.ts"; -import { generateTagListPage } from "../pages/tag_list.ts"; +import { generateTagListPage } from "../pages/tag_list.tsx"; import { parseSlideFile } from "../slide/parse.ts"; export async function runBuildCommand(config: Config) { diff --git a/vhosts/blog/nuldoc-src/pages/about.ts b/vhosts/blog/nuldoc-src/pages/about.ts deleted file mode 100644 index b5411eb7..00000000 --- a/vhosts/blog/nuldoc-src/pages/about.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { staticScriptElement } from "../components/utils.ts"; -import { Config } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; -import { dateToString } from "../revision.ts"; -import { getPostPublishedDate } from "./post.ts"; -import { SlidePage } from "./slide.ts"; - -export type AboutPage = Page; - -export async function generateAboutPage( - slides: SlidePage[], - config: Config, -): Promise { - const body = el( - "body", - { className: "single" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "article", - { className: "post-single" }, - el( - "header", - { className: "post-header" }, - el("h1", { className: "post-title" }, "nsfisis"), - el( - "div", - { className: "my-icon" }, - await staticScriptElement("/p5.min.js", {}, config), - await staticScriptElement("/my-icon.js", {}, config), - el("div", { id: "p5jsMyIcon" }), - el( - "noscript", - {}, - el("img", { src: "/favicon.svg" }), - ), - ), - ), - el( - "div", - { className: "post-content" }, - el( - "section", - {}, - el("h2", {}, "読み方"), - el( - "p", - {}, - "読み方は決めていません。音にする必要があるときは本名である「いまむら」をお使いください。", - ), - ), - el( - "section", - {}, - el("h2", {}, "アカウント"), - el( - "ul", - {}, - el( - "li", - {}, - el( - "a", - { href: "https://twitter.com/nsfisis" }, - "Twitter (現 𝕏): @nsfisis", - ), - ), - el( - "li", - {}, - el( - "a", - { href: "https://github.com/nsfisis" }, - "GitHub: @nsfisis", - ), - ), - ), - ), - el( - "section", - {}, - el("h2", {}, "仕事"), - el( - "ul", - {}, - el( - "li", - {}, - "2021-01~現在: ", - el( - "a", - { href: "https://www.dgcircus.com/" }, - "デジタルサーカス株式会社", - ), - ), - ), - ), - el( - "section", - {}, - el("h2", {}, "登壇"), - el( - "ul", - {}, - ...Array.from(slides).sort((a, b) => { - const ta = dateToString(getPostPublishedDate(a)); - const tb = dateToString(getPostPublishedDate(b)); - if (ta > tb) return -1; - if (ta < tb) return 1; - return 0; - }).map((slide) => - el( - "li", - {}, - el( - "a", - { href: slide.href }, - `${ - dateToString(getPostPublishedDate(slide)) - }: ${slide.event} (${slide.talkType})`, - ), - ) - ), - ), - ), - ), - ), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: config.blog.siteCopyrightYear, - metaDescription: "このサイトの著者について", - metaKeywords: [], - metaTitle: `About|${config.blog.siteName}`, - requiresSyntaxHighlight: false, - }, - body, - config, - ); - - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: "/about/index.html", - href: "/about/", - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/about.tsx b/vhosts/blog/nuldoc-src/pages/about.tsx new file mode 100644 index 00000000..ea74fa32 --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/about.tsx @@ -0,0 +1,106 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import StaticScript from "../components/StaticScript.tsx"; +import { Config } from "../config.ts"; +import { el } from "../dom.ts"; +import { renderToDOM } from "../jsx/render.ts"; +import { Page } from "../page.ts"; +import { dateToString } from "../revision.ts"; +import { getPostPublishedDate } from "./post.tsx"; +import { SlidePage } from "./slide.tsx"; + +export type AboutPage = Page; + +export async function generateAboutPage( + slides: SlidePage[], + config: Config, +): Promise { + const html = await renderToDOM( + + + +
+
+
+

nsfisis

+
+ + +
+ +
+
+
+
+

読み方

+

+ 読み方は決めていません。音にする必要があるときは本名である「いまむら」をお使いください。 +

+
+
+

アカウント

+ +
+
+

仕事

+ +
+
+

登壇

+ +
+
+
+
+ + +
, + ); + + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: "/about/index.html", + href: "/about/", + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/home.ts b/vhosts/blog/nuldoc-src/pages/home.ts deleted file mode 100644 index 86a767c0..00000000 --- a/vhosts/blog/nuldoc-src/pages/home.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { Config } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; - -export type HomePage = Page; - -export async function generateHomePage(config: Config): Promise { - const body = el( - "body", - { className: "single" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "article", - { className: "post-single" }, - el( - "article", - { className: "post-entry" }, - el( - "a", - { href: "/about/" }, - el( - "header", - { className: "entry-header" }, - el("h2", {}, "About"), - ), - ), - ), - el( - "article", - { className: "post-entry" }, - el( - "a", - { href: "/posts/" }, - el( - "header", - { className: "entry-header" }, - el("h2", {}, "Posts"), - ), - ), - ), - el( - "article", - { className: "post-entry" }, - el( - "a", - { href: "/slides/" }, - el( - "header", - { className: "entry-header" }, - el("h2", {}, "Slides"), - ), - ), - ), - el( - "article", - { className: "post-entry" }, - el( - "a", - { href: "/tags/" }, - el( - "header", - { className: "entry-header" }, - el("h2", {}, "Tags"), - ), - ), - ), - ), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: config.blog.siteCopyrightYear, - metaDescription: "nsfisis のブログサイト", - metaKeywords: [], - metaTitle: config.blog.siteName, - metaAtomFeedHref: `https://${config.blog.fqdn}/atom.xml`, - requiresSyntaxHighlight: false, - }, - body, - config, - ); - - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: "/index.html", - href: "/", - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/home.tsx b/vhosts/blog/nuldoc-src/pages/home.tsx new file mode 100644 index 00000000..3e79928a --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/home.tsx @@ -0,0 +1,65 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config } from "../config.ts"; +import { el } from "../dom.ts"; +import { Page } from "../page.ts"; + +export type HomePage = Page; + +export async function generateHomePage(config: Config): Promise { + const html = await renderToDOM( + + + +
+ +
+ + +
, + ); + + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: "/index.html", + href: "/", + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/not_found.ts b/vhosts/blog/nuldoc-src/pages/not_found.ts deleted file mode 100644 index bb70d8ac..00000000 --- a/vhosts/blog/nuldoc-src/pages/not_found.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { Config } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; - -export type NotFoundPage = Page; - -export async function generateNotFoundPage( - config: Config, -): Promise { - const body = el( - "body", - { className: "single" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "article", - {}, - el("div", { className: "not-found" }, "404"), - ), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: config.blog.siteCopyrightYear, - metaDescription: "リクエストされたページが見つかりません", - metaKeywords: [], - metaTitle: `Page Not Found|${config.blog.siteName}`, - requiresSyntaxHighlight: false, - }, - body, - config, - ); - - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: "/404.html", - href: "/404.html", - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/not_found.tsx b/vhosts/blog/nuldoc-src/pages/not_found.tsx new file mode 100644 index 00000000..f0b5f964 --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/not_found.tsx @@ -0,0 +1,39 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config } from "../config.ts"; +import { el } from "../dom.ts"; +import { Page } from "../page.ts"; + +export type NotFoundPage = Page; + +export async function generateNotFoundPage( + config: Config, +): Promise { + const html = await renderToDOM( + + + +
+
+
404
+
+
+ + +
, + ); + + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: "/404.html", + href: "/404.html", + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/post.ts b/vhosts/blog/nuldoc-src/pages/post.ts deleted file mode 100644 index c0c3bb2e..00000000 --- a/vhosts/blog/nuldoc-src/pages/post.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { join } from "std/path/mod.ts"; -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { Config, getTagLabel } from "../config.ts"; -import { el, Element } from "../dom.ts"; -import { Document } from "../ndoc/document.ts"; -import { Page } from "../page.ts"; -import { Date, dateToString, Revision } from "../revision.ts"; - -export interface PostPage extends Page { - title: string; - description: string; - tags: string[]; - revisions: Revision[]; - published: Date; - updated: Date; - uuid: string; -} - -export function getPostPublishedDate(page: { revisions: Revision[] }): Date { - for (const rev of page.revisions) { - if (!rev.isInternal) { - return rev.date; - } - } - return page.revisions[0].date; -} - -export function getPostUpdatedDate(page: { revisions: Revision[] }): Date { - return page.revisions[page.revisions.length - 1].date; -} - -export function postHasAnyUpdates(page: { revisions: Revision[] }): boolean { - return 2 <= page.revisions.filter((rev) => !rev.isInternal).length; -} - -export async function generatePostPage( - doc: Document, - config: Config, -): Promise { - const body = el( - "body", - { className: "single" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "article", - { className: "post-single" }, - el( - "header", - { className: "post-header" }, - el("h1", { className: "post-title" }, doc.title), - ...(doc.tags.length === 0 ? [] : [ - el( - "ul", - { className: "post-tags" }, - ...doc.tags.map((slug) => - el( - "li", - { className: "tag" }, - el( - "a", - { href: `/tags/${slug}/` }, - getTagLabel(config, slug), - ), - ) - ), - ), - ]), - ), - el( - "div", - { className: "post-content" }, - el( - "section", - {}, - el("h2", { id: "changelog" }, "更新履歴"), - el( - "ol", - {}, - ...doc.revisions.map((rev) => - el( - "li", - { className: "revision" }, - el( - "time", - { datetime: dateToString(rev.date) }, - dateToString(rev.date), - ), - `: ${rev.remark}`, - ) - ), - ), - ), - // TODO: refactor - ...(doc.root.children[0] as Element).children, - // TODO: footnotes - //
- // <% for footnote in footnotes %> - //
- // <%= footnote.index %>. <%= footnote.text %> - //
- // <% end %> - //
- ), - ), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: getPostPublishedDate(doc).year, - metaDescription: doc.description, - metaKeywords: doc.tags.map((slug) => getTagLabel(config, slug)), - metaTitle: `${doc.title}|${config.blog.siteName}`, - requiresSyntaxHighlight: true, - }, - body, - config, - ); - - const cwd = Deno.cwd(); - const contentDir = join(cwd, config.locations.contentDir); - const destFilePath = join( - doc.sourceFilePath.replace(contentDir, "").replace(".ndoc", ""), - "index.html", - ); - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: destFilePath, - href: destFilePath.replace("index.html", ""), - title: doc.title, - description: doc.description, - tags: doc.tags, - revisions: doc.revisions, - published: getPostPublishedDate(doc), - updated: getPostUpdatedDate(doc), - uuid: doc.uuid, - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/post.tsx b/vhosts/blog/nuldoc-src/pages/post.tsx new file mode 100644 index 00000000..529d6738 --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/post.tsx @@ -0,0 +1,123 @@ +import { join } from "std/path/mod.ts"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config, getTagLabel } from "../config.ts"; +import { el, Element } from "../dom.ts"; +import { Document } from "../ndoc/document.ts"; +import { Page } from "../page.ts"; +import { Date, dateToString, Revision } from "../revision.ts"; + +export interface PostPage extends Page { + title: string; + description: string; + tags: string[]; + revisions: Revision[]; + published: Date; + updated: Date; + uuid: string; +} + +export function getPostPublishedDate(page: { revisions: Revision[] }): Date { + for (const rev of page.revisions) { + if (!rev.isInternal) { + return rev.date; + } + } + return page.revisions[0].date; +} + +export function getPostUpdatedDate(page: { revisions: Revision[] }): Date { + return page.revisions[page.revisions.length - 1].date; +} + +export function postHasAnyUpdates(page: { revisions: Revision[] }): boolean { + return 2 <= page.revisions.filter((rev) => !rev.isInternal).length; +} + +export async function generatePostPage( + doc: Document, + config: Config, +): Promise { + const html = await renderToDOM( + getTagLabel(config, slug))} + metaTitle={`${doc.title}|${config.blog.siteName}`} + requiresSyntaxHighlight + config={config} + > + + +
+
+
+

{doc.title}

+ {doc.tags.length !== 0 && ( + + )} +
+
+
+

更新履歴

+
    + {doc.revisions.map((rev) => ( +
  1. + + {`: ${rev.remark}`} +
  2. + ))} +
+
+ { + // TODO: refactor + (doc.root.children[0] as Element).children + } + { + // TODO: footnotes + //
+ // <% for footnote in footnotes %> + //
+ // <%= footnote.index %>. <%= footnote.text %> + //
+ // <% end %> + //
+ } +
+
+
+ + +
, + ); + + const cwd = Deno.cwd(); + const contentDir = join(cwd, config.locations.contentDir); + const destFilePath = join( + doc.sourceFilePath.replace(contentDir, "").replace(".ndoc", ""), + "index.html", + ); + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: destFilePath, + href: destFilePath.replace("index.html", ""), + title: doc.title, + description: doc.description, + tags: doc.tags, + revisions: doc.revisions, + published: getPostPublishedDate(doc), + updated: getPostUpdatedDate(doc), + uuid: doc.uuid, + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/post_list.ts b/vhosts/blog/nuldoc-src/pages/post_list.ts deleted file mode 100644 index 40df8ed9..00000000 --- a/vhosts/blog/nuldoc-src/pages/post_list.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { postPageEntry } from "../components/post_page_entry.ts"; -import { Config } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; -import { dateToString } from "../revision.ts"; -import { getPostPublishedDate, PostPage } from "./post.ts"; - -export type PostListPage = Page; - -export async function generatePostListPage( - posts: PostPage[], - config: Config, -): Promise { - const pageTitle = "投稿一覧"; - - const body = el( - "body", - { className: "list" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "header", - { className: "page-header" }, - el("h1", {}, pageTitle), - ), - ...Array.from(posts).sort((a, b) => { - const ta = dateToString(getPostPublishedDate(a)); - const tb = dateToString(getPostPublishedDate(b)); - if (ta > tb) return -1; - if (ta < tb) return 1; - return 0; - }).map((post) => postPageEntry(post)), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: config.blog.siteCopyrightYear, - metaDescription: "投稿した記事の一覧", - metaKeywords: [], - metaTitle: `${pageTitle}|${config.blog.siteName}`, - metaAtomFeedHref: `https://${config.blog.fqdn}/posts/atom.xml`, - requiresSyntaxHighlight: false, - }, - body, - config, - ); - - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: "/posts/index.html", - href: "/posts/", - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/post_list.tsx b/vhosts/blog/nuldoc-src/pages/post_list.tsx new file mode 100644 index 00000000..2d32636f --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/post_list.tsx @@ -0,0 +1,53 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import PostPageEntry from "../components/PostPageEntry.tsx"; +import { Config } from "../config.ts"; +import { el } from "../dom.ts"; +import { Page } from "../page.ts"; +import { dateToString } from "../revision.ts"; +import { getPostPublishedDate, PostPage } from "./post.tsx"; + +export type PostListPage = Page; + +export async function generatePostListPage( + posts: PostPage[], + config: Config, +): Promise { + const pageTitle = "投稿一覧"; + + const html = await renderToDOM( + + + +
+
+

{pageTitle}

+
+ {Array.from(posts).sort((a, b) => { + const ta = dateToString(getPostPublishedDate(a)); + const tb = dateToString(getPostPublishedDate(b)); + if (ta > tb) return -1; + if (ta < tb) return 1; + return 0; + }).map((post) => )} +
+ + +
, + ); + + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: "/posts/index.html", + href: "/posts/", + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/slide.ts b/vhosts/blog/nuldoc-src/pages/slide.ts deleted file mode 100644 index 15a18bb1..00000000 --- a/vhosts/blog/nuldoc-src/pages/slide.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { join } from "std/path/mod.ts"; -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { staticScriptElement } from "../components/utils.ts"; -import { Config, getTagLabel } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; -import { Date, dateToString, Revision } from "../revision.ts"; -import { Slide } from "../slide/slide.ts"; -import { getPostPublishedDate, getPostUpdatedDate } from "./post.ts"; - -export interface SlidePage extends Page { - title: string; - description: string; - event: string; - talkType: string; - slideLink: string; - tags: string[]; - revisions: Revision[]; - published: Date; - updated: Date; - uuid: string; -} - -export async function generateSlidePage( - slide: Slide, - config: Config, -): Promise { - const body = el( - "body", - { className: "single" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "article", - { className: "post-single" }, - el( - "header", - { className: "post-header" }, - el("h1", { className: "post-title" }, slide.title), - ...(slide.tags.length === 0 ? [] : [ - el( - "ul", - { className: "post-tags" }, - ...slide.tags.map((slug) => - el( - "li", - { className: "tag" }, - el( - "a", - { href: `/tags/${slug}/` }, - getTagLabel(config, slug), - ), - ) - ), - ), - ]), - ), - el( - "div", - { className: "post-content" }, - el( - "section", - {}, - el("h2", { id: "changelog" }, "更新履歴"), - el( - "ol", - {}, - ...slide.revisions.map((rev) => - el( - "li", - { className: "revision" }, - el( - "time", - { datetime: dateToString(rev.date) }, - dateToString(rev.date), - ), - `: ${rev.remark}`, - ) - ), - ), - ), - el( - "canvas", - { id: "slide", "data-slide-link": slide.slideLink }, - ), - el( - "div", - {}, - el("button", { id: "prev" }, "Prev"), - el("button", { id: "next" }, "Next"), - ), - await staticScriptElement("/slide.js", { type: "module" }, config), - ), - ), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: getPostPublishedDate(slide).year, - metaDescription: slide.title, - metaKeywords: slide.tags.map((slug) => getTagLabel(config, slug)), - metaTitle: `${slide.event} (${slide.talkType})|${config.blog.siteName}`, - requiresSyntaxHighlight: true, - }, - body, - config, - ); - - const cwd = Deno.cwd(); - const contentDir = join(cwd, config.locations.contentDir); - const destFilePath = join( - slide.sourceFilePath.replace(contentDir, "").replace(".toml", ""), - "index.html", - ); - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: destFilePath, - href: destFilePath.replace("index.html", ""), - title: slide.title, - description: `登壇: ${slide.event} (${slide.talkType})`, - event: slide.event, - talkType: slide.talkType, - slideLink: slide.slideLink, - tags: slide.tags, - revisions: slide.revisions, - published: getPostPublishedDate(slide), - updated: getPostUpdatedDate(slide), - uuid: slide.uuid, - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/slide.tsx b/vhosts/blog/nuldoc-src/pages/slide.tsx new file mode 100644 index 00000000..4165163a --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/slide.tsx @@ -0,0 +1,110 @@ +import { join } from "std/path/mod.ts"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalFooter from "../components/GlobalFooter.tsx"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import StaticScript from "../components/StaticScript.tsx"; +import { Config, getTagLabel } from "../config.ts"; +import { el } from "../dom.ts"; +import { Page } from "../page.ts"; +import { Date, dateToString, Revision } from "../revision.ts"; +import { Slide } from "../slide/slide.ts"; +import { getPostPublishedDate, getPostUpdatedDate } from "./post.tsx"; + +export interface SlidePage extends Page { + title: string; + description: string; + event: string; + talkType: string; + slideLink: string; + tags: string[]; + revisions: Revision[]; + published: Date; + updated: Date; + uuid: string; +} + +export async function generateSlidePage( + slide: Slide, + config: Config, +): Promise { + const html = await renderToDOM( + getTagLabel(config, slug))} + metaTitle={`${slide.event} (${slide.talkType})|${config.blog.siteName}`} + requiresSyntaxHighlight + config={config} + > + + +
+
+
+

{slide.title}

+ {slide.tags.length !== 0 && ( + + )} +
+
+
+

更新履歴

+
    + {slide.revisions.map((rev) => ( +
  1. + + {`: ${rev.remark}`} +
  2. + ))} +
+
+ +
+ + +
+ +
+
+
+ + +
, + ); + + const cwd = Deno.cwd(); + const contentDir = join(cwd, config.locations.contentDir); + const destFilePath = join( + slide.sourceFilePath.replace(contentDir, "").replace(".toml", ""), + "index.html", + ); + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: destFilePath, + href: destFilePath.replace("index.html", ""), + title: slide.title, + description: `登壇: ${slide.event} (${slide.talkType})`, + event: slide.event, + talkType: slide.talkType, + slideLink: slide.slideLink, + tags: slide.tags, + revisions: slide.revisions, + published: getPostPublishedDate(slide), + updated: getPostUpdatedDate(slide), + uuid: slide.uuid, + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/slide_list.ts b/vhosts/blog/nuldoc-src/pages/slide_list.ts deleted file mode 100644 index 53b2d2b1..00000000 --- a/vhosts/blog/nuldoc-src/pages/slide_list.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { slidePageEntry } from "../components/slide_page_entry.ts"; -import { Config } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; -import { dateToString } from "../revision.ts"; -import { getPostPublishedDate } from "./post.ts"; -import { SlidePage } from "./slide.ts"; - -export type SlideListPage = Page; - -export async function generateSlideListPage( - slides: SlidePage[], - config: Config, -): Promise { - const pageTitle = "スライド一覧"; - - const body = el( - "body", - { className: "list" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "header", - { className: "page-header" }, - el("h1", {}, pageTitle), - ), - ...Array.from(slides).sort((a, b) => { - const ta = dateToString(getPostPublishedDate(a)); - const tb = dateToString(getPostPublishedDate(b)); - if (ta > tb) return -1; - if (ta < tb) return 1; - return 0; - }).map((slide) => slidePageEntry(slide)), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: config.blog.siteCopyrightYear, - metaDescription: "登壇したイベントで使用したスライドの一覧", - metaKeywords: [], - metaTitle: `${pageTitle}|${config.blog.siteName}`, - metaAtomFeedHref: `https://${config.blog.fqdn}/slides/atom.xml`, - requiresSyntaxHighlight: false, - }, - body, - config, - ); - - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: "/slides/index.html", - href: "/slides/", - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/slide_list.tsx b/vhosts/blog/nuldoc-src/pages/slide_list.tsx new file mode 100644 index 00000000..31eeca68 --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/slide_list.tsx @@ -0,0 +1,54 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import SlidePageEntry from "../components/SlidePageEntry.tsx"; +import { Config } from "../config.ts"; +import { el } from "../dom.ts"; +import { Page } from "../page.ts"; +import { dateToString } from "../revision.ts"; +import { getPostPublishedDate } from "./post.tsx"; +import { SlidePage } from "./slide.tsx"; + +export type SlideListPage = Page; + +export async function generateSlideListPage( + slides: SlidePage[], + config: Config, +): Promise { + const pageTitle = "スライド一覧"; + + const html = await renderToDOM( + + + +
+
+

{pageTitle}

+
+ {Array.from(slides).sort((a, b) => { + const ta = dateToString(getPostPublishedDate(a)); + const tb = dateToString(getPostPublishedDate(b)); + if (ta > tb) return -1; + if (ta < tb) return 1; + return 0; + }).map((slide) => )} +
+ + +
, + ); + + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: "/slides/index.html", + href: "/slides/", + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/tag.ts b/vhosts/blog/nuldoc-src/pages/tag.ts deleted file mode 100644 index 32711f7e..00000000 --- a/vhosts/blog/nuldoc-src/pages/tag.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { postPageEntry } from "../components/post_page_entry.ts"; -import { slidePageEntry } from "../components/slide_page_entry.ts"; -import { Config, getTagLabel } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; -import { getPostPublishedDate } from "./post.ts"; -import { TaggedPage } from "./tagged_page.ts"; - -export interface TagPage extends Page { - tagSlug: string; - tagLabel: string; - numOfPosts: number; - numOfSlides: number; -} - -export async function generateTagPage( - tagSlug: string, - pages: TaggedPage[], - config: Config, -): Promise { - const tagLabel = getTagLabel(config, tagSlug); - const pageTitle = `タグ「${tagLabel}」一覧`; - - const body = el( - "body", - { className: "list" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el("header", { className: "page-header" }, el("h1", {}, pageTitle)), - ...pages.map((page) => - "event" in page ? slidePageEntry(page) : postPageEntry(page) - ), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: getPostPublishedDate(pages[pages.length - 1]).year, - metaDescription: `タグ「${tagLabel}」のついた記事またはスライドの一覧`, - metaKeywords: [tagLabel], - metaTitle: `${pageTitle}|${config.blog.siteName}`, - metaAtomFeedHref: `https://${config.blog.fqdn}/tags/${tagSlug}/atom.xml`, - requiresSyntaxHighlight: false, - }, - body, - config, - ); - - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: `/tags/${tagSlug}/index.html`, - href: `/tags/${tagSlug}/`, - tagSlug: tagSlug, - tagLabel: tagLabel, - numOfPosts: pages.filter((p) => !("event" in p)).length, - numOfSlides: pages.filter((p) => "event" in p).length, - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/tag.tsx b/vhosts/blog/nuldoc-src/pages/tag.tsx new file mode 100644 index 00000000..8dfc9a39 --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/tag.tsx @@ -0,0 +1,64 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import PostPageEntry from "../components/PostPageEntry.tsx"; +import SlidePageEntry from "../components/SlidePageEntry.tsx"; +import { Config, getTagLabel } from "../config.ts"; +import { el } from "../dom.ts"; +import { Page } from "../page.ts"; +import { getPostPublishedDate } from "./post.tsx"; +import { TaggedPage } from "./tagged_page.ts"; + +export interface TagPage extends Page { + tagSlug: string; + tagLabel: string; + numOfPosts: number; + numOfSlides: number; +} + +export async function generateTagPage( + tagSlug: string, + pages: TaggedPage[], + config: Config, +): Promise { + const tagLabel = getTagLabel(config, tagSlug); + const pageTitle = `タグ「${tagLabel}」一覧`; + + const html = await renderToDOM( + + + +
+
+

{pageTitle}

+
+ {pages.map((page) => + "event" in page + ? + : + )} +
+ + +
, + ); + + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: `/tags/${tagSlug}/index.html`, + href: `/tags/${tagSlug}/`, + tagSlug: tagSlug, + tagLabel: tagLabel, + numOfPosts: pages.filter((p) => !("event" in p)).length, + numOfSlides: pages.filter((p) => "event" in p).length, + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/tag_list.ts b/vhosts/blog/nuldoc-src/pages/tag_list.ts deleted file mode 100644 index 57f6a293..00000000 --- a/vhosts/blog/nuldoc-src/pages/tag_list.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { globalFooter } from "../components/global_footer.ts"; -import { globalHeader } from "../components/global_header.ts"; -import { pageLayout } from "../components/page_layout.ts"; -import { Config } from "../config.ts"; -import { el } from "../dom.ts"; -import { Page } from "../page.ts"; -import { TagPage } from "./tag.ts"; - -export type TagListPage = Page; - -export async function generateTagListPage( - tags: TagPage[], - config: Config, -): Promise { - const pageTitle = "タグ一覧"; - - const body = el( - "body", - { className: "list" }, - globalHeader(config), - el( - "main", - { className: "main" }, - el( - "header", - { className: "page-header" }, - el("h1", {}, pageTitle), - ), - ...Array.from(tags).sort((a, b) => { - const ta = a.tagSlug; - const tb = b.tagSlug; - if (ta < tb) return -1; - if (ta > tb) return 1; - return 0; - }).map((tag) => - el( - "article", - { className: "post-entry" }, - el( - "a", - { href: tag.href }, - el( - "header", - { className: "entry-header" }, - el("h2", {}, tag.tagLabel), - ), - el( - "footer", - { className: "entry-footer" }, - (() => { - const posts = tag.numOfPosts === 0 - ? "" - : `${tag.numOfPosts}件の記事`; - const slides = tag.numOfSlides === 0 - ? "" - : `${tag.numOfSlides}件のスライド`; - return `${posts}${posts && slides ? "、" : ""}${slides}`; - })(), - ), - ), - ) - ), - ), - globalFooter(config), - ); - - const html = await pageLayout( - { - metaCopyrightYear: config.blog.siteCopyrightYear, - metaDescription: "タグの一覧", - metaKeywords: [], - metaTitle: `${pageTitle}|${config.blog.siteName}`, - requiresSyntaxHighlight: false, - }, - body, - config, - ); - - return { - root: el("__root__", {}, html), - renderer: "html", - destFilePath: "/tags/index.html", - href: "/tags/", - }; -} diff --git a/vhosts/blog/nuldoc-src/pages/tag_list.tsx b/vhosts/blog/nuldoc-src/pages/tag_list.tsx new file mode 100644 index 00000000..5ea6f25f --- /dev/null +++ b/vhosts/blog/nuldoc-src/pages/tag_list.tsx @@ -0,0 +1,69 @@ +import GlobalFooter from "../components/GlobalFooter.tsx"; +import { renderToDOM } from "../jsx/render.ts"; +import GlobalHeader from "../components/GlobalHeader.tsx"; +import PageLayout from "../components/PageLayout.tsx"; +import { Config } from "../config.ts"; +import { el } from "../dom.ts"; +import { Page } from "../page.ts"; +import { TagPage } from "./tag.tsx"; + +export type TagListPage = Page; + +export async function generateTagListPage( + tags: TagPage[], + config: Config, +): Promise { + const pageTitle = "タグ一覧"; + + const html = await renderToDOM( + + + +
+
+

{pageTitle}

+
+ {Array.from(tags).sort((a, b) => { + const ta = a.tagSlug; + const tb = b.tagSlug; + if (ta < tb) return -1; + if (ta > tb) return 1; + return 0; + }).map((tag) => ( + + ))} +
+ + +
, + ); + + return { + root: el("__root__", {}, html), + renderer: "html", + destFilePath: "/tags/index.html", + href: "/tags/", + }; +} diff --git a/vhosts/blog/nuldoc-src/pages/tagged_page.ts b/vhosts/blog/nuldoc-src/pages/tagged_page.ts index 23de8cb4..026ca91f 100644 --- a/vhosts/blog/nuldoc-src/pages/tagged_page.ts +++ b/vhosts/blog/nuldoc-src/pages/tagged_page.ts @@ -1,4 +1,4 @@ -import { PostPage } from "./post.ts"; -import { SlidePage } from "./slide.ts"; +import { PostPage } from "./post.tsx"; +import { SlidePage } from "./slide.tsx"; export type TaggedPage = PostPage | SlidePage; -- cgit v1.2.3-70-g09d2