-
Notifications
You must be signed in to change notification settings - Fork 31
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
Referencing data from content collections #530
Comments
We've discussed some initial examples of how data collections could work, including querying and referencing. This was informed through @tony-sull and I's work on the astro.build site. Ex: Creating a collection of JSONSay you have a collection of blog post authors you would like to store as JSON. You can create a new collection under src/data/
authors/
ben.json
fred.json
matthew.json This collection can be configured with a schema like any other content collection. To flag the collection as data-specific, we may expose a new // src/content/config.ts
import { defineDataCollection, z } from 'astro:content';
const authors = defineDataCollection({
schema: z.object({
name: z.string(),
twitter: z.string().url(),
})
});
export const collections = { authors }; It can also be queried like any other collection, this example using ---
import { getDataCollection } from 'astro:content';
const authors = await getDataCollection('authors');
---
<ul>
{authors.map(author => (
<li>
<a href={author.data.twitter}>{author.data.name}</a>
</li>
)}
</ul> Return typeData collections will return a subset of fields exposed by content collections: type DataCollectionEntry<C> = {
id: string;
data: object;
collection: C;
} This omits a few key fields:
Ex: Referencing data collectionsData collections could be referenced from existing content collection schemas. One example may be a reference() function (see @tony-sull 's early experiment) to reference data collection entries by slug from your frontmatter. This example allows you to list all blog post authors from each blog post: src/content/config.ts
import { defineCollection, defineDataCollection, reference, z } from 'astro:content'
const blog = defineCollection({
schema: z.object({
title: z.string(),
authors: z.array(reference("authors")),
})
});
const authors = defineDataCollection({
schema: z.object({
name: z.string(),
avatar: image(),
})
})
export const collections { blog, authors }; Then, authors can be referenced by slug from each ---
title: Astro 2.0 launched
authors:
- fred-schott
- ben-holmes
--- |
How do you differentiate between We should try to support This may even make sense to add as an explicit goal of the stage 2 proposal, since I'd argue the query DX hit of always needing to unwrap an array for Other initial thoughts:
|
Another reason to avoid this for now: if the whole reference system works by referencing an |
@FredKSchott Thanks for the suggestions! Think I agree with all of these. Thoughts on the API design:
...
// Reference a single author by id (default)
author: reference('authors'),
// Reference multiple authors in a list of IDs
authors: reference('authors', { relation: 'many' }),
|
This comment was marked as outdated.
This comment was marked as outdated.
I'd definitely prefer the For me I can't think of many uses for |
This comment was marked as outdated.
This comment was marked as outdated.
@tony-sull Just marked my comment above as outdated because... I'm wrong! Zod transforms run separately, so you can totally do |
@bholmesdev Excellent! I wasn't actually sure if that setup would work, glad that does the trick! 🚀 |
Discussion on single-file data collections vs. multi-fileThere have been a few mentions of support a single file to store all data collection entries as an array, instead of splitting up entries per-file as we do content collections today. This would mean, say, a single Investigating this, I think it's best to stick with multiple files instead. Reasons:
The reasons in favor of
|
I'd definitely lean towards multiple files for data collections, at least for the use cases I can think of. CSVs are an interesting one, but I could even see wanting multiple CSV files for something like a "database" of transactions grouped by month
|
I am working on a template for a talk I'll be giving at soon-to-be-announced conference, where I want to show people how they can setup an engineering blog for themselves or a multi-author blog for their company. A feature like relational data from JSON would be really neat to have! In the meantime I manually hooked it all up based on a string ID. A few notes on the earlier conversation here:
Just an idea I'd like to throw in here: what if you could do |
Ah, that's great to hear @EddyVinck! I'm working to have a preview release by end-of-day tomorrow. I'll share that branch here once it's up.
This is an interesting idea! Though I will admit, I'm not sure if
I also worry that the |
Well I'm a man of my word! Here's a preview branch + video overview of the new data collection APIs. Still waiting on the preview release CI action (something's holding it up...) but you should be able to clone the repo and try the |
Looks like the link got cut off, here's the actual PR: withastro/astro#6850 |
Discussion on
|
This one's really minor, but I also like that reusing That means one less |
Using |
@jasikpark So as part of this, I don't expect data and content to be able to live in the same collection. We'd require users to specify the type of a collection in their config file (i.e. |
ohhhhhh i forgot that
wouldn't be supported... hmm i dunno how i feel about either directory then 🙈 |
@jasikpark Well that would be supported still, as long as you add an underscore |
Ok - I guess I've been thinking of a collection entry as a folder rather than a markdoc file 😓 good to understand that better |
@jasikpark That's a model keystatic has adopted actually! Since nested directories are used for |
cool, i'll play around w/ that then - thx for all the responses 💜 how does it make you think of the app folder for nextjs? |
@jasikpark Well, it's the difference between file vs. directory-based routing. I think content collections and Astro's |
ooohhhh thx for clarifying, that's interesting yeah |
I'm more in favour of |
Thanks for the input y'all! Implemented |
Closing as this is completed and in stable. |
Details
Summary
Introduce a standard to store data separately from your content (ex. JSON files), with a way to "reference" this data from existing content collections.
Background & Motivation
Content collections are restricted to supporting
.md
,.mdx
, and.mdoc
files. This is limiting for other forms of data you may need to store, namely raw data formats like JSON.Taking a blog post as the example, there will likely be author information thats reused across multiple blog posts. To standardize updates when, say, updating an author's profile picture, it's best to store authors in a separate data entry, with an API to reference this data from any blog post by ID.
The content collections API was built generically to support this future, choosing format-agnostic naming like
data
instead offrontmatter
andbody
instead ofrawContent
. Because of this, expanding support to new data formats without API changes is a natural progression.Use cases
We have a few use cases in mind considering data collections and data references. We expect this list to grow through the RFC discussion and learning from our community!
i18n/
collection containingen.json
,fr.json
, etc.alt
text or image widths and heights for standard assets. For example, animages/banner.json
file containing thesrc
as a string, alt text, and a preferredwidth
Goals
src/data/
directory distinct fromsrc/content/
, or simply allow data collections withinsrc/content/
.Non-goals
The text was updated successfully, but these errors were encountered: