jalil.arfaoui.net/src/content.config.ts

140 lines
4.4 KiB
TypeScript
Raw Normal View History

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}$`), '') });
2026-01-07 03:03:42 +01:00
const formatDate = (date: Date, lang: string = 'fr') => {
const locales: Record<string, string> = { 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'),
2026-01-07 03:03:42 +01:00
}).transform((data) => ({
...data,
dateFormatted: formatDate(data.date, data.lang),
})),
});
const projectsCollection = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/projects", ...stripExtension('md') }),
schema: z.object({
title: z.string(),
description: z.string(),
date: z.date(),
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'),
}).transform((data) => ({
...data,
dateFormatted: formatDate(data.date, data.lang),
})),
});
const experiencesCollection = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/experiences", ...stripExtension('md') }),
schema: z.object({
role: z.string(),
company: z.string(),
companyUrl: z.string().url().optional(),
location: z.string().optional(),
startDate: z.string(),
endDate: z.string().optional(),
technologies: z.array(z.string()).optional(),
type: z.enum(['employment', 'freelance', 'teaching', 'community', 'entrepreneurship']),
featured: z.boolean().default(false),
draft: z.boolean().default(false),
lang: z.enum(['fr', 'en', 'ar']).default('fr'),
}),
});
const recommendationsCollection = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/recommendations" }),
schema: z.object({
author: z.string(),
authorRole: z.string(),
company: z.string().optional(),
avatar: z.string().optional(),
url: z.string().url().optional(),
date: z.date(),
featured: z.boolean().default(false),
relationship: z.string().optional(),
lang: z.enum(['fr', 'en']).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,
experiences: experiencesCollection,
recommendations: recommendationsCollection,
talks: talksCollection,
photoBlogPosts: photoBlogPostsCollection,
photoCategories: photoCategoriesCollection,
};