aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/nuldoc/nuldoc-src/pages
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-11-27 04:02:06 +0900
committernsfisis <nsfisis@gmail.com>2025-11-27 04:02:06 +0900
commitd1014de68415df8f0a5dc3389332e086119c6198 (patch)
tree6564411eb6381eb48f86ed2b658c5440295596fa /services/nuldoc/nuldoc-src/pages
parentb587ae4cfdfb991dcd9d7a1109b7530f774691dd (diff)
downloadnsfisis.dev-d1014de68415df8f0a5dc3389332e086119c6198.tar.gz
nsfisis.dev-d1014de68415df8f0a5dc3389332e086119c6198.tar.zst
nsfisis.dev-d1014de68415df8f0a5dc3389332e086119c6198.zip
refactor(nuldoc): eliminate JSX
Diffstat (limited to 'services/nuldoc/nuldoc-src/pages')
-rw-r--r--services/nuldoc/nuldoc-src/pages/AboutPage.ts160
-rw-r--r--services/nuldoc/nuldoc-src/pages/AboutPage.tsx113
-rw-r--r--services/nuldoc/nuldoc-src/pages/AtomPage.ts27
-rw-r--r--services/nuldoc/nuldoc-src/pages/AtomPage.tsx26
-rw-r--r--services/nuldoc/nuldoc-src/pages/HomePage.ts78
-rw-r--r--services/nuldoc/nuldoc-src/pages/HomePage.tsx54
-rw-r--r--services/nuldoc/nuldoc-src/pages/NotFoundPage.ts40
-rw-r--r--services/nuldoc/nuldoc-src/pages/NotFoundPage.tsx38
-rw-r--r--services/nuldoc/nuldoc-src/pages/PostListPage.ts49
-rw-r--r--services/nuldoc/nuldoc-src/pages/PostListPage.tsx58
-rw-r--r--services/nuldoc/nuldoc-src/pages/PostPage.ts90
-rw-r--r--services/nuldoc/nuldoc-src/pages/PostPage.tsx71
-rw-r--r--services/nuldoc/nuldoc-src/pages/SlideListPage.ts45
-rw-r--r--services/nuldoc/nuldoc-src/pages/SlideListPage.tsx45
-rw-r--r--services/nuldoc/nuldoc-src/pages/SlidePage.ts98
-rw-r--r--services/nuldoc/nuldoc-src/pages/SlidePage.tsx73
-rw-r--r--services/nuldoc/nuldoc-src/pages/TagListPage.ts70
-rw-r--r--services/nuldoc/nuldoc-src/pages/TagListPage.tsx62
-rw-r--r--services/nuldoc/nuldoc-src/pages/TagPage.ts50
-rw-r--r--services/nuldoc/nuldoc-src/pages/TagPage.tsx50
20 files changed, 707 insertions, 590 deletions
diff --git a/services/nuldoc/nuldoc-src/pages/AboutPage.ts b/services/nuldoc/nuldoc-src/pages/AboutPage.ts
new file mode 100644
index 0000000..43e239e
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/AboutPage.ts
@@ -0,0 +1,160 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import GlobalHeader from "../components/AboutGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import StaticScript from "../components/StaticScript.ts";
+import { Config } from "../config.ts";
+import { dateToString } from "../revision.ts";
+import { getPostPublishedDate } from "../generators/post.ts";
+import { SlidePage } from "../generators/slide.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function AboutPage(
+ slides: SlidePage[],
+ config: Config,
+): Promise<Element> {
+ return await PageLayout({
+ metaCopyrightYear: config.site.copyrightYear,
+ metaDescription: "このサイトの著者について",
+ metaTitle: `About|${config.sites.about.siteName}`,
+ site: "about",
+ config,
+ children: elem(
+ "body",
+ { class: "single" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem(
+ "article",
+ { class: "post-single" },
+ elem(
+ "header",
+ { class: "post-header" },
+ elem("h1", { class: "post-title" }, "nsfisis"),
+ elem(
+ "div",
+ { class: "my-icon" },
+ elem(
+ "div",
+ { id: "myIcon" },
+ elem("img", { src: "/favicon.svg" }),
+ ),
+ await StaticScript({
+ fileName: "/my-icon.js",
+ defer: "true",
+ config,
+ }),
+ ),
+ ),
+ elem(
+ "div",
+ { class: "post-content" },
+ elem(
+ "section",
+ {},
+ elem("h2", {}, "読み方"),
+ elem(
+ "p",
+ {},
+ "読み方は決めていません。音にする必要があるときは本名である「いまむら」をお使いください。",
+ ),
+ ),
+ elem(
+ "section",
+ {},
+ elem("h2", {}, "アカウント"),
+ elem(
+ "ul",
+ {},
+ elem(
+ "li",
+ {},
+ elem(
+ "a",
+ {
+ href: "https://twitter.com/nsfisis",
+ target: "_blank",
+ rel: "noreferrer",
+ },
+ "Twitter (現 𝕏): @nsfisis",
+ ),
+ ),
+ elem(
+ "li",
+ {},
+ elem(
+ "a",
+ {
+ href: "https://github.com/nsfisis",
+ target: "_blank",
+ rel: "noreferrer",
+ },
+ "GitHub: @nsfisis",
+ ),
+ ),
+ ),
+ ),
+ elem(
+ "section",
+ {},
+ elem("h2", {}, "仕事"),
+ elem(
+ "ul",
+ {},
+ elem(
+ "li",
+ {},
+ "2021-01~現在: ",
+ elem(
+ "a",
+ {
+ href: "https://www.dgcircus.com/",
+ target: "_blank",
+ rel: "noreferrer",
+ },
+ "デジタルサーカス株式会社",
+ ),
+ ),
+ ),
+ ),
+ elem(
+ "section",
+ {},
+ elem("h2", {}, "登壇"),
+ elem(
+ "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) =>
+ elem(
+ "li",
+ {},
+ elem(
+ "a",
+ {
+ href:
+ `https://${config.sites.slides.fqdn}${slide.href}`,
+ },
+ `${
+ dateToString(getPostPublishedDate(slide))
+ }: ${slide.event} (${slide.talkType})`,
+ ),
+ )
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/AboutPage.tsx b/services/nuldoc/nuldoc-src/pages/AboutPage.tsx
deleted file mode 100644
index d0397c1..0000000
--- a/services/nuldoc/nuldoc-src/pages/AboutPage.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import GlobalHeader from "../components/AboutGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import StaticScript from "../components/StaticScript.tsx";
-import { Config } from "../config.ts";
-import { dateToString } from "../revision.ts";
-import { getPostPublishedDate } from "../generators/post.ts";
-import { SlidePage } from "../generators/slide.ts";
-
-export default function AboutPage(
- slides: SlidePage[],
- config: Config,
-) {
- return (
- <PageLayout
- metaCopyrightYear={config.site.copyrightYear}
- metaDescription="このサイトの著者について"
- metaTitle={`About|${config.sites.about.siteName}`}
- site="about"
- config={config}
- >
- <body className="single">
- <GlobalHeader config={config} />
- <main className="main">
- <article className="post-single">
- <header className="post-header">
- <h1 className="post-title">nsfisis</h1>
- <div className="my-icon">
- <div id="myIcon">
- <img src="/favicon.svg" />
- </div>
- <StaticScript
- fileName="/my-icon.js"
- defer="true"
- config={config}
- />
- </div>
- </header>
- <div className="post-content">
- <section>
- <h2>読み方</h2>
- <p>
- 読み方は決めていません。音にする必要があるときは本名である「いまむら」をお使いください。
- </p>
- </section>
- <section>
- <h2>アカウント</h2>
- <ul>
- <li>
- <a
- href="https://twitter.com/nsfisis"
- target="_blank"
- rel="noreferrer"
- >
- Twitter (現 𝕏): @nsfisis
- </a>
- </li>
- <li>
- <a
- href="https://github.com/nsfisis"
- target="_blank"
- rel="noreferrer"
- >
- GitHub: @nsfisis
- </a>
- </li>
- </ul>
- </section>
- <section>
- <h2>仕事</h2>
- <ul>
- <li>
- {"2021-01~現在: "}
- <a
- href="https://www.dgcircus.com/"
- target="_blank"
- rel="noreferrer"
- >
- デジタルサーカス株式会社
- </a>
- </li>
- </ul>
- </section>
- <section>
- <h2>登壇</h2>
- <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) => (
- <li>
- <a
- href={`https://${config.sites.slides.fqdn}${slide.href}`}
- >
- {`${
- dateToString(getPostPublishedDate(slide))
- }: ${slide.event} (${slide.talkType})`}
- </a>
- </li>
- ))}
- </ul>
- </section>
- </div>
- </article>
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/AtomPage.ts b/services/nuldoc/nuldoc-src/pages/AtomPage.ts
new file mode 100644
index 0000000..f270972
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/AtomPage.ts
@@ -0,0 +1,27 @@
+import { Feed } from "../generators/atom.ts";
+import { elem, Element } from "../dom.ts";
+
+export default function AtomPage({ feed }: { feed: Feed }): Element {
+ return elem(
+ "feed",
+ { xmlns: "http://www.w3.org/2005/Atom" },
+ elem("id", {}, feed.id),
+ elem("title", {}, feed.title),
+ elem("link", { rel: "alternate", href: feed.linkToAlternate }),
+ elem("link", { rel: "self", href: feed.linkToSelf }),
+ elem("author", {}, elem("name", {}, feed.author)),
+ elem("updated", {}, feed.updated),
+ ...feed.entries.map((entry) =>
+ elem(
+ "entry",
+ {},
+ elem("id", {}, entry.id),
+ elem("link", { rel: "alternate", href: entry.linkToAlternate }),
+ elem("title", {}, entry.title),
+ elem("summary", {}, entry.summary),
+ elem("published", {}, entry.published),
+ elem("updated", {}, entry.updated),
+ )
+ ),
+ );
+}
diff --git a/services/nuldoc/nuldoc-src/pages/AtomPage.tsx b/services/nuldoc/nuldoc-src/pages/AtomPage.tsx
deleted file mode 100644
index 21c3bfa..0000000
--- a/services/nuldoc/nuldoc-src/pages/AtomPage.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Feed } from "../generators/atom.ts";
-
-export default function AtomPage({ feed }: { feed: Feed }) {
- return (
- <feed xmlns="http://www.w3.org/2005/Atom">
- <id>{feed.id}</id>
- <title>{feed.title}</title>
- <link rel="alternate" href={feed.linkToAlternate} />
- <link rel="self" href={feed.linkToSelf} />
- <author>
- <name>{feed.author}</name>
- </author>
- <updated>{feed.updated}</updated>
- {feed.entries.map((entry) => (
- <entry>
- <id>{entry.id}</id>
- <link rel="alternate" href={entry.linkToAlternate} />
- <title>{entry.title}</title>
- <summary>{entry.summary}</summary>
- <published>{entry.published}</published>
- <updated>{entry.updated}</updated>
- </entry>
- ))}
- </feed>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/HomePage.ts b/services/nuldoc/nuldoc-src/pages/HomePage.ts
new file mode 100644
index 0000000..503a382
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/HomePage.ts
@@ -0,0 +1,78 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import GlobalHeader from "../components/DefaultGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import { Config } from "../config.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function HomePage(config: Config): Promise<Element> {
+ return await PageLayout({
+ metaCopyrightYear: config.site.copyrightYear,
+ metaDescription: "nsfisis のサイト",
+ metaTitle: config.sites.default.siteName,
+ metaAtomFeedHref: `https://${config.sites.default.fqdn}/atom.xml`,
+ site: "default",
+ config,
+ children: elem(
+ "body",
+ { class: "single" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem(
+ "article",
+ { class: "post-single" },
+ elem(
+ "article",
+ { class: "post-entry" },
+ elem(
+ "a",
+ { href: `https://${config.sites.about.fqdn}/` },
+ elem(
+ "header",
+ { class: "entry-header" },
+ elem("h2", {}, "About"),
+ ),
+ ),
+ ),
+ elem(
+ "article",
+ { class: "post-entry" },
+ elem(
+ "a",
+ { href: `https://${config.sites.blog.fqdn}/posts/` },
+ elem("header", { class: "entry-header" }, elem("h2", {}, "Blog")),
+ ),
+ ),
+ elem(
+ "article",
+ { class: "post-entry" },
+ elem(
+ "a",
+ { href: `https://${config.sites.slides.fqdn}/slides/` },
+ elem(
+ "header",
+ { class: "entry-header" },
+ elem("h2", {}, "Slides"),
+ ),
+ ),
+ ),
+ elem(
+ "article",
+ { class: "post-entry" },
+ elem(
+ "a",
+ { href: `https://repos.${config.sites.default.fqdn}/` },
+ elem(
+ "header",
+ { class: "entry-header" },
+ elem("h2", {}, "Repositories"),
+ ),
+ ),
+ ),
+ ),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/HomePage.tsx b/services/nuldoc/nuldoc-src/pages/HomePage.tsx
deleted file mode 100644
index a2cbdd1..0000000
--- a/services/nuldoc/nuldoc-src/pages/HomePage.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import GlobalHeader from "../components/DefaultGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import { Config } from "../config.ts";
-
-export default function HomePage(config: Config) {
- return (
- <PageLayout
- metaCopyrightYear={config.site.copyrightYear}
- metaDescription="nsfisis のサイト"
- metaTitle={config.sites.default.siteName}
- metaAtomFeedHref={`https://${config.sites.default.fqdn}/atom.xml`}
- site="default"
- config={config}
- >
- <body className="single">
- <GlobalHeader config={config} />
- <main className="main">
- <article className="post-single">
- <article className="post-entry">
- <a href={`https://${config.sites.about.fqdn}/`}>
- <header className="entry-header">
- <h2>About</h2>
- </header>
- </a>
- </article>
- <article className="post-entry">
- <a href={`https://${config.sites.blog.fqdn}/posts/`}>
- <header className="entry-header">
- <h2>Blog</h2>
- </header>
- </a>
- </article>
- <article className="post-entry">
- <a href={`https://${config.sites.slides.fqdn}/slides/`}>
- <header className="entry-header">
- <h2>Slides</h2>
- </header>
- </a>
- </article>
- <article className="post-entry">
- <a href={`https://repos.${config.sites.default.fqdn}/`}>
- <header className="entry-header">
- <h2>Repositories</h2>
- </header>
- </a>
- </article>
- </article>
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/NotFoundPage.ts b/services/nuldoc/nuldoc-src/pages/NotFoundPage.ts
new file mode 100644
index 0000000..34854c4
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/NotFoundPage.ts
@@ -0,0 +1,40 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import AboutGlobalHeader from "../components/AboutGlobalHeader.ts";
+import BlogGlobalHeader from "../components/BlogGlobalHeader.ts";
+import SlidesGlobalHeader from "../components/SlidesGlobalHeader.ts";
+import DefaultGlobalHeader from "../components/DefaultGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import { Config } from "../config.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function NotFoundPage(
+ site: "default" | "about" | "blog" | "slides",
+ config: Config,
+): Promise<Element> {
+ const GlobalHeader = site === "about"
+ ? AboutGlobalHeader
+ : site === "blog"
+ ? BlogGlobalHeader
+ : site === "slides"
+ ? SlidesGlobalHeader
+ : DefaultGlobalHeader;
+
+ return await PageLayout({
+ metaCopyrightYear: config.site.copyrightYear,
+ metaDescription: "リクエストされたページが見つかりません",
+ metaTitle: `Page Not Found|${config.sites[site].siteName}`,
+ site,
+ config,
+ children: elem(
+ "body",
+ { class: "single" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem("article", {}, elem("div", { class: "not-found" }, "404")),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/NotFoundPage.tsx b/services/nuldoc/nuldoc-src/pages/NotFoundPage.tsx
deleted file mode 100644
index 11ce518..0000000
--- a/services/nuldoc/nuldoc-src/pages/NotFoundPage.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import AboutGlobalHeader from "../components/AboutGlobalHeader.tsx";
-import BlogGlobalHeader from "../components/BlogGlobalHeader.tsx";
-import SlidesGlobalHeader from "../components/SlidesGlobalHeader.tsx";
-import DefaultGlobalHeader from "../components/DefaultGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import { Config } from "../config.ts";
-
-export default function NotFoundPage(
- site: "default" | "about" | "blog" | "slides",
- config: Config,
-) {
- return (
- <PageLayout
- metaCopyrightYear={config.site.copyrightYear}
- metaDescription="リクエストされたページが見つかりません"
- metaTitle={`Page Not Found|${config.sites[site].siteName}`}
- site={site}
- config={config}
- >
- <body className="single">
- {site === "about"
- ? <AboutGlobalHeader config={config} />
- : site === "blog"
- ? <BlogGlobalHeader config={config} />
- : site === "slides"
- ? <SlidesGlobalHeader config={config} />
- : <DefaultGlobalHeader config={config} />}
- <main className="main">
- <article>
- <div className="not-found">404</div>
- </article>
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/PostListPage.ts b/services/nuldoc/nuldoc-src/pages/PostListPage.ts
new file mode 100644
index 0000000..53b8fa4
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/PostListPage.ts
@@ -0,0 +1,49 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import GlobalHeader from "../components/BlogGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import Pagination from "../components/Pagination.ts";
+import PostPageEntry from "../components/PostPageEntry.ts";
+import { Config } from "../config.ts";
+import { PostPage } from "../generators/post.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function PostListPage(
+ posts: PostPage[],
+ config: Config,
+ currentPage: number,
+ totalPages: number,
+): Promise<Element> {
+ const pageTitle = "投稿一覧";
+
+ const pageInfoSuffix = ` (${currentPage}ページ目)`;
+ const metaTitle =
+ `${pageTitle}${pageInfoSuffix}|${config.sites.blog.siteName}`;
+ const metaDescription = `投稿した記事の一覧${pageInfoSuffix}`;
+
+ return await PageLayout({
+ metaCopyrightYear: config.site.copyrightYear,
+ metaDescription,
+ metaTitle,
+ metaAtomFeedHref: `https://${config.sites.blog.fqdn}/posts/atom.xml`,
+ site: "blog",
+ config,
+ children: elem(
+ "body",
+ { class: "list" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem(
+ "header",
+ { class: "page-header" },
+ elem("h1", {}, pageTitle + pageInfoSuffix),
+ ),
+ Pagination({ currentPage, totalPages, basePath: "/posts/" }),
+ ...posts.map((post) => PostPageEntry({ post, config })),
+ Pagination({ currentPage, totalPages, basePath: "/posts/" }),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/PostListPage.tsx b/services/nuldoc/nuldoc-src/pages/PostListPage.tsx
deleted file mode 100644
index 5ed9696..0000000
--- a/services/nuldoc/nuldoc-src/pages/PostListPage.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import GlobalHeader from "../components/BlogGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import Pagination from "../components/Pagination.tsx";
-import PostPageEntry from "../components/PostPageEntry.tsx";
-import { Config } from "../config.ts";
-import { PostPage } from "../generators/post.ts";
-
-export default function PostListPage(
- posts: PostPage[],
- config: Config,
- currentPage: number,
- totalPages: number,
-) {
- const pageTitle = "投稿一覧";
-
- const pageInfoSuffix = ` (${currentPage}ページ目)`;
- const metaTitle =
- `${pageTitle}${pageInfoSuffix}|${config.sites.blog.siteName}`;
- const metaDescription = `投稿した記事の一覧${pageInfoSuffix}`;
-
- return (
- <PageLayout
- metaCopyrightYear={config.site.copyrightYear}
- metaDescription={metaDescription}
- metaTitle={metaTitle}
- metaAtomFeedHref={`https://${config.sites.blog.fqdn}/posts/atom.xml`}
- site="blog"
- config={config}
- >
- <body className="list">
- <GlobalHeader config={config} />
- <main className="main">
- <header className="page-header">
- <h1>{pageTitle}{pageInfoSuffix}</h1>
- </header>
-
- <Pagination
- currentPage={currentPage}
- totalPages={totalPages}
- basePath="/posts/"
- />
-
- {posts.map((post) => (
- <PostPageEntry post={post} config={config} key={post.uuid} />
- ))}
-
- <Pagination
- currentPage={currentPage}
- totalPages={totalPages}
- basePath="/posts/"
- />
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/PostPage.ts b/services/nuldoc/nuldoc-src/pages/PostPage.ts
new file mode 100644
index 0000000..84f58c3
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/PostPage.ts
@@ -0,0 +1,90 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import GlobalHeader from "../components/BlogGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import TableOfContents from "../components/TableOfContents.ts";
+import { Config, getTagLabel } from "../config.ts";
+import { elem, Element } from "../dom.ts";
+import { Document } from "../djot/document.ts";
+import { dateToString } from "../revision.ts";
+import { getPostPublishedDate } from "../generators/post.ts";
+
+export default async function PostPage(
+ doc: Document,
+ config: Config,
+): Promise<Element> {
+ return await PageLayout({
+ metaCopyrightYear: getPostPublishedDate(doc).year,
+ metaDescription: doc.description,
+ metaKeywords: doc.tags.map((slug) => getTagLabel(config, slug)),
+ metaTitle: `${doc.title}|${config.sites.blog.siteName}`,
+ requiresSyntaxHighlight: true,
+ site: "blog",
+ config,
+ children: elem(
+ "body",
+ { class: "single" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem(
+ "article",
+ { class: "post-single" },
+ elem(
+ "header",
+ { class: "post-header" },
+ elem("h1", { class: "post-title" }, doc.title),
+ doc.tags.length !== 0
+ ? elem(
+ "ul",
+ { class: "post-tags" },
+ ...doc.tags.map((slug) =>
+ elem(
+ "li",
+ { class: "tag" },
+ elem(
+ "a",
+ { href: `/tags/${slug}/` },
+ getTagLabel(config, slug),
+ ),
+ )
+ ),
+ )
+ : null,
+ ),
+ doc.toc && doc.toc.entries.length > 0
+ ? TableOfContents({ toc: doc.toc })
+ : null,
+ elem(
+ "div",
+ { class: "post-content" },
+ elem(
+ "section",
+ { id: "changelog" },
+ elem("h2", {}, elem("a", { href: "#changelog" }, "更新履歴")),
+ elem(
+ "ol",
+ {},
+ ...doc.revisions.map((rev) =>
+ elem(
+ "li",
+ { class: "revision" },
+ elem(
+ "time",
+ { datetime: dateToString(rev.date) },
+ dateToString(rev.date),
+ ),
+ `: ${rev.remark}`,
+ )
+ ),
+ ),
+ ),
+ // TODO: refactor
+ ...(doc.root.children[0] as Element).children,
+ ),
+ ),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/PostPage.tsx b/services/nuldoc/nuldoc-src/pages/PostPage.tsx
deleted file mode 100644
index beebdb3..0000000
--- a/services/nuldoc/nuldoc-src/pages/PostPage.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import GlobalHeader from "../components/BlogGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import TableOfContents from "../components/TableOfContents.tsx";
-import { Config, getTagLabel } from "../config.ts";
-import { Element } from "../dom.ts";
-import { Document } from "../djot/document.ts";
-import { dateToString } from "../revision.ts";
-import { getPostPublishedDate } from "../generators/post.ts";
-
-export default function PostPage(
- doc: Document,
- config: Config,
-) {
- return (
- <PageLayout
- metaCopyrightYear={getPostPublishedDate(doc).year}
- metaDescription={doc.description}
- metaKeywords={doc.tags.map((slug) => getTagLabel(config, slug))}
- metaTitle={`${doc.title}|${config.sites.blog.siteName}`}
- requiresSyntaxHighlight
- site="blog"
- config={config}
- >
- <body className="single">
- <GlobalHeader config={config} />
- <main className="main">
- <article className="post-single">
- <header className="post-header">
- <h1 className="post-title">{doc.title}</h1>
- {doc.tags.length !== 0 && (
- <ul className="post-tags">
- {doc.tags.map((slug) => (
- <li className="tag">
- <a href={`/tags/${slug}/`}>{getTagLabel(config, slug)}</a>
- </li>
- ))}
- </ul>
- )}
- </header>
- {doc.toc && doc.toc.entries.length > 0 && (
- <TableOfContents toc={doc.toc} />
- )}
- <div className="post-content">
- <section id="changelog">
- <h2>
- <a href="#changelog">更新履歴</a>
- </h2>
- <ol>
- {doc.revisions.map((rev) => (
- <li className="revision">
- <time datetime={dateToString(rev.date)}>
- {dateToString(rev.date)}
- </time>
- {`: ${rev.remark}`}
- </li>
- ))}
- </ol>
- </section>
- {
- // TODO: refactor
- (doc.root.children[0] as Element).children
- }
- </div>
- </article>
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/SlideListPage.ts b/services/nuldoc/nuldoc-src/pages/SlideListPage.ts
new file mode 100644
index 0000000..9a1c2b2
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/SlideListPage.ts
@@ -0,0 +1,45 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import GlobalHeader from "../components/SlidesGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import SlidePageEntry from "../components/SlidePageEntry.ts";
+import { Config } from "../config.ts";
+import { dateToString } from "../revision.ts";
+import { getPostPublishedDate } from "../generators/post.ts";
+import { SlidePage } from "../generators/slide.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function SlideListPage(
+ slides: SlidePage[],
+ config: Config,
+): Promise<Element> {
+ const pageTitle = "スライド一覧";
+
+ return await PageLayout({
+ metaCopyrightYear: config.site.copyrightYear,
+ metaDescription: "登壇したイベントで使用したスライドの一覧",
+ metaTitle: `${pageTitle}|${config.sites.slides.siteName}`,
+ metaAtomFeedHref: `https://${config.sites.slides.fqdn}/slides/atom.xml`,
+ site: "slides",
+ config,
+ children: elem(
+ "body",
+ { class: "list" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem("header", { class: "page-header" }, elem("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, config })),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/SlideListPage.tsx b/services/nuldoc/nuldoc-src/pages/SlideListPage.tsx
deleted file mode 100644
index dc216eb..0000000
--- a/services/nuldoc/nuldoc-src/pages/SlideListPage.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import GlobalHeader from "../components/SlidesGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import SlidePageEntry from "../components/SlidePageEntry.tsx";
-import { Config } from "../config.ts";
-import { dateToString } from "../revision.ts";
-import { getPostPublishedDate } from "../generators/post.ts";
-import { SlidePage } from "../generators/slide.ts";
-
-export default function SlideListPage(
- slides: SlidePage[],
- config: Config,
-) {
- const pageTitle = "スライド一覧";
-
- return (
- <PageLayout
- metaCopyrightYear={config.site.copyrightYear}
- metaDescription="登壇したイベントで使用したスライドの一覧"
- metaTitle={`${pageTitle}|${config.sites.slides.siteName}`}
- metaAtomFeedHref={`https://${config.sites.slides.fqdn}/slides/atom.xml`}
- site="slides"
- config={config}
- >
- <body className="list">
- <GlobalHeader config={config} />
- <main className="main">
- <header className="page-header">
- <h1>{pageTitle}</h1>
- </header>
- {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={slide} config={config} key={slide.uuid} />
- ))}
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/SlidePage.ts b/services/nuldoc/nuldoc-src/pages/SlidePage.ts
new file mode 100644
index 0000000..8699134
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/SlidePage.ts
@@ -0,0 +1,98 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import GlobalHeader from "../components/SlidesGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import StaticScript from "../components/StaticScript.ts";
+import { Config, getTagLabel } from "../config.ts";
+import { dateToString } from "../revision.ts";
+import { Slide } from "../slide/slide.ts";
+import { getPostPublishedDate } from "../generators/post.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function SlidePage(
+ slide: Slide,
+ config: Config,
+): Promise<Element> {
+ return await PageLayout({
+ metaCopyrightYear: getPostPublishedDate(slide).year,
+ metaDescription: slide.title,
+ metaKeywords: slide.tags.map((slug) => getTagLabel(config, slug)),
+ metaTitle:
+ `${slide.event} (${slide.talkType})|${config.sites.slides.siteName}`,
+ requiresSyntaxHighlight: true,
+ site: "slides",
+ config,
+ children: elem(
+ "body",
+ { class: "single" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem(
+ "article",
+ { class: "post-single" },
+ elem(
+ "header",
+ { class: "post-header" },
+ elem("h1", { class: "post-title" }, slide.title),
+ slide.tags.length !== 0
+ ? elem(
+ "ul",
+ { class: "post-tags" },
+ ...slide.tags.map((slug) =>
+ elem(
+ "li",
+ { class: "tag" },
+ elem(
+ "a",
+ { href: `/tags/${slug}/` },
+ getTagLabel(config, slug),
+ ),
+ )
+ ),
+ )
+ : null,
+ ),
+ elem(
+ "div",
+ { class: "post-content" },
+ elem(
+ "section",
+ { id: "changelog" },
+ elem("h2", {}, elem("a", { href: "#changelog" }, "更新履歴")),
+ elem(
+ "ol",
+ {},
+ ...slide.revisions.map((rev) =>
+ elem(
+ "li",
+ { class: "revision" },
+ elem(
+ "time",
+ { datetime: dateToString(rev.date) },
+ dateToString(rev.date),
+ ),
+ `: ${rev.remark}`,
+ )
+ ),
+ ),
+ ),
+ elem("canvas", { id: "slide", "data-slide-link": slide.slideLink }),
+ elem(
+ "div",
+ {},
+ elem("button", { id: "prev", type: "button" }, "Prev"),
+ elem("button", { id: "next", type: "button" }, "Next"),
+ ),
+ await StaticScript({
+ fileName: "/slide.js",
+ type: "module",
+ config,
+ }),
+ ),
+ ),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/SlidePage.tsx b/services/nuldoc/nuldoc-src/pages/SlidePage.tsx
deleted file mode 100644
index 53944df..0000000
--- a/services/nuldoc/nuldoc-src/pages/SlidePage.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import GlobalHeader from "../components/SlidesGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import StaticScript from "../components/StaticScript.tsx";
-import { Config, getTagLabel } from "../config.ts";
-import { dateToString } from "../revision.ts";
-import { Slide } from "../slide/slide.ts";
-import { getPostPublishedDate } from "../generators/post.ts";
-
-export default function SlidePage(
- slide: Slide,
- config: Config,
-) {
- return (
- <PageLayout
- metaCopyrightYear={getPostPublishedDate(slide).year}
- metaDescription={slide.title}
- metaKeywords={slide.tags.map((slug) => getTagLabel(config, slug))}
- metaTitle={`${slide.event} (${slide.talkType})|${config.sites.slides.siteName}`}
- requiresSyntaxHighlight
- site="slides"
- config={config}
- >
- <body className="single">
- <GlobalHeader config={config} />
- <main className="main">
- <article className="post-single">
- <header className="post-header">
- <h1 className="post-title">{slide.title}</h1>
- {slide.tags.length !== 0 && (
- <ul className="post-tags">
- {slide.tags.map((slug) => (
- <li className="tag">
- <a href={`/tags/${slug}/`}>{getTagLabel(config, slug)}</a>
- </li>
- ))}
- </ul>
- )}
- </header>
- <div className="post-content">
- <section id="changelog">
- <h2>
- <a href="#changelog">更新履歴</a>
- </h2>
- <ol>
- {slide.revisions.map((rev) => (
- <li className="revision">
- <time datetime={dateToString(rev.date)}>
- {dateToString(rev.date)}
- </time>
- {`: ${rev.remark}`}
- </li>
- ))}
- </ol>
- </section>
- <canvas id="slide" data-slide-link={slide.slideLink} />
- <div>
- <button id="prev" type="button">Prev</button>
- <button id="next" type="button">Next</button>
- </div>
- <StaticScript
- fileName="/slide.js"
- type="module"
- config={config}
- />
- </div>
- </article>
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/TagListPage.ts b/services/nuldoc/nuldoc-src/pages/TagListPage.ts
new file mode 100644
index 0000000..6872a2f
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/TagListPage.ts
@@ -0,0 +1,70 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import BlogGlobalHeader from "../components/BlogGlobalHeader.ts";
+import SlidesGlobalHeader from "../components/SlidesGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import { Config } from "../config.ts";
+import { TagPage } from "../generators/tag.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function TagListPage(
+ tags: TagPage[],
+ site: "blog" | "slides",
+ config: Config,
+): Promise<Element> {
+ const pageTitle = "タグ一覧";
+
+ const GlobalHeader = site === "blog" ? BlogGlobalHeader : SlidesGlobalHeader;
+
+ return await PageLayout({
+ metaCopyrightYear: config.site.copyrightYear,
+ metaDescription: "タグの一覧",
+ metaTitle: `${pageTitle}|${config.sites[site].siteName}`,
+ site,
+ config,
+ children: elem(
+ "body",
+ { class: "list" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem("header", { class: "page-header" }, elem("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) => {
+ const posts = tag.numOfPosts === 0
+ ? ""
+ : `${tag.numOfPosts}件の記事`;
+ const slides = tag.numOfSlides === 0
+ ? ""
+ : `${tag.numOfSlides}件のスライド`;
+ const footerText = `${posts}${
+ posts && slides ? "、" : ""
+ }${slides}`;
+
+ return elem(
+ "article",
+ { class: "post-entry" },
+ elem(
+ "a",
+ { href: tag.href },
+ elem(
+ "header",
+ { class: "entry-header" },
+ elem("h2", {}, tag.tagLabel),
+ ),
+ elem("footer", { class: "entry-footer" }, footerText),
+ ),
+ );
+ }),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/TagListPage.tsx b/services/nuldoc/nuldoc-src/pages/TagListPage.tsx
deleted file mode 100644
index 3ee58f3..0000000
--- a/services/nuldoc/nuldoc-src/pages/TagListPage.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import BlogGlobalHeader from "../components/BlogGlobalHeader.tsx";
-import SlidesGlobalHeader from "../components/SlidesGlobalHeader.tsx";
-import PageLayout from "../components/PageLayout.tsx";
-import { Config } from "../config.ts";
-import { TagPage } from "../generators/tag.ts";
-
-export default function TagListPage(
- tags: TagPage[],
- site: "blog" | "slides",
- config: Config,
-) {
- const pageTitle = "タグ一覧";
-
- return (
- <PageLayout
- metaCopyrightYear={config.site.copyrightYear}
- metaDescription="タグの一覧"
- metaTitle={`${pageTitle}|${config.sites[site].siteName}`}
- site={site}
- config={config}
- >
- <body className="list">
- {site === "blog"
- ? <BlogGlobalHeader config={config} />
- : <SlidesGlobalHeader config={config} />}
- <main className="main">
- <header className="page-header">
- <h1>{pageTitle}</h1>
- </header>
- {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) => (
- <article className="post-entry">
- <a href={tag.href}>
- <header className="entry-header">
- <h2>{tag.tagLabel}</h2>
- </header>
- <footer className="entry-footer">
- {(() => {
- const posts = tag.numOfPosts === 0
- ? ""
- : `${tag.numOfPosts}件の記事`;
- const slides = tag.numOfSlides === 0
- ? ""
- : `${tag.numOfSlides}件のスライド`;
- return `${posts}${posts && slides ? "、" : ""}${slides}`;
- })()}
- </footer>
- </a>
- </article>
- ))}
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}
diff --git a/services/nuldoc/nuldoc-src/pages/TagPage.ts b/services/nuldoc/nuldoc-src/pages/TagPage.ts
new file mode 100644
index 0000000..408f0b4
--- /dev/null
+++ b/services/nuldoc/nuldoc-src/pages/TagPage.ts
@@ -0,0 +1,50 @@
+import GlobalFooter from "../components/GlobalFooter.ts";
+import BlogGlobalHeader from "../components/BlogGlobalHeader.ts";
+import SlidesGlobalHeader from "../components/SlidesGlobalHeader.ts";
+import PageLayout from "../components/PageLayout.ts";
+import PostPageEntry from "../components/PostPageEntry.ts";
+import SlidePageEntry from "../components/SlidePageEntry.ts";
+import { Config, getTagLabel } from "../config.ts";
+import { getPostPublishedDate } from "../generators/post.ts";
+import { TaggedPage } from "../generators/tagged_page.ts";
+import { elem, Element } from "../dom.ts";
+
+export default async function TagPage(
+ tagSlug: string,
+ pages: TaggedPage[],
+ site: "blog" | "slides",
+ config: Config,
+): Promise<Element> {
+ const tagLabel = getTagLabel(config, tagSlug);
+ const pageTitle = `タグ「${tagLabel}」一覧`;
+
+ const GlobalHeader = site === "blog" ? BlogGlobalHeader : SlidesGlobalHeader;
+
+ return await PageLayout({
+ metaCopyrightYear: getPostPublishedDate(pages[pages.length - 1]).year,
+ metaDescription: `タグ「${tagLabel}」のついた記事またはスライドの一覧`,
+ metaKeywords: [tagLabel],
+ metaTitle: `${pageTitle}|${config.sites[site].siteName}`,
+ metaAtomFeedHref: `https://${
+ config.sites[site].fqdn
+ }/tags/${tagSlug}/atom.xml`,
+ site,
+ config,
+ children: elem(
+ "body",
+ { class: "list" },
+ GlobalHeader({ config }),
+ elem(
+ "main",
+ { class: "main" },
+ elem("header", { class: "page-header" }, elem("h1", {}, pageTitle)),
+ ...pages.map((page) =>
+ "event" in page
+ ? SlidePageEntry({ slide: page, config })
+ : PostPageEntry({ post: page, config })
+ ),
+ ),
+ GlobalFooter({ config }),
+ ),
+ });
+}
diff --git a/services/nuldoc/nuldoc-src/pages/TagPage.tsx b/services/nuldoc/nuldoc-src/pages/TagPage.tsx
deleted file mode 100644
index 6c64172..0000000
--- a/services/nuldoc/nuldoc-src/pages/TagPage.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import GlobalFooter from "../components/GlobalFooter.tsx";
-import BlogGlobalHeader from "../components/BlogGlobalHeader.tsx";
-import SlidesGlobalHeader from "../components/SlidesGlobalHeader.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 { getPostPublishedDate } from "../generators/post.ts";
-import { TaggedPage } from "../generators/tagged_page.ts";
-
-export default function TagPage(
- tagSlug: string,
- pages: TaggedPage[],
- site: "blog" | "slides",
- config: Config,
-) {
- const tagLabel = getTagLabel(config, tagSlug);
- const pageTitle = `タグ「${tagLabel}」一覧`;
-
- return (
- <PageLayout
- metaCopyrightYear={getPostPublishedDate(pages[pages.length - 1]).year}
- metaDescription={`タグ「${tagLabel}」のついた記事またはスライドの一覧`}
- metaKeywords={[tagLabel]}
- metaTitle={`${pageTitle}|${config.sites[site].siteName}`}
- metaAtomFeedHref={`https://${
- config.sites[site].fqdn
- }/tags/${tagSlug}/atom.xml`}
- site={site}
- config={config}
- >
- <body className="list">
- {site === "blog"
- ? <BlogGlobalHeader config={config} />
- : <SlidesGlobalHeader config={config} />}
- <main className="main">
- <header className="page-header">
- <h1>{pageTitle}</h1>
- </header>
- {pages.map((page) =>
- "event" in page
- ? <SlidePageEntry slide={page} config={config} key={page.uuid} />
- : <PostPageEntry post={page} config={config} key={page.uuid} />
- )}
- </main>
- <GlobalFooter config={config} />
- </body>
- </PageLayout>
- );
-}