diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/og/[slug].png.ts | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/pages/og/[slug].png.ts b/src/pages/og/[slug].png.ts index 712a39f..67a4d7c 100644 --- a/src/pages/og/[slug].png.ts +++ b/src/pages/og/[slug].png.ts @@ -1,6 +1,9 @@ import satori from "satori"; import { Resvg } from "@resvg/resvg-js"; -import { readFileSync } from "node:fs"; +import { readFileSync, existsSync, readdirSync } from "node:fs"; +import path from "node:path"; + +const contentDir = "src/content/docs"; const pages: Record<string, string> = { index: "だれもがしあわせに暮らせるまちへ", @@ -22,8 +25,45 @@ const pages: Record<string, string> = { "ippan-situmon": "一般質問", }; +function findMdxFiles(dir: string): string[] { + if (!existsSync(dir)) return []; + const files: string[] = []; + for (const entry of readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".") || entry.name.startsWith("_")) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) files.push(...findMdxFiles(full)); + else if (entry.name.endsWith(".mdx")) files.push(full); + } + return files; +} + +function readTitle(filePath: string): string | null { + try { + const content = readFileSync(filePath, "utf-8"); + const m = + content.match(/^title:\s*"(.+?)"/m) ?? content.match(/^title:\s*(.+)/m); + return m?.[1] ?? null; + } catch { + return null; + } +} + export async function getStaticPaths() { - return Object.keys(pages).map((slug) => ({ params: { slug } })); + const slugs = new Set<string>(); + // Manual pages + for (const s of Object.keys(pages)) slugs.add(s); + // Auto-discover ippan-situmon pages + for (const f of findMdxFiles(path.join(contentDir, "ippan-situmon"))) { + const s = f + .replace(/\\/g, "/") + .replace(contentDir + "/", "") + .replace(/\.mdx$/, "") + .replace(/\/index$/, ""); + if (s) slugs.add(s); + } + return [...slugs] + .filter((s) => s.length > 0) + .map((slug) => ({ params: { slug: slug.replace(/\//g, "-") } })); } const fontBuffer = readFileSync("node_modules/.noto-sans-jp.otf"); @@ -72,7 +112,13 @@ const stars = [ export async function GET({ params }: { params: { slug: string } }) { const slug = params.slug; - const title = pages[slug] ?? "小平市議 安竹洋平 公式サイト"; + // Convert - back to / for nested paths + const fileSlug = slug.replace(/-/g, "/"); + let title = pages[fileSlug]; + if (!title) { + const mdxPath = path.join(contentDir, fileSlug + ".mdx"); + title = readTitle(mdxPath) ?? "小平市議 安竹洋平 公式サイト"; + } const svg = await satori( { |
