From 93c716f87672d1ba35362ec466b4a47babc9bdfe Mon Sep 17 00:00:00 2001 From: hoelee Date: Sun, 6 Sep 2026 07:31:02 +0800 Subject: [PATCH] Add Pagefind search, sort posts by update time, link DigiKedai bot repo --- package-lock.json | 112 +++++++++- package.json | 5 +- src/components/PostList.astro | 8 + src/components/Search.astro | 201 ++++++++++++++++++ .../how-i-built-the-digikedai-telegram-bot.md | 2 +- src/layouts/BaseLayout.astro | 4 + src/lib/sort.ts | 17 ++ src/pages/categories/[category].astro | 7 +- src/pages/index.astro | 4 +- src/pages/posts/index.astro | 4 +- src/pages/zh/index.astro | 4 +- src/styles/global.css | 14 ++ 12 files changed, 369 insertions(+), 13 deletions(-) create mode 100644 src/components/Search.astro create mode 100644 src/lib/sort.ts diff --git a/package-lock.json b/package-lock.json index 7931a1f..71a2677 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "@astrojs/sitemap": "^3.7.4", "@fontsource-variable/inter": "^5.3.0", "@fontsource/jetbrains-mono": "^5.3.0", - "astro": "^5.5.0" + "astro": "^5.5.0", + "pagefind": "^1.5.2" } }, "node_modules/@astrojs/compiler": { @@ -1184,6 +1185,97 @@ "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", "license": "MIT" }, + "node_modules/@pagefind/darwin-arm64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.5.2.tgz", + "integrity": "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/darwin-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.5.2.tgz", + "integrity": "sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/freebsd-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.5.2.tgz", + "integrity": "sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@pagefind/linux-arm64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.5.2.tgz", + "integrity": "sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/linux-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.5.2.tgz", + "integrity": "sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/windows-arm64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/windows-arm64/-/windows-arm64-1.5.2.tgz", + "integrity": "sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@pagefind/windows-x64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.5.2.tgz", + "integrity": "sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/pluginutils": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", @@ -4028,6 +4120,24 @@ "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", "license": "MIT" }, + "node_modules/pagefind": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.5.2.tgz", + "integrity": "sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==", + "license": "MIT", + "bin": { + "pagefind": "lib/runner/bin.cjs" + }, + "optionalDependencies": { + "@pagefind/darwin-arm64": "1.5.2", + "@pagefind/darwin-x64": "1.5.2", + "@pagefind/freebsd-x64": "1.5.2", + "@pagefind/linux-arm64": "1.5.2", + "@pagefind/linux-x64": "1.5.2", + "@pagefind/windows-arm64": "1.5.2", + "@pagefind/windows-x64": "1.5.2" + } + }, "node_modules/parse-latin": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", diff --git a/package.json b/package.json index 1d98aac..4ce1d03 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "private": true, "scripts": { "dev": "astro dev", - "build": "astro build", + "build": "astro build && pagefind --site dist", "preview": "astro preview", "astro": "astro" }, @@ -14,6 +14,7 @@ "@astrojs/sitemap": "^3.7.4", "@fontsource-variable/inter": "^5.3.0", "@fontsource/jetbrains-mono": "^5.3.0", - "astro": "^5.5.0" + "astro": "^5.5.0", + "pagefind": "^1.5.2" } } diff --git a/src/components/PostList.astro b/src/components/PostList.astro index 1ca16d9..9c14a5c 100644 --- a/src/components/PostList.astro +++ b/src/components/PostList.astro @@ -19,6 +19,14 @@ const fmt = (d: Date) =>

{post.data.title}

+ {post.data.updatedDate && ( + <> + · + + Updated {fmt(post.data.updatedDate)} + + + )} · {post.data.category} {post.data.tags.map((t) => {t})} diff --git a/src/components/Search.astro b/src/components/Search.astro new file mode 100644 index 0000000..5cb45d8 --- /dev/null +++ b/src/components/Search.astro @@ -0,0 +1,201 @@ +--- +// Client-side search via Pagefind. The search box lives in the site header; +// this component is mounted once per page (in BaseLayout) and drives the +// overlay + results. Pagefind's index is generated post-build (see the build +// script); its UI/JS loads from /pagefind/ at runtime. +interface Props { + lang: string; +} +const { lang } = Astro.props; +const placeholder = + lang === 'zh' ? '搜索文章…' : 'Search posts…'; +const noResults = + lang === 'zh' ? '没有匹配的结果。' : 'No results.'; +--- + + + + + + diff --git a/src/content/posts/how-i-built-the-digikedai-telegram-bot.md b/src/content/posts/how-i-built-the-digikedai-telegram-bot.md index 1c1917b..5742a70 100644 --- a/src/content/posts/how-i-built-the-digikedai-telegram-bot.md +++ b/src/content/posts/how-i-built-the-digikedai-telegram-bot.md @@ -153,7 +153,7 @@ One container on the NAS now answers customer questions across two channels language, and issues free-trial accounts end-to-end — with a prompt suite of ~175 unit tests covering the deterministic flows, retrieval, and the payload contracts. The source lives at -[git.hoelee.com/hoelee/dsm-resource-management](https://git.hoelee.com/hoelee/dsm-resource-management). +[git.hoelee.com/hoelee/digikedai-bot](https://git.hoelee.com/hoelee/digikedai-bot). If you're building your own Telegram bot backed by an LLM, the lesson is the boring one: the model is the easy part. The webhook lifecycle, the payload diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 12fa6ad..0bc3b1b 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -3,6 +3,7 @@ import '../styles/global.css'; import '@fontsource-variable/inter'; import '@fontsource/jetbrains-mono/400.css'; import { SITE } from '../config'; +import Search from '../components/Search.astro'; interface Props { title: string; @@ -137,6 +138,7 @@ const nav = isZh {nav.categories} {nav.about} {nav.rss} + {switchLabel} @@ -156,6 +158,8 @@ const nav = isZh + +