Add per-post banners (16:9 hero images) + banner-gen script; add banner to all posts
Deploy / build (push) Successful in 37s

This commit is contained in:
2026-09-09 06:33:13 +08:00
parent ca650f69c0
commit 3a00a2d517
33 changed files with 1245 additions and 0 deletions
+1
View File
@@ -25,6 +25,7 @@ const posts = defineCollection({
// When absent, the language switch falls back to the section landing page (/ or /zh/).
translation: z.string().optional(),
ogImage: z.string().optional(),
banner: z.string().optional(),
}),
});
@@ -5,6 +5,7 @@ pubDate: 2026-09-09
category: devops
tags: [authentik, sso, docker, portainer, self-hosting, oidc, upgrade]
ogImage: /og/authentik-major-upgrade-gotchas.png
banner: /banners/authentik-major-upgrade-gotchas.png
---
I run authentik as the single sign-on gate in front of my self-hosted stack —
+1
View File
@@ -5,6 +5,7 @@ pubDate: 2026-09-05
category: notes
tags: [intro]
ogImage: /og/hello-world.png
banner: /banners/hello-world.png
---
Welcome. This is where I write about what I build and learn — mostly
@@ -5,6 +5,7 @@ pubDate: 2026-09-06
category: case-studies
tags: [telegram, docker, cloudflare, litellm, typescript, ai]
ogImage: /og/how-i-built-the-digikedai-telegram-bot.png
banner: /banners/how-i-built-the-digikedai-telegram-bot.png
---
Digi Kedai sells digital products — online courses, ebooks, and templates — and
@@ -5,6 +5,7 @@ pubDate: 2026-09-04
category: case-studies
tags: [astro, gitea, ci-cd, self-hosting, docker, cloudflare]
ogImage: /og/how-i-host-this-blog.png
banner: /banners/how-i-host-this-blog.png
---
This blog is itself a project I built to demonstrate the kind of work I do.
@@ -5,6 +5,7 @@ pubDate: 2026-09-09
category: devops
tags: [docker, telegram, python, dns, ipv6, debugging, portainer]
ogImage: /og/why-telegram-bot-notifications-die.png
banner: /banners/why-telegram-bot-notifications-die.png
---
I run a small monitoring bot that watches Carousell for newly-listed
@@ -5,6 +5,7 @@ pubDate: 2026-09-09
category: devops
tags: [authentik, sso, docker, portainer, self-hosting, oidc, upgrade]
ogImage: /og/authentik-major-upgrade-gotchas.png
banner: /banners/authentik-major-upgrade-gotchas.png
---
我把 authentik 当作自托管体系前面的单点登录闸门——邮箱、仪表盘、Synology
@@ -5,6 +5,7 @@ pubDate: 2026-09-06
category: case-studies
tags: [telegram, docker, cloudflare, litellm, typescript, ai]
ogImage: /og/how-i-built-the-digikedai-telegram-bot.png
banner: /banners/how-i-built-the-digikedai-telegram-bot.png
---
Digi Kedai 销售数字产品——在线课程、电子书、模板——每一单都会带来一连串同样的顾客问题:*「这门课有免费试看吗?」「我怎么拿到账号?」「我该买哪个套餐?」*。对一个人的生意来说,人工回复根本忙不过来。于是我打造了一个 AI 客服机器人,全天候解答这些问题,甚至能在无人介入的情况下自动发放免费试用账号。
@@ -5,6 +5,7 @@ pubDate: 2026-09-06
category: case-studies
tags: [astro, gitea, ci-cd, self-hosting, docker, cloudflare]
ogImage: /og/how-i-host-this-blog.png
banner: /banners/how-i-host-this-blog.png
---
这个博客本身,就是我用来说明「我到底会做什么」的一个项目。下面是完整的
@@ -5,6 +5,7 @@ pubDate: 2026-09-09
category: devops
tags: [docker, telegram, python, dns, ipv6, debugging, portainer]
ogImage: /og/why-telegram-bot-notifications-die.png
banner: /banners/why-telegram-bot-notifications-die.png
---
我跑着一个小监控机器人,专门盯着 Carousell 上新上架的商品,一旦有新品就通过
+5
View File
@@ -62,6 +62,11 @@ const switchHref = translation ? `/posts/${translation}/` : undefined;
}}
>
<article>
{post.data.banner && (
<figure class="article-banner">
<img src={post.data.banner} alt="" loading="lazy" width="1600" height="900" />
</figure>
)}
<header class="article-head">
<h1>{post.data.title}</h1>
<div class="meta">
+12
View File
@@ -170,6 +170,18 @@ article a { text-decoration: underline; text-underline-offset: 2px; }
time { color: var(--faint); font-size: 0.88rem; }
/* ---------- Article ---------- */
.article-banner {
margin: 0 0 2rem;
border-radius: var(--radius);
overflow: hidden;
border: 1px solid var(--border);
line-height: 0;
}
.article-banner img {
width: 100%;
height: auto;
display: block;
}
.article-head {
margin-bottom: 2rem;
padding-bottom: 1.5rem;