Categories page: descriptions, per-category terminal illustrations, full ZH version
Deploy / build (push) Successful in 17s
Deploy / build (push) Successful in 17s
- 7 categories now listed with name, blurb, post count and a per-category terminal-style SVG illustration (CategoryArt) - empty categories show '0 posts · coming soon' (non-link, no soft-404) - new zh pages: /zh/categories/ index + /zh/categories/[category]/ detail - PostList is locale-aware (zh-CN dates, zh category links) - zh nav '分类' now points to /zh/categories/ - category detail pages get art + description header - language switch wired both ways (EN <-> ZH)
This commit is contained in:
1 parent
730a936137
commit
4cf52e04c1
11 files changed
+577
-25
No files matched your search
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Category metadata — single source of truth for the 7 official categories.
|
||||
* Names + descriptions in EN/ZH, one accent color per category (used by the
|
||||
* terminal-style illustration on the categories page).
|
||||
*
|
||||
* The enum itself stays in src/content.config.ts (zod); this file adds the
|
||||
* human-facing copy and ordering for listing pages.
|
||||
*/
|
||||
|
||||
export const CATEGORY_SLUGS = [
|
||||
'ai',
|
||||
'case-studies',
|
||||
'devops',
|
||||
'engineering',
|
||||
'notes',
|
||||
'tutorials',
|
||||
'web3',
|
||||
] as const;
|
||||
|
||||
export type CategorySlug = (typeof CATEGORY_SLUGS)[number];
|
||||
|
||||
interface CategoryMeta {
|
||||
slug: CategorySlug;
|
||||
/** Display name (Title Case EN / 中文) */
|
||||
name: { en: string; zh: string };
|
||||
/** One-paragraph description of what lives in this category */
|
||||
blurb: { en: string; zh: string };
|
||||
/** Accent color for the category illustration (terminal prompt / glyph) */
|
||||
accent: string;
|
||||
}
|
||||
|
||||
export const CATEGORY_META: Record<CategorySlug, CategoryMeta> = {
|
||||
ai: {
|
||||
slug: 'ai',
|
||||
name: { en: 'AI', zh: '人工智能' },
|
||||
blurb: {
|
||||
en: 'n8n workflows, Telegram bots, local LLMs, the Mem0 memory stack and TTS — AI automations I have actually shipped, mostly on self-hosted hardware.',
|
||||
zh: 'n8n 工作流、Telegram 机器人、本地大模型、Mem0 记忆栈与语音合成——真正落地运行过的 AI 自动化,大部分跑在自己托管的基础设施上。',
|
||||
},
|
||||
accent: '#0e94ff',
|
||||
},
|
||||
'case-studies': {
|
||||
slug: 'case-studies',
|
||||
name: { en: 'Case Studies', zh: '案例研究' },
|
||||
blurb: {
|
||||
en: 'How I built X, end to end: the problem, the debugging story, the fix and the measured result. This is my working portfolio.',
|
||||
zh: '「我是如何构建 X」的完整实录:问题、踩坑、修复与可衡量的结果。这是我的实战作品集。',
|
||||
},
|
||||
accent: '#3fb950',
|
||||
},
|
||||
devops: {
|
||||
slug: 'devops',
|
||||
name: { en: 'DevOps', zh: 'DevOps' },
|
||||
blurb: {
|
||||
en: 'Docker & Portainer, Traefik, Cloudflare tunnels, a ~140-container NAS homelab, backups and monitoring — my most hands-on, differentiated material.',
|
||||
zh: 'Docker/Portainer、Traefik、Cloudflare 隧道、约 140 个容器的 NAS 家庭机房、备份与监控——我最硬核、实操最深的领域。',
|
||||
},
|
||||
accent: '#295cff',
|
||||
},
|
||||
engineering: {
|
||||
slug: 'engineering',
|
||||
name: { en: 'Engineering', zh: '工程开发' },
|
||||
blurb: {
|
||||
en: 'Java & Spring, PHP and WordPress deep dives — how production web applications are really put together, from the code up.',
|
||||
zh: 'Java/Spring、PHP 与 WordPress 深度解析——生产级 Web 应用从代码层面开始的真实构建方式。',
|
||||
},
|
||||
accent: '#7c9cff',
|
||||
},
|
||||
notes: {
|
||||
slug: 'notes',
|
||||
name: { en: 'Notes', zh: '随记' },
|
||||
blurb: {
|
||||
en: 'Short, low-friction entries: fixes, gotchas and link roundups from day-to-day work. Quick reads that save someone an afternoon.',
|
||||
zh: '简短速记:问题修复、避坑记录与链接精选,来自日常开发的第一手经验。三分钟读完,省一个下午。',
|
||||
},
|
||||
accent: '#ff7ab6',
|
||||
},
|
||||
tutorials: {
|
||||
slug: 'tutorials',
|
||||
name: { en: 'Tutorials', zh: '教程' },
|
||||
blurb: {
|
||||
en: 'Beginner-friendly, follow-along how-tos. Copy the commands, run them, get a working result — then understand why it worked.',
|
||||
zh: '面向初学者的跟练教程:复制命令、动手运行、得到可用结果——再弄懂它为什么能work。',
|
||||
},
|
||||
accent: '#f5a524',
|
||||
},
|
||||
web3: {
|
||||
slug: 'web3',
|
||||
name: { en: 'Web3', zh: 'Web3' },
|
||||
blurb: {
|
||||
en: 'Solidity, Foundry, ERC-20/721 — honestly framed learning projects on testnets, not production DeFi.',
|
||||
zh: 'Solidity、Foundry、ERC-20/721——在测试网上如实记录的学习项目,而非生产级 DeFi。',
|
||||
},
|
||||
accent: '#b026ff',
|
||||
},
|
||||
};
|
||||
|
||||
/** Ordered list of all categories (alphabetical by slug). */
|
||||
export const ALL_CATEGORIES: CategoryMeta[] = CATEGORY_SLUGS.map((s) => CATEGORY_META[s]);
|
||||
|
||||
/** Safer lookup that tolerates unknown strings (e.g. old post data). */
|
||||
export function categoryMeta(slug: string): CategoryMeta | undefined {
|
||||
return (CATEGORY_META as Record<string, CategoryMeta | undefined>)[slug];
|
||||
}
|
||||
Reference in new issue
Block a user