我正在使用 AstroJS 开发一个项目。目标是使用 getStaticPaths 函数按照动态路由方法在单个页面上显示一些图像、标题和描述。
从图像库开始
src
images
apple
apple-01.jpg
apple-02.jpg
apple-03.jpg
apple-03.jpg
banana
banana-01.jpg
banana-02.jpg
banana-03.jpg
banana-03.jpg
页面结果符合预期
/page/{path}
------------
{Title}
{Description}
{Image}
{Image}
{Image}
------------
幸运的是,按照 Bryce Russell 的编码示例,我成功地将多个图像放到一个页面上。然而,尽管尝试了某种形式的 Data Passing Props 与 Bryce Russell 编码示例的结合,但我仍在努力寻找包含标题和描述的方法。
下面的代码是我的第八次尝试,并且...
// [page].astro
---
import fg from "fast-glob";
export async function getStaticPaths() {
//Data array for titles and description based on image folder name
const labels = [
{page: 'image folder name', title: "Title goes here", desc: "description goes here"},
{page: 'image folder name', title: "Title goes here", desc: "description goes here"}
];
//Create labels (Title and Description) based on [page].astro
return labels.map((label) => {
return {
params: { id: label.page },
props: { title: label.title, desc: label.desc }
};
});
// Get all collection folder paths: 'src/images/[collection]'
const collections: string[] = fg.sync("src/images/*", {
onlyDirectories: true,
});
// Create a new route for every collection
return collections.map((collection) => {
return {
params: { collection: collection.split("/").pop() },
props: {
images: fg.sync(`${collection}/**/*.{png,jpg}`).map((img) => img.replace("", "/")),
},
};
});
}
export interface Props {
images: string[];
}
const { collection } = Astro.params;
const { label } = Astro.params
const { images, title, desc } = Astro.props;
---
<div>
<section>
{title}
{desc}
</section>
<section>
{
images.map((img) => (
<img src={img} loading="lazy" />
))
}
</section>
</div>
显然,我做得太草率了,而且我知道这不是正确的方法。显然, getStaticPaths() 不允许在同一函数中两次返回 .map() 。除非我错过了什么?
尽管我尝试寻找解决方案,但我也研究了 Astro 文档,试图找到一些提示、示例或技巧。我没有任何运气。
因此,我希望能够获得一些帮助来寻找解决方案,并更好地了解如何使用 getStaticPaths() 将多个图像和数据(标题和描述)收集到遵循路由路径的单个页面中。除非有其他方法可以做到这一点?你会推荐什么?
提前致谢。
正如您所发现的,如果路径包含动态部分(例如集合中某些内容的名称),则
Astro.glob
和
import.meta.glob()
不起作用。但以下有效:
通过将以下内容放入
fruit
来启动 src/content/fruit/apple.yaml
内容收集
title: 'Apple'
description: 'Appples are awesome.'
images:
- src: './apple-1.jpg'
alt: 'image one desc'
- src: './apple-2.jpg'
alt: 'image two desc'
不要忘记添加图像文件,例如
src/content/fruit/apple-1.jpg
通过将以下内容放入
src/content/config.ts
来描述您的架构验证和图像处理集合:
import { defineCollection, z } from "astro:content";
// from https://docs.astro.build/en/guides/images/#images-in-content-collections
const fruitCollection = defineCollection({
schema: ({ image }) => z.object({
title: z.string(),
description: z.string(),
images: z.array( z.object({
src: image(),
alt: z.string(),
})),
}),
});
export const collections = {
fruit: fruitCollection,
};
让 Astro 通过将以下内容放入
src/pages/[...slug].astro
来生成页面:
---
import { Image } from "astro:assets";
import { getCollection } from 'astro:content';
// from https://docs.astro.build/en/tutorials/add-content-collections/#generate-pages-from-a-collection
export async function getStaticPaths() {
const entries = await getCollection('fruit');
return entries.map(entry => ({
params: { slug: entry.id }, props: { entry },
}));
}
const { entry } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Astro</title>
</head>
<body>
<h1>{entry.data.title}</h1>
<p>{entry.data.description}</p>
{entry.data.images.map(image =>
<Image src={image.src} alt={image.alt} />)}
</body>
</html>
访问http://localhost:4321/apple/