-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Content Collections #373
Content Collections #373
Conversation
Overall I am super thrilled by this, great work! I have one very nitpicky bikeshed, which is that the |
I like the changes that you described in the video. The part that is unclear for me right now is if zod stuff is optional or not. The |
@JLarky, yes schema files are totally optional! You can still call And that's a good suggestion! It was avoided since types like |
@natemoo-re Fair point! the
I understand |
I'm confused about what you did with schema but could you more importantly talk about define collection? What else does it do rather than allow you to define a schema? Does it have other configuration details? Oh and good luck. I hope this RFC doesn't hurt performance at all or slow down SSG defineCollection({
schema: {
title: z.string(),
slug: z.string(),
// mark optional properties with `.optional()`
image: z.string().optional(),
tags: z.array(z.string()),
// transform to another data type with `transform`
// ex. convert date strings to Date objects
publishedDate: z.string().transform((str) => new Date(str)),
},
});
``` |
@louiss0 Ah yes, I should clarify: we may introduce collection config options other than // not final code
const blog = defineCollection({
slug: ({ id, data }) => data.customSlug ?? slugify(slug),
schema: {...},
}) Nesting And thanks! Happy to share we're seeing perf gains from content schemas over |
Co-authored-by: Ben Holmes <[email protected]>
Co-authored-by: Ben Holmes <[email protected]>
Co-authored-by: Ben Holmes <[email protected]>
Update renderEntry with implementation details
Are there any plans to introduce a concept of relationships between collections? For example, a Another thing I'd really love is to have some const allBlogPostsAfter2020 = await search(`
blog.* from blog
where publishedDate.year > 2022
order by publishedDate asc
`); where Furthermore, the search API can flatten the // this gives you all the blog posts
const allBlogPosts = await search(`blog.* from blog`)
// this gives you an entry
const firstBlogPost = await search(`blog.* from blog where title = "First Blog Post"`)
// this gives you the latest entry
const latestBlogPost = await search(`blog.* from blog order by publishedDate asc limit 1`) This might also work nicely with relationships using joins. const blogPostsByAstro = await search(`
blog.* from blog, author
where blog.authorId = author.id
and author.name = "Astro"
`) Lume does something similar using its search and relations plugins. |
@naiyerasif Ah, I love these ideas!
|
How far have you gotten in the last few days? Did you fix the windows problem? Is the magic layouts feature going to go away after this feature is standardized? |
This can be a separate RFC if you think the current RFC may become too big.
Any fluent query DSL (like Nuxt's Content) should be fine. I agree that having helper functions for such an API would be immensely helpful. I think this should be a part of this RFC since you're already planning for something similar with |
Is it possible for the collection argument for const blogs = await getCollection("blog");
const englishBlogs = await getCollection("blog/en"); To not introduce complexity, schemas will still be limited to top-level ( |
Also, why not move // now
const { Content } = renderEntry(entry);
// idea
const { Content } = entry.render(); |
@pilcrowonpaper Good questions!
|
Alright everyone, thank you so much for your input and excitement over these past few weeks. We plan to discuss Content Collections during the RFC call on our discord tomorrow (2pm ET), and hope to reach consensus for an experimental release! I'll highlight 2 final tweaks that were made:
import { defineCollection } from 'astro:content';
const blog = defineCollection({
slug({ id, data }) {
return data.slug ?? myCustomSlugify(id);
},
schema: {...}
});
export const collections = { blog };
And that's it! Hope to see y'all on the call tomorrow 👋 |
Things to figure out before unflagging:
|
aliases: [content collections criticism,]
|
Would it be possible to provide a function to the collection config so that we can transform/create slugs in our own way? For example, the current slug normalizer that's creating the Seems the simplest solution is to continue to provide a simple slugifier and then allow people who want a more advanced one to provide that to the config. Of course you could just map over the collection returned by |
The solution is built in already. import { defineCollection } from 'astro:content'; const blog = defineCollection({ export const collections = { blog }; |
@ispringle fair point! Other RFC reviewers raised slug customization as well, so we decided to ship a Also curious to hear how our default slugger can be improved! We have an existing issue for handling file name spaces, but open to further ideas as well. |
Both points have been addressed in the final RFC draft. With these resolved... this RFC is officially accepted and good-to-merge 🥳 Thanks again to everyone for your time and input. You can try on the experimental release with our shiny new Content Collections docs. We'll also be marking this RFC as closed. So if you have future ideas, we encourage you to start a new discussion. Thanks again 🙌 |
Summary
Content Collections are a way to fetch Markdown and MDX frontmatter in your Astro projects in a consistent, performant, and type-safe way.
This is paired with Render Content, a solution to script and style bleed when importing globs of Markdown and MDX Content.
Both proposals are presented below, and are meant to be reviewed and accepted as a pair.
astro-content-smol.mp4
Links