Enhancement: more configurable collection paths (#340) - #1623
Open
ashusatyarthi-wq wants to merge 2 commits into
Open
ashusatyarthi-wq wants to merge 2 commits into
ashusatyarthi-wq wants to merge 2 commits into
Conversation
…lues (Thinkmill#340) Adds an optional `computeSlug` on a collection config, used only when a new item is created: `computeSlug: (fields) => string`. For a collection whose `path` uses the `**` glob, the returned string can contain `/` to nest the item under sub-directories derived from its own field values (e.g. a date field producing `2026/09/my-post`) — the same nesting a manually-typed slug already supports for `**` collections, just computed instead of typed. How this differs from the issue's original `path: (fields) => string` sketch, and why: I initially prototyped that shape (`path: string | { base, resolve }`, posted on the issue) but found it doesn't hold up on the reader side. Every "list existing items" path (`app/utils.ts`'s tree walk, `reader/generic.ts`'s `collectionReader`) discovers items by walking one static directory and glob-matching filenames — it never has field values in hand before it finds a file, so a path computed from fields can't be inverted for listing without either parsing every file up front or introducing a second static anchor. Digging into how `slugField` is actually used turned up the way around that problem: a `**` collection already treats a slug containing `/` as a nested path (`app/utils.ts`'s `getEntriesInCollectionWithTreeKey`, `handleDirectory`) and discovers it by a plain recursive tree walk keyed off the slug alone — no per-item field parsing needed. So instead of making `path` computed (which needs the reader to invert an arbitrary function), this makes the *slug* computed (which the reader already discovers structurally, unchanged) and gets the same nested-by-field-values outcome the issue asked for, without touching path-resolution/listing code, and without conflicting with `slugField`'s existing compile-time coupling to a `SlugFormField` schema field (the `collection()` helper's generic constrains `SlugField` to a key whose schema field extends `SlugFormField`, which a plain function can't satisfy). Scope: `computeSlug` only affects the moment a *new* item's slug is decided — editing/renaming an existing item is untouched (`ItemPage.tsx` keeps reading/writing the real, already-fixed slug the normal way). To keep the change surgical, the fallback wiring lives in a single new helper, `getSlugForNewItem` (app/utils.ts), used only at the actual item-creation call sites in create-item.tsx: the two places a new item's slug is first decided (`CreateItemLocal`, `CreateItemCollab`), and the five places downstream of a successful create that re-derive that same slug for navigation/copy/paste. `getSlugFromState` itself, and its ~18 other call sites (editing, array-field items, change-detection, validation, cloud serialization), are untouched. Also: added `testTimeout: 20_000` to the root vitest config. Found while running the full suite before pushing — 4 tests in the markdoc editor suites (lists.test.tsx, pasting/from-other-editors.test.tsx) were failing on the default 5s budget, but only ever as the first test in their file. Confirmed via `git stash` that this reproduces on a clean, untouched checkout, and that every individual test body actually finishes in well under a second — the 5s default includes each file's own import/transform cost, which this machine's resources push close to the limit for the heavier editor suites. Bumped to 20s rather than leaving it as pre-existing flakiness in a PR that's meant to leave `pnpm vitest run` fully green. Full suite after this change: 58 files, 705 passed, 8 skipped, 0 failed. `pnpm check:types` and `pnpm lint` also clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
changeset-bot flagged the PR as missing one — this repo versions @keystatic/core via changesets, so a feature addition like computeSlug needs one for the next release's changelog/version bump. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 0c4653e The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Author
|
Hi team, just following up on PR #1623. Changeset verification has passed and implementation is ready for review and CI workflow approval whenever you have a moment. Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #340. Implements dynamic slug computation via
computeSlugin Collection configuration, allowing nested collection paths (e.g. date-based or field-derived subdirectories) when paired with the**pattern.