import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';
import { baseEntry, themeOverride } from '@eratic/core';
/**
* blog.eratic.ro has two kinds of entry that share one feed and one URL space.
*
* posts/2026/a-walk-in-fog.mdx → /2026/a-walk-in-fog/
* photos/2026/harbour.mdx → /2026/harbour/
*
* They are separate collections because their frontmatter genuinely differs —
* a photo set has a `photos` array and a post does not — but they render
* through the same route and appear together, newest first, in the listing and
* in both feeds. The `[^_]` in the glob means a filename starting with an
* underscore is ignored, which is a quick way to park something.
*
* Two entries with the same year/slug across the two collections would produce
* the same URL. Astro fails the build on duplicate routes, so that is caught
* rather than silently shadowed.
*/
const posts = defineCollection({
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: './src/content/posts' }),
schema: ({ image }) =>
baseEntry.extend({
/** article (default) · wide · bare — see docs/02-design-system.md */
canvas: z.enum(['article', 'wide', 'bare']).default('article'),
theme: themeOverride,
/** Lead image. Also used for link previews. */
cover: image().optional(),
coverAlt: z.string().optional(),
/** Show the cover at the top of the article as well as in previews. */
showCover: z.boolean().default(true),
}),
});
const photos = defineCollection({
loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: './src/content/photos' }),
schema: ({ image }) =>
baseEntry.extend({
// Photo sets default to the wider track; text still sits at the
// reading measure inside it.
canvas: z.enum(['article', 'wide', 'bare']).default('wide'),
theme: themeOverride,
photos: z
.array(
z.object({
src: image(),
alt: z.string().min(1, 'Every photograph needs alt text.'),
caption: z.string().optional(),
}),
)
.min(1, 'A photo set needs at least one photograph.'),
/** Render camera settings under each frame. */
exif: z.boolean().default(true),
columns: z.union([z.literal(1), z.literal(2), z.literal(3)]).default(2),
/** Where these were made. A place name, never coordinates. */
place: z.string().optional(),
}),
});
export const collections = { posts, photos };