diff options
| author | nsfisis <nsfisis@gmail.com> | 2023-03-18 18:53:05 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2023-03-18 18:53:05 +0900 |
| commit | 71aba3df235dc9a8acbee0e33980b30ba4ce44d4 (patch) | |
| tree | 3e9b3b047b71f3293e399d21c5eb1bc252544c1b /nuldoc-src/components/page_layout.ts | |
| parent | 12035272d44d92cd2360aeff88d499db67fe1949 (diff) | |
| download | blog.nsfisis.dev-71aba3df235dc9a8acbee0e33980b30ba4ce44d4.tar.gz blog.nsfisis.dev-71aba3df235dc9a8acbee0e33980b30ba4ce44d4.tar.zst blog.nsfisis.dev-71aba3df235dc9a8acbee0e33980b30ba4ce44d4.zip | |
refactor: add components/*.ts for shared components
Diffstat (limited to 'nuldoc-src/components/page_layout.ts')
| -rw-r--r-- | nuldoc-src/components/page_layout.ts | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/nuldoc-src/components/page_layout.ts b/nuldoc-src/components/page_layout.ts new file mode 100644 index 0000000..d76e3b2 --- /dev/null +++ b/nuldoc-src/components/page_layout.ts @@ -0,0 +1,89 @@ +import { crypto, toHashString } from "std/crypto/mod.ts"; +import { join } from "std/path/mod.ts"; +import { Config } from "../config.ts"; +import { el, Element, text } from "../dom.ts"; + +type Params = { + metaCopyrightYear: number; + metaDescription: string; + metaKeywords: string[]; + metaTitle: string; + requiresSyntaxHighlight: boolean; +}; + +export async function pageLayout( + { + metaCopyrightYear, + metaDescription, + metaKeywords, + metaTitle, + 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", + `© ${metaCopyrightYear} ${config.blog.author}`, + ]]), + metaElement([["name", "description"], [ + "content", + metaDescription, + ]]), + ...(metaKeywords.length === 0 ? [] : [ + metaElement([["name", "keywords"], [ + "content", + metaKeywords.join(","), + ]]), + ]), + linkElement("icon", "/favicon.svg", "image/svg+xml"), + el("title", [], text(`${metaTitle} | ${config.blog.siteName}`)), + await stylesheetLinkElement("/style.css", config), + ...( + requiresSyntaxHighlight + ? [await stylesheetLinkElement("/hl.css", config)] + : [] + ), + ); + return el( + "html", + [["lang", "ja-JP"]], + head, + body, + ); +} + +async function stylesheetLinkElement( + fileName: string, + config: Config, +): Promise<Element> { + const filePath = join(Deno.cwd(), config.locations.staticDir, fileName); + const content = (await Deno.readFile(filePath)).buffer; + const hash = toHashString(await crypto.subtle.digest("MD5", content), "hex"); + return el("link", [["rel", "stylesheet"], ["href", `${fileName}?h=${hash}`]]); +} + +function metaElement(attrs: [string, string][]): Element { + return el("meta", attrs); +} + +function linkElement( + rel: string, + href: string, + type: string | null, +): Element { + const attrs: [string, string][] = [["rel", rel], ["href", href]]; + if (type !== null) { + attrs.push(["type", type]); + } + return el("link", attrs); +} |
