summaryrefslogtreecommitdiffhomepage
path: root/vhosts/blog/nuldoc-src/components
diff options
context:
space:
mode:
Diffstat (limited to 'vhosts/blog/nuldoc-src/components')
-rw-r--r--vhosts/blog/nuldoc-src/components/GlobalFooter.tsx9
-rw-r--r--vhosts/blog/nuldoc-src/components/GlobalHeader.tsx27
-rw-r--r--vhosts/blog/nuldoc-src/components/PageLayout.tsx63
-rw-r--r--vhosts/blog/nuldoc-src/components/PostPageEntry.tsx39
-rw-r--r--vhosts/blog/nuldoc-src/components/SlidePageEntry.tsx39
-rw-r--r--vhosts/blog/nuldoc-src/components/StaticScript.tsx17
-rw-r--r--vhosts/blog/nuldoc-src/components/StaticStylesheet.tsx11
-rw-r--r--vhosts/blog/nuldoc-src/components/global_footer.ts10
-rw-r--r--vhosts/blog/nuldoc-src/components/global_header.ts26
-rw-r--r--vhosts/blog/nuldoc-src/components/page_layout.ts82
-rw-r--r--vhosts/blog/nuldoc-src/components/post_page_entry.ts50
-rw-r--r--vhosts/blog/nuldoc-src/components/slide_page_entry.ts50
-rw-r--r--vhosts/blog/nuldoc-src/components/utils.ts24
13 files changed, 206 insertions, 241 deletions
diff --git a/vhosts/blog/nuldoc-src/components/GlobalFooter.tsx b/vhosts/blog/nuldoc-src/components/GlobalFooter.tsx
new file mode 100644
index 00000000..757beced
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/components/GlobalFooter.tsx
@@ -0,0 +1,9 @@
+import { Config } from "../config.ts";
+
+export default function GlobalFooter({ config }: { config: Config }) {
+ return (
+ <footer className="footer">
+ {`&copy; ${config.blog.siteCopyrightYear} ${config.blog.author}`}
+ </footer>
+ );
+}
diff --git a/vhosts/blog/nuldoc-src/components/GlobalHeader.tsx b/vhosts/blog/nuldoc-src/components/GlobalHeader.tsx
new file mode 100644
index 00000000..c0fa7e8b
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/components/GlobalHeader.tsx
@@ -0,0 +1,27 @@
+import { Config } from "../config.ts";
+
+export default function GlobalHeader({ config }: { config: Config }) {
+ return (
+ <header className="header">
+ <div className="site-logo">
+ <a href="/">{config.blog.siteName}</a>
+ </div>
+ <nav className="nav">
+ <ul>
+ <li>
+ <a href="/about/">About</a>
+ </li>
+ <li>
+ <a href="/posts/">Posts</a>
+ </li>
+ <li>
+ <a href="/slides/">Slides</a>
+ </li>
+ <li>
+ <a href="/tags/">Tags</a>
+ </li>
+ </ul>
+ </nav>
+ </header>
+ );
+}
diff --git a/vhosts/blog/nuldoc-src/components/PageLayout.tsx b/vhosts/blog/nuldoc-src/components/PageLayout.tsx
new file mode 100644
index 00000000..c7145e0a
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/components/PageLayout.tsx
@@ -0,0 +1,63 @@
+import { Config } from "../config.ts";
+import { JSXNode } from "myjsx/jsx-runtime";
+import StaticStylesheet from "./StaticStylesheet.tsx";
+
+type Props = {
+ metaCopyrightYear: number;
+ metaDescription: string;
+ metaKeywords?: string[];
+ metaTitle: string;
+ metaAtomFeedHref?: string;
+ requiresSyntaxHighlight?: boolean;
+ config: Config;
+ children: JSXNode;
+};
+
+export default function PageLayout(
+ {
+ metaCopyrightYear,
+ metaDescription,
+ metaKeywords,
+ metaTitle,
+ metaAtomFeedHref,
+ requiresSyntaxHighlight,
+ config,
+ children,
+ }: Props,
+) {
+ return (
+ <html lang="ja-JP">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="author" content={config.blog.author} />
+ <meta
+ name="copyright"
+ content={`&copy; ${metaCopyrightYear} ${config.blog.author}`}
+ />
+ <meta name="description" content={metaDescription} />
+ {metaKeywords && metaKeywords.length !== 0 &&
+ <meta name="keywords" content={metaKeywords.join(",")} />}
+ <meta property="og:type" content="article" />
+ <meta property="og:title" content={metaTitle} />
+ <meta property="og:description" content={metaDescription} />
+ <meta property="og:site_name" content={config.blog.siteName} />
+ <meta property="og:locale" content="ja_JP" />
+ {metaAtomFeedHref &&
+ (
+ <link
+ rel="alternate"
+ href={metaAtomFeedHref}
+ type="application/atom+xml"
+ />
+ )}
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
+ <title>{metaTitle}</title>
+ <StaticStylesheet fileName="/style.css" config={config} />
+ {requiresSyntaxHighlight &&
+ <StaticStylesheet fileName="/hl.css" config={config} />}
+ </head>
+ {children}
+ </html>
+ );
+}
diff --git a/vhosts/blog/nuldoc-src/components/PostPageEntry.tsx b/vhosts/blog/nuldoc-src/components/PostPageEntry.tsx
new file mode 100644
index 00000000..2708b009
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/components/PostPageEntry.tsx
@@ -0,0 +1,39 @@
+import {
+ getPostPublishedDate,
+ getPostUpdatedDate,
+ postHasAnyUpdates,
+ PostPage,
+} from "../generators/post.ts";
+import { dateToString } from "../revision.ts";
+
+export default function PostPageEntry({ post }: { post: PostPage }) {
+ return (
+ <article className="post-entry">
+ <a href={post.href}>
+ <header className="entry-header">
+ <h2>{post.title}</h2>
+ </header>
+ <section className="entry-content">
+ <p>{post.description}</p>
+ </section>
+ <footer className="entry-footer">
+ <time datetime={dateToString(getPostPublishedDate(post))}>
+ {dateToString(getPostPublishedDate(post))}
+ </time>
+ {" 投稿"}
+ {
+ // TODO(jsx): support Fragment and merge them.
+ postHasAnyUpdates(post) && "、"
+ }
+ {postHasAnyUpdates(post) &&
+ (
+ <time datetime={dateToString(getPostUpdatedDate(post))}>
+ {dateToString(getPostUpdatedDate(post))}
+ </time>
+ )}
+ {postHasAnyUpdates(post) && " 更新"}
+ </footer>
+ </a>
+ </article>
+ );
+}
diff --git a/vhosts/blog/nuldoc-src/components/SlidePageEntry.tsx b/vhosts/blog/nuldoc-src/components/SlidePageEntry.tsx
new file mode 100644
index 00000000..d2cf9a17
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/components/SlidePageEntry.tsx
@@ -0,0 +1,39 @@
+import {
+ getPostPublishedDate,
+ getPostUpdatedDate,
+ postHasAnyUpdates,
+} from "../generators/post.ts";
+import { SlidePage } from "../generators/slide.ts";
+import { dateToString } from "../revision.ts";
+
+export default function SlidePageEntry({ slide }: { slide: SlidePage }) {
+ return (
+ <article className="post-entry">
+ <a href={slide.href}>
+ <header className="entry-header">
+ <h2>{slide.description}</h2>
+ </header>
+ <section className="entry-content">
+ <p>{slide.title}</p>
+ </section>
+ <footer className="entry-footer">
+ <time datetime={dateToString(getPostPublishedDate(slide))}>
+ {dateToString(getPostPublishedDate(slide))}
+ </time>
+ {" 登壇"}
+ {
+ // TODO(jsx): support Fragment and merge them.
+ postHasAnyUpdates(slide) && "、"
+ }
+ {postHasAnyUpdates(slide) &&
+ (
+ <time datetime={dateToString(getPostUpdatedDate(slide))}>
+ {dateToString(getPostUpdatedDate(slide))}
+ </time>
+ )}
+ {postHasAnyUpdates(slide) && " 更新"}
+ </footer>
+ </a>
+ </article>
+ );
+}
diff --git a/vhosts/blog/nuldoc-src/components/StaticScript.tsx b/vhosts/blog/nuldoc-src/components/StaticScript.tsx
new file mode 100644
index 00000000..eb26ada7
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/components/StaticScript.tsx
@@ -0,0 +1,17 @@
+import { join } from "std/path/mod.ts";
+import { Config } from "../config.ts";
+import { calculateFileHash } from "./utils.ts";
+
+export default async function StaticScript(
+ { fileName, type, config }: {
+ fileName: string;
+ type?: string;
+ config: Config;
+ },
+) {
+ const filePath = join(Deno.cwd(), config.locations.staticDir, fileName);
+ const hash = await calculateFileHash(filePath);
+ return (
+ <script src={`${fileName}?h=${hash}`} {...(type ? { type } : {})}></script>
+ );
+}
diff --git a/vhosts/blog/nuldoc-src/components/StaticStylesheet.tsx b/vhosts/blog/nuldoc-src/components/StaticStylesheet.tsx
new file mode 100644
index 00000000..5c2c2a0f
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/components/StaticStylesheet.tsx
@@ -0,0 +1,11 @@
+import { join } from "std/path/mod.ts";
+import { Config } from "../config.ts";
+import { calculateFileHash } from "./utils.ts";
+
+export default async function StaticStylesheet(
+ { fileName, config }: { fileName: string; config: Config },
+) {
+ const filePath = join(Deno.cwd(), config.locations.staticDir, fileName);
+ const hash = await calculateFileHash(filePath);
+ return <link rel="stylesheet" href={`${fileName}?h=${hash}`} />;
+}
diff --git a/vhosts/blog/nuldoc-src/components/global_footer.ts b/vhosts/blog/nuldoc-src/components/global_footer.ts
deleted file mode 100644
index 7fdc8797..00000000
--- a/vhosts/blog/nuldoc-src/components/global_footer.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Config } from "../config.ts";
-import { el, Element } from "../dom.ts";
-
-export function globalFooter(config: Config): Element {
- return el(
- "footer",
- { className: "footer" },
- `&copy; ${config.blog.siteCopyrightYear} ${config.blog.author}`,
- );
-}
diff --git a/vhosts/blog/nuldoc-src/components/global_header.ts b/vhosts/blog/nuldoc-src/components/global_header.ts
deleted file mode 100644
index 166c48ff..00000000
--- a/vhosts/blog/nuldoc-src/components/global_header.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Config } from "../config.ts";
-import { el, Element } from "../dom.ts";
-
-export function globalHeader(config: Config): Element {
- return el(
- "header",
- { className: "header" },
- el(
- "div",
- { className: "site-logo" },
- el("a", { href: "/" }, config.blog.siteName),
- ),
- el(
- "nav",
- { className: "nav" },
- el(
- "ul",
- {},
- el("li", {}, el("a", { href: "/about/" }, "About")),
- el("li", {}, el("a", { href: "/posts/" }, "Posts")),
- el("li", {}, el("a", { href: "/slides/" }, "Slides")),
- el("li", {}, el("a", { href: "/tags/" }, "Tags")),
- ),
- ),
- );
-}
diff --git a/vhosts/blog/nuldoc-src/components/page_layout.ts b/vhosts/blog/nuldoc-src/components/page_layout.ts
deleted file mode 100644
index a6b75d01..00000000
--- a/vhosts/blog/nuldoc-src/components/page_layout.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { Config } from "../config.ts";
-import { el, Element } from "../dom.ts";
-import { stylesheetLinkElement } from "./utils.ts";
-
-type Params = {
- metaCopyrightYear: number;
- metaDescription: string;
- metaKeywords: string[];
- metaTitle: string;
- metaAtomFeedHref?: string;
- requiresSyntaxHighlight: boolean;
-};
-
-export async function pageLayout(
- {
- metaCopyrightYear,
- metaDescription,
- metaKeywords,
- metaTitle,
- metaAtomFeedHref,
- requiresSyntaxHighlight,
- }: Params,
- body: Element,
- config: Config,
-): Promise<Element> {
- 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: `&copy; ${metaCopyrightYear} ${config.blog.author}`,
- }),
- metaElement({ name: "description", content: metaDescription }),
- ...(metaKeywords.length === 0 ? [] : [
- metaElement({ name: "keywords", content: metaKeywords.join(",") }),
- ]),
- metaElement({ property: "og:type", content: "article" }),
- metaElement({ property: "og:title", content: metaTitle }),
- metaElement({ property: "og:description", content: metaDescription }),
- metaElement({ property: "og:site_name", content: config.blog.siteName }),
- metaElement({ property: "og:locale", content: "ja_JP" }),
- ...(metaAtomFeedHref
- ? [linkElement("alternate", metaAtomFeedHref, "application/atom+xml")]
- : []),
- linkElement("icon", "/favicon.svg", "image/svg+xml"),
- el("title", {}, metaTitle),
- await stylesheetLinkElement("/style.css", config),
- ...(
- requiresSyntaxHighlight
- ? [await stylesheetLinkElement("/hl.css", config)]
- : []
- ),
- );
- return el(
- "html",
- { lang: "ja-JP" },
- head,
- body,
- );
-}
-
-function metaElement(attrs: Record<string, string>): Element {
- return el("meta", attrs);
-}
-
-function linkElement(
- rel: string,
- href: string,
- type: string | null,
-): Element {
- const attrs: Record<string, string> = { rel: rel, href: href };
- if (type !== null) {
- attrs.type = type;
- }
- return el("link", attrs);
-}
diff --git a/vhosts/blog/nuldoc-src/components/post_page_entry.ts b/vhosts/blog/nuldoc-src/components/post_page_entry.ts
deleted file mode 100644
index bd82eb95..00000000
--- a/vhosts/blog/nuldoc-src/components/post_page_entry.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { el, Element } from "../dom.ts";
-import {
- getPostPublishedDate,
- getPostUpdatedDate,
- postHasAnyUpdates,
- PostPage,
-} from "../pages/post.ts";
-import { dateToString } from "../revision.ts";
-
-export function postPageEntry(post: PostPage): Element {
- return el(
- "article",
- { className: "post-entry" },
- el(
- "a",
- { href: post.href },
- el(
- "header",
- { className: "entry-header" },
- el("h2", {}, post.title),
- ),
- el(
- "section",
- { className: "entry-content" },
- el("p", {}, post.description),
- ),
- el(
- "footer",
- { className: "entry-footer" },
- el(
- "time",
- { datetime: dateToString(getPostPublishedDate(post)) },
- dateToString(getPostPublishedDate(post)),
- ),
- " 投稿",
- ...(postHasAnyUpdates(post)
- ? [
- "、",
- el(
- "time",
- { "datetime": dateToString(getPostUpdatedDate(post)) },
- dateToString(getPostUpdatedDate(post)),
- ),
- " 更新",
- ]
- : []),
- ),
- ),
- );
-}
diff --git a/vhosts/blog/nuldoc-src/components/slide_page_entry.ts b/vhosts/blog/nuldoc-src/components/slide_page_entry.ts
deleted file mode 100644
index e64a4022..00000000
--- a/vhosts/blog/nuldoc-src/components/slide_page_entry.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { el, Element } from "../dom.ts";
-import {
- getPostPublishedDate,
- getPostUpdatedDate,
- postHasAnyUpdates,
-} from "../pages/post.ts";
-import { SlidePage } from "../pages/slide.ts";
-import { dateToString } from "../revision.ts";
-
-export function slidePageEntry(slide: SlidePage): Element {
- return el(
- "article",
- { className: "post-entry" },
- el(
- "a",
- { href: slide.href },
- el(
- "header",
- { className: "entry-header" },
- el("h2", {}, slide.description),
- ),
- el(
- "section",
- { className: "entry-content" },
- el("p", {}, slide.title),
- ),
- el(
- "footer",
- { className: "entry-footer" },
- el(
- "time",
- { datetime: dateToString(getPostPublishedDate(slide)) },
- dateToString(getPostPublishedDate(slide)),
- ),
- " 登壇",
- ...(postHasAnyUpdates(slide)
- ? [
- "、",
- el(
- "time",
- { "datetime": dateToString(getPostUpdatedDate(slide)) },
- dateToString(getPostUpdatedDate(slide)),
- ),
- " 更新",
- ]
- : []),
- ),
- ),
- );
-}
diff --git a/vhosts/blog/nuldoc-src/components/utils.ts b/vhosts/blog/nuldoc-src/components/utils.ts
index ce693100..14059b5b 100644
--- a/vhosts/blog/nuldoc-src/components/utils.ts
+++ b/vhosts/blog/nuldoc-src/components/utils.ts
@@ -1,28 +1,6 @@
import { Hash } from "checksum/mod.ts";
-import { join } from "std/path/mod.ts";
-import { Config } from "../config.ts";
-import { el, Element } from "../dom.ts";
-export async function stylesheetLinkElement(
- fileName: string,
- config: Config,
-): Promise<Element> {
- const filePath = join(Deno.cwd(), config.locations.staticDir, fileName);
- const hash = await calculateFileHash(filePath);
- return el("link", { rel: "stylesheet", href: `${fileName}?h=${hash}` });
-}
-
-export async function staticScriptElement(
- fileName: string,
- attrs: Record<string, string>,
- config: Config,
-): Promise<Element> {
- const filePath = join(Deno.cwd(), config.locations.staticDir, fileName);
- const hash = await calculateFileHash(filePath);
- return el("script", { src: `${fileName}?h=${hash}`, ...attrs });
-}
-
-async function calculateFileHash(
+export async function calculateFileHash(
filePath: string,
): Promise<string> {
const content = await Deno.readFile(filePath);