Skip to content
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

Enhancement: more configurable collection path #340

Open
florian-lefebvre opened this issue Jun 18, 2023 · 15 comments
Open

Enhancement: more configurable collection path #340

florian-lefebvre opened this issue Jun 18, 2023 · 15 comments
Labels
roadmap Something we're planning to solve

Comments

@florian-lefebvre
Copy link
Contributor

Current state

Currently, the path is always static except for the slug, specified by slugField.

The problem

Projects often require more custom paths, e.g.: locales, publish date

Proposal

Make the collection config an intersection like so (pseudocode):

type Collection = { /* base props */}
	& (
		{
			path: string // with * validation
			slugField: keyof fields	
		}
		| {
			path: (fields: Record<string, any>) => string // with * validation
			slugField: keyof fields // might not be required, we could manually specify the field by interpolation instead
		}
	)

Examples

Locales

export default defineConfig({
	// ...
	collections: {
		blog: collection({
			label: "Blog",
			path: ({ locale }) => `src/content/blog/${locale}/*`
			schema: {
				// ...
				locale: fields.text({ label: "Locale" }) // could be a relationship, whatever
			}
		})
	}
})

Publish date

export default defineConfig({
	// ...
	collections: {
		blog: collection({
			label: "Blog",
			path: ({ publishDate }) => `src/content/blog/${publishDate}.*`
			schema: {
				// ...
				publishDate: fields.date({ label: "Published date" })
			}
		})
	}
})
@JedWatson
Copy link
Member

Noted on the use case here 👍

We're pretty keen on keeping slugs static (i.e not having a function you need to call in order to know where entries live) because we need to load the content directly from GitHub over their API, and knowing that as part of static config is very helpful. The challenge with allowing a function to define it is that it becomes non-deterministic, while that's not the case in your examples above, there'd be nothing stopping you from doing:

path: () => `/content/${date.now()}/*`

... chaos 💥

However we've discussed supporting support multiple slugFields as an alternative, which may solve the problem:

export default defineConfig({
	// ...
	collections: {
		blog: collection({
			// ...
			slugFields: ['locale', 'slug'],
			path: 'src/content/blog/*/*', // stars are replaced with values in order of the keys in the array above
			schema: {
				// ...
				slug: fields.slug(/* ... */),
				locale: fields.text({ label: "Locale" })
			}
		})
	}
})

What do you think? sound useful? can you see any limitations with this approach, if we added it, that you couldn't work around?

@florian-lefebvre
Copy link
Contributor Author

Sounds good 👍, a few thoughts:

  • It should be also applied for usage with documents fields
  • Maybe we could push this a bit further with Typescript string interpolation

Right now, path requires either * or ** to be included. By setting the slugFields, we could pass them to the path type to force including [locale] and [slug] in the path. I don't know if this is possible though 🤔.

Wdyt?

@JedWatson JedWatson added the roadmap Something we're planning to solve label Jun 28, 2023
@JedWatson
Copy link
Member

I had a chat with the team today about it, and there's some nuance that we need to solve, but I've put it on the roadmap.

I like your idea about using the name of the field in the path too, we'll see what we can come up with and whether that's possible 🙂

Can you expand a bit more on what you mean by "it should be applied for usage with document fields" too?

@florian-lefebvre
Copy link
Contributor Author

Awesome thanks! My bad, I just checked my schema and I thought putting format: { contentField: 'document' } changed the key to set for the path. Nevermind!

@florian-lefebvre
Copy link
Contributor Author

florian-lefebvre commented Jul 26, 2023

Hey @JedWatson, hope you're doing well! Do you have any ETA about this? Or could I help in any way, maybe with some guidance? It has become a must for the project I'm working on and I can dedicate a bit of time to make changes to keystatic

@florian-lefebvre
Copy link
Contributor Author

florian-lefebvre commented Aug 1, 2023

Sounds good 👍, a few thoughts:

  • It should be also applied for usage with documents fields
  • Maybe we could push this a bit further with Typescript string interpolation

Right now, path requires either * or ** to be included. By setting the slugFields, we could pass them to the path type to force including [locale] and [slug] in the path. I don't know if this is possible though 🤔.

Wdyt?

@JedWatson have a look at https://www.typescriptlang.org/play#code/C4TwDgpgBAxgFhGBrACgQ2HAPAZQDYCuA5lBAB7AQB2AJgM5R3ABOAllUQDRQAqpF1eoxbsiAPigBeKAG18xALr9KtBjIBQUKPJLkVQtFRBQA-FAAUfPYIYADACQBvQyAC+9pzvfOjr26e1CEgAuKCoIADcIZgBKKFDwqOZ1BU0AnjSEyOiAbnV1GAB7KiZYZggMCABhQrw8RGBWYqkoXCDlG2E2Dm50TA7VLtExczS6IIAxVgg8elCdGQVONLAMOFD4RFQ1tuJetbF1GNCIwtYaKQlHVzyC4tKyFphyypq6hqaqcxkAIjQf7g-ABGPyWUB+eEK5QAtgBaVhgOgEaEAensaBRADNCoUgWhmD8YnkgA

Credits to SuperKXT on Matt's TS Wizards Discord server

EDIT: more realistic version
https://www.typescriptlang.org/play#code/C4TwDgpgBAxgFhGBrACgQ2HAPAZQDYCuA5lBAB7AQB2AJgM5R3ABOAllUQDRQAqpF1eoxbsiAPigBeKAG18xALr9KtBjIBQUKPJLkVQtFRBQA-FAAUfPYIYADACQBvQyAC+9pzvfOjr26e1CEgAuKCoIADcIZgBKKFDwqOZ1BU0AnjSEyOiAbnV1UEgoAGEAezw8RGBWUqpcIOUbYTYObnRMRtVm0QlpRzS6IIAxVgg8elCdGQU8rTAMOFD4RFQF+uI2hbE81zz1GFqmWGYIDAgyiqqaqikodd0BLqYWrih2uE6hZ57zNIPLmDVWqhC6VQHXe6bTBidRxSQSf5goFUPYHKhHMi3GAnM6gq61cyORjDUbjOihGQAIholIU3HmmFClPsNKgrhiewAZgQqODasdTpQylROawiFg0joGNYugAlRClZg0LDfVrdDhiThpd7Sx5CeUHJVYJAQEClTmBYh0biq8RarR4vnoz4MfpaLQyJBQdhQE1mi1ShShImDYgjMYTS1EOiehTTHJQBmLN4LGNIJS7NKudRicxo0VEYN-cpI67kqBu92e703P3mkol-HooOyNLu2AIZDvLCO5FpuOU0NEcNk2kyKgEAC2ACNonSGwC+7GqUnaTD20oZUJx9lmKl21ozCGSRHy72y8vByfRzNEwsskk2W33SDG07+7M2Ts4pWTsACMwNz5mKOz5GiRzGNI2KCuctQFoSaQAPSIVoAB6JjFouZZFu2aDBsSYakpGVI0vOSZMiylJsva7rTksOJCm+yKEgRw5EeWVIQLS9L3lAzJcWyMQ0a4WrsnkQA

@algora-pbc

This comment was marked as outdated.

@aazam-gh
Copy link

Hi is this issue still available to be worked on? Would love to give it a shot :)

@florian-lefebvre
Copy link
Contributor Author

cc @JedWatson

@aazam-gh
Copy link

@florian-lefebvre any updates?

@florian-lefebvre
Copy link
Contributor Author

nope, I'm not on the team so waiting for an answer as well

@sravanth-space
Copy link

@algora-pbc Can you add a bounty label for issue?

@florian-lefebvre
Copy link
Contributor Author

florian-lefebvre commented Sep 6, 2023

That's a bot, I think labelling has to be done by the keystatic team if they wish

@rishi-raj-jain
Copy link

@florian-lefebvre

Is this open to work? Would love to crush this.

@reteps
Copy link

reteps commented Oct 20, 2024

@JedWatson Any updates?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
roadmap Something we're planning to solve
Projects
None yet
Development

No branches or pull requests

7 participants