site: topics axis + per-source indexes
Topics — the curated subscription layer: 18-value controlled vocabulary in src/lib/topics.ts, enum-enforced by the content schema on finds and reviews so unattended runs can't drift it. /topics/ index + /topics/<t>/ pages with finds first-class alongside reviews, per-topic RSS feeds that include finds (unlike category/tag feeds), "By topic" section on /feeds/, Topics footer link and llms.txt section, dev-shim coverage for the new feed URLs. daily-finds and build-review skills now classify at capture/graduation time; "giftable" is a tag, never a topic. Per-source indexes: /sources/<slug>/ lists every review and find from a source (catalog ∪ names in content, so retired sources resolve); find/review colophons link "(more from this source)"; /sources/ cards link "everything from this source →"; sub-3-item pages noindexed. Claude-Session: https://claude.ai/code/session_01WZaczDJjL3xZ3u5spsN5AL
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { defineCollection, z } from 'astro:content';
|
||||
import { glob } from 'astro/loaders';
|
||||
import { TOPICS } from './lib/topics';
|
||||
|
||||
const stripIndex = ({ entry }: { entry: string }) =>
|
||||
entry.replace(/\/index\.mdx$/, '');
|
||||
@@ -18,6 +19,7 @@ const reviews = defineCollection({
|
||||
subtitle: z.string(),
|
||||
date: z.coerce.date(),
|
||||
category: z.string(),
|
||||
topics: z.array(z.enum(TOPICS)).default([]),
|
||||
tags: z.array(z.string()).default([]),
|
||||
link: z.string().url().optional(),
|
||||
linkText: z.string().optional(),
|
||||
@@ -57,7 +59,7 @@ const find = defineCollection({
|
||||
linkText: z.string().optional(),
|
||||
amazonLink: z.string().url().optional(),
|
||||
source: z.string(),
|
||||
topics: z.array(z.string()).default([]),
|
||||
topics: z.array(z.enum(TOPICS)).default([]),
|
||||
tags: z.array(z.string()).default([]),
|
||||
description: z.string().optional(),
|
||||
promotedTo: z.string().optional(),
|
||||
|
||||
Reference in New Issue
Block a user