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 ."
|
"check": "biome check --apply-unsafe ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/check": "^0.9.4",
|
"@astrojs/check": "^0.9.6",
|
||||||
"@astrojs/tailwind": "^5.1.0",
|
"@astrojs/tailwind": "^6.0.2",
|
||||||
"@biomejs/biome": "1.7.3",
|
"@biomejs/biome": "1.7.3",
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@tailwindcss/typography": "^0.5.13",
|
||||||
"@types/node": "^25.0.3",
|
"@types/node": "^25.0.3",
|
||||||
"astro": "^4.8.2",
|
"astro": "^5.17.2",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"tsx": "^4.21.0",
|
"tsx": "^4.21.0",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import CategoryNav from '../CategoryNav.astro';
|
||||||
import AlbumHeader from '../AlbumHeader.astro';
|
import AlbumHeader from '../AlbumHeader.astro';
|
||||||
import MasonryGallery from '../MasonryGallery.astro';
|
import MasonryGallery from '../MasonryGallery.astro';
|
||||||
import Lightbox from '../Lightbox.astro';
|
import Lightbox from '../Lightbox.astro';
|
||||||
|
import { render } from 'astro:content';
|
||||||
import { getPostBaseSlug, type Locale } from '../../../utils/i18n';
|
import { getPostBaseSlug, type Locale } from '../../../utils/i18n';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -16,7 +17,7 @@ const { post, lang = 'fr' } = Astro.props;
|
||||||
// Importer toutes les images du dossier photos
|
// Importer toutes les images du dossier photos
|
||||||
const allImages = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/photos/blog/**/*.{jpg,jpeg,png,webp}');
|
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);
|
const baseSlug = getPostBaseSlug(post.id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const { count } = Astro.props;
|
||||||
const postsLoop = allPosts.slice(0, count).map((post) => {
|
const postsLoop = allPosts.slice(0, count).map((post) => {
|
||||||
return {
|
return {
|
||||||
...(post.data || {}),
|
...(post.data || {}),
|
||||||
link: `/post/${post.slug}`,
|
link: `/post/${post.id}`,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
import { defineCollection, z } from "astro:content";
|
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 formatDate = (date: Date, lang: string = 'fr') => {
|
||||||
const locales: Record<string, string> = { fr: 'fr-FR', en: 'en-US', ar: 'ar-SA' };
|
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({
|
const blogCollection = defineCollection({
|
||||||
type: "content",
|
loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
|
|
@ -28,7 +33,7 @@ const blogCollection = defineCollection({
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectsCollection = defineCollection({
|
const projectsCollection = defineCollection({
|
||||||
type: "content",
|
loader: glob({ pattern: "**/*.md", base: "./src/content/projects" }),
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
|
|
@ -47,7 +52,7 @@ const projectsCollection = defineCollection({
|
||||||
});
|
});
|
||||||
|
|
||||||
const talksCollection = defineCollection({
|
const talksCollection = defineCollection({
|
||||||
type: "content",
|
loader: glob({ pattern: "**/*.md", base: "./src/content/talks" }),
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
|
|
@ -66,7 +71,7 @@ const talksCollection = defineCollection({
|
||||||
});
|
});
|
||||||
|
|
||||||
const photoBlogPostsCollection = defineCollection({
|
const photoBlogPostsCollection = defineCollection({
|
||||||
type: "content",
|
loader: glob({ pattern: "**/*.md", base: "./src/content/photoBlogPosts", ...stripExtension('md') }),
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
|
|
@ -80,7 +85,7 @@ const photoBlogPostsCollection = defineCollection({
|
||||||
});
|
});
|
||||||
|
|
||||||
const photoCategoriesCollection = defineCollection({
|
const photoCategoriesCollection = defineCollection({
|
||||||
type: "data",
|
loader: glob({ pattern: "**/*.json", base: "./src/content/photoCategories", ...stripExtension('json') }),
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
subtitle: z.string(),
|
subtitle: z.string(),
|
||||||
|
|
@ -95,4 +100,4 @@ export const collections = {
|
||||||
talks: talksCollection,
|
talks: talksCollection,
|
||||||
photoBlogPosts: photoBlogPostsCollection,
|
photoBlogPosts: photoBlogPostsCollection,
|
||||||
photoCategories: photoCategoriesCollection,
|
photoCategories: photoCategoriesCollection,
|
||||||
};
|
};
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
---
|
---
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection, render } from "astro:content";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const postEntries = await getCollection("blog");
|
const postEntries = await getCollection("blog");
|
||||||
return postEntries.map((entry) => ({
|
return postEntries.map((entry) => ({
|
||||||
params: { slug: entry.slug },
|
params: { slug: entry.id },
|
||||||
props: { entry },
|
props: { entry },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { entry } = Astro.props;
|
const { entry } = Astro.props;
|
||||||
const { Content } = await entry.render();
|
const { Content } = await render(entry);
|
||||||
---
|
---
|
||||||
|
|
||||||
<Content />
|
<Content />
|
||||||
|
|
@ -170,7 +170,7 @@ export function getHomePath(locale: Locale): string {
|
||||||
return locale === 'fr' ? '/' : `/${locale}`;
|
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 {
|
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