import { defineCollection, z } from "astro:content"; import { glob } from "astro/loaders"; /** Préserve les points dans les IDs (ex: "portraits.en.json" → "portraits.en") */ const stripExtension = (ext: string) => ({ generateId: ({ entry }: { entry: string }) => entry.replace(new RegExp(`\\.${ext}$`), '') }); const formatDate = (date: Date, lang: string = 'fr') => { const locales: Record = { fr: 'fr-FR', en: 'en-US', ar: 'ar-SA' }; return date.toLocaleDateString(locales[lang] || 'fr-FR', { year: 'numeric', month: 'long', day: 'numeric', }); }; const blogCollection = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }), schema: z.object({ title: z.string(), description: z.string(), date: z.date(), category: z.enum(['pro', 'comedy', 'photo']), tags: z.array(z.string()).optional(), image: z.string().optional(), imageAlt: z.string().optional(), draft: z.boolean().default(false), lang: z.enum(['fr', 'en', 'ar']).default('fr'), }).transform((data) => ({ ...data, dateFormatted: formatDate(data.date, data.lang), })), }); const projectsCollection = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/content/projects" }), schema: z.object({ title: z.string(), description: z.string(), date: z.date(), dateFormatted: z.string(), category: z.enum(['dev', 'comedy', 'photo']), technologies: z.array(z.string()).optional(), url: z.string().url().optional(), github: z.string().url().optional(), image: z.string().optional(), imageAlt: z.string().optional(), featured: z.boolean().default(false), draft: z.boolean().default(false), lang: z.enum(['fr', 'en', 'ar']).default('fr'), }), }); const talksCollection = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/content/talks" }), schema: z.object({ title: z.string(), description: z.string(), date: z.date(), dateFormatted: z.string(), event: z.string(), location: z.string(), slides: z.string().url().optional(), video: z.string().url().optional(), image: z.string().optional(), imageAlt: z.string().optional(), tags: z.array(z.string()).optional(), draft: z.boolean().default(false), lang: z.enum(['fr', 'en', 'ar']).default('fr'), }), }); const photoBlogPostsCollection = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/content/photoBlogPosts", ...stripExtension('md') }), schema: z.object({ title: z.string(), description: z.string(), date: z.date(), coverImage: z.string(), tags: z.array(z.string()).optional(), featured: z.boolean().default(false), draft: z.boolean().default(false), lang: z.enum(['fr', 'en', 'ar']).default('fr'), }), }); const photoCategoriesCollection = defineCollection({ loader: glob({ pattern: "**/*.json", base: "./src/content/photoCategories", ...stripExtension('json') }), schema: z.object({ title: z.string(), subtitle: z.string(), order: z.number().optional(), lang: z.enum(['fr', 'en', 'ar']).default('fr'), }), }); export const collections = { blog: blogCollection, projects: projectsCollection, talks: talksCollection, photoBlogPosts: photoBlogPostsCollection, photoCategories: photoCategoriesCollection, };