Migration Astro v4 → v5 avec Content Layer API
- Mise à jour astro@5.17, @astrojs/tailwind@6, @astrojs/check - Remplacement des content collections legacy par des loaders glob() - Déplacement src/content/config.ts → src/content.config.ts - entry.slug → entry.id, entry.render() → render(entry) - Ajout de generateId personnalisé pour préserver les points dans les IDs des fichiers multilingues (.en, .ar)
This commit is contained in:
parent
73d4d2fa06
commit
ae565d46ac
7 changed files with 1680 additions and 1340 deletions
2982
package-lock.json
generated
2982
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,12 +13,12 @@
|
|||
"check": "biome check --apply-unsafe ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@astrojs/check": "^0.9.6",
|
||||
"@astrojs/tailwind": "^6.0.2",
|
||||
"@biomejs/biome": "1.7.3",
|
||||
"@tailwindcss/typography": "^0.5.13",
|
||||
"@types/node": "^25.0.3",
|
||||
"astro": "^4.8.2",
|
||||
"astro": "^5.17.2",
|
||||
"dotenv": "^17.2.3",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"tsx": "^4.21.0",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import CategoryNav from '../CategoryNav.astro';
|
|||
import AlbumHeader from '../AlbumHeader.astro';
|
||||
import MasonryGallery from '../MasonryGallery.astro';
|
||||
import Lightbox from '../Lightbox.astro';
|
||||
import { render } from 'astro:content';
|
||||
import { getPostBaseSlug, type Locale } from '../../../utils/i18n';
|
||||
|
||||
interface Props {
|
||||
|
|
@ -16,7 +17,7 @@ const { post, lang = 'fr' } = Astro.props;
|
|||
// Importer toutes les images du dossier photos
|
||||
const allImages = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/photos/blog/**/*.{jpg,jpeg,png,webp}');
|
||||
|
||||
const { Content } = await post.render();
|
||||
const { Content } = await render(post);
|
||||
|
||||
const baseSlug = getPostBaseSlug(post.id);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const { count } = Astro.props;
|
|||
const postsLoop = allPosts.slice(0, count).map((post) => {
|
||||
return {
|
||||
...(post.data || {}),
|
||||
link: `/post/${post.slug}`,
|
||||
link: `/post/${post.id}`,
|
||||
};
|
||||
});
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
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<string, string> = { fr: 'fr-FR', en: 'en-US', ar: 'ar-SA' };
|
||||
|
|
@ -10,7 +15,7 @@ const formatDate = (date: Date, lang: string = 'fr') => {
|
|||
};
|
||||
|
||||
const blogCollection = defineCollection({
|
||||
type: "content",
|
||||
loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
|
|
@ -28,7 +33,7 @@ const blogCollection = defineCollection({
|
|||
});
|
||||
|
||||
const projectsCollection = defineCollection({
|
||||
type: "content",
|
||||
loader: glob({ pattern: "**/*.md", base: "./src/content/projects" }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
|
|
@ -47,7 +52,7 @@ const projectsCollection = defineCollection({
|
|||
});
|
||||
|
||||
const talksCollection = defineCollection({
|
||||
type: "content",
|
||||
loader: glob({ pattern: "**/*.md", base: "./src/content/talks" }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
|
|
@ -66,7 +71,7 @@ const talksCollection = defineCollection({
|
|||
});
|
||||
|
||||
const photoBlogPostsCollection = defineCollection({
|
||||
type: "content",
|
||||
loader: glob({ pattern: "**/*.md", base: "./src/content/photoBlogPosts", ...stripExtension('md') }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
|
|
@ -80,7 +85,7 @@ const photoBlogPostsCollection = defineCollection({
|
|||
});
|
||||
|
||||
const photoCategoriesCollection = defineCollection({
|
||||
type: "data",
|
||||
loader: glob({ pattern: "**/*.json", base: "./src/content/photoCategories", ...stripExtension('json') }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
subtitle: z.string(),
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import { getCollection, render } from "astro:content";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const postEntries = await getCollection("blog");
|
||||
return postEntries.map((entry) => ({
|
||||
params: { slug: entry.slug },
|
||||
params: { slug: entry.id },
|
||||
props: { entry },
|
||||
}));
|
||||
}
|
||||
|
||||
const { entry } = Astro.props;
|
||||
const { Content } = await entry.render();
|
||||
const { Content } = await render(entry);
|
||||
---
|
||||
|
||||
<Content />
|
||||
|
|
@ -170,7 +170,7 @@ export function getHomePath(locale: Locale): string {
|
|||
return locale === 'fr' ? '/' : `/${locale}`;
|
||||
}
|
||||
|
||||
/** Slug de base d'un photo blog post depuis son id (ex: "2015/enigma.en.md" → "enigma") */
|
||||
/** Slug de base d'un photo blog post depuis son id (ex: "2015/enigma.en" → "enigma") */
|
||||
export function getPostBaseSlug(postId: string): string {
|
||||
return postId.replace(/^\d{4}\//, '').replace(/\.(en|ar)?\.mdx?$/, '');
|
||||
return postId.replace(/^\d{4}\//, '').replace(/\.(en|ar)(\.md)?$/, '');
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue