df9c40847d
- About page with identity cards and equipment lists (about.json) - Contact page: station info, obfuscated e-mail, lazy Leaflet/OSM map with antenna tower marker and dark-mode tiles - Privacy, license and disclaimer pages from a legal collection - QRT-themed 404 page - LICENSE (MIT) and LICENSE-CONTENT (CC BY-SA 4.0 legal code) - Shared PageHeader and CodeCopy components Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { defineCollection } from 'astro:content';
|
|
import { glob } from 'astro/loaders';
|
|
import { z } from 'astro/zod';
|
|
|
|
// One folder per post: src/content/blog/<slug>/index.md(x) + its images.
|
|
const blog = defineCollection({
|
|
loader: glob({
|
|
pattern: '**/index.{md,mdx}',
|
|
base: './src/content/blog',
|
|
generateId: ({ entry }) => entry.replace(/\/index\.mdx?$/, ''),
|
|
}),
|
|
schema: ({ image }) =>
|
|
z
|
|
.object({
|
|
title: z.string().max(70),
|
|
description: z.string().min(50).max(160),
|
|
pubDate: z.coerce.date(),
|
|
updatedDate: z.coerce.date().optional(),
|
|
category: z.string(), // must exist in src/data/categories.json (checked in lib/posts.ts)
|
|
tags: z.array(z.string()).default([]),
|
|
cover: image().optional(),
|
|
coverAlt: z.string().optional(),
|
|
featured: z.boolean().default(false),
|
|
diy: z.boolean().default(false),
|
|
draft: z.boolean().default(false),
|
|
})
|
|
.refine((d) => !d.cover || !!d.coverAlt, {
|
|
message: 'coverAlt is required when cover is set',
|
|
path: ['coverAlt'],
|
|
}),
|
|
});
|
|
|
|
// Legal pages: src/content/legal/<slug>.md → /<slug>/
|
|
const legal = defineCollection({
|
|
loader: glob({ pattern: '*.md', base: './src/content/legal' }),
|
|
schema: z.object({
|
|
title: z.string().max(60),
|
|
description: z.string().min(50).max(160),
|
|
updated: z.coerce.date(),
|
|
}),
|
|
});
|
|
|
|
export const collections = { blog, legal };
|