Replies: 6 comments 7 replies
-
|
I would vote a implementation like this: Target collection should not be immutable. The content picker should show all status. Reverse links are useful but not needed in the first implementation. Multiple references should be supported in the future at least. |
Beta Was this translation helpful? Give feedback.
-
|
Coming from this as a content editor, rather than a developer, I'd love to see something like Voxel's (WP) implementation of their Reference Field, as a future goal. https://docs.getvoxel.io/articles/post-relation-field-2/ |
Beta Was this translation helpful? Give feedback.
-
|
If anyone would like to take this on, that would be great. Happy to discuss details of implementation |
Beta Was this translation helpful? Give feedback.
-
|
@ascorbic few interconencted questions:
|
Beta Was this translation helpful? Give feedback.
-
|
Hi @ascorbic and all. Since we are doing a join table approach with back-links, I thought of something: why not surface the relationship on both sides as fields? For example, say you have Chapters and Lessons as collections. Each Lesson belongs to a Chapter. If you are on the Chapter side of things, it would be useful to see the lessons it contains directly, rather than putting it in a "Referenced by" side panel or something similar. Same thing if you are checking a Lesson. We still end up with "one row per reference" in the DB, but it makes it easier for the user to navigate the relations. Here is the full proposal: https://github.com/MA2153/emdash/blob/reference-field/docs/superpowers/specs/2026-05-10-reference-field-relations-design.md Please let me know your thoughts :) I know it's a Sunday so no rush. |
Beta Was this translation helpful? Give feedback.
-
|
Very excited about this one. It's a huge levelup for emdash. think the current proposal is in a good place, especially with the join table, automatic i18n behavior, and surfacing the relation on both sides as fields instead of hiding it away in a “referenced by” panel. A few additions I think would make the proposal more complete without changing the core direction: 1. Add a stable relation identityRight now the relationship is mainly understood through the two reciprocal field ids. That works technically, but I think it would help to give the relationship itself a stable identity too. Something like:
This could be generated when the pair is created and stored on both field rows without a separate relations table. It gives the relationship something human-readable for debugging, imports/exports, API docs, migrations, and future tooling. For example, if a user creates: The pair could share relationKey = "lesson_chapter". This should probably be editable before creation, then locked afterward, similar to slugs. 2. Add reciprocal field visibilityI like the idea that the reciprocal side is a real field. That feels much better for editors than a hidden backlink panel. But we may want some control over how visible/editable the reciprocal field is. Possible options:
Default could stay editable, matching the current proposal. The reason is that some relationships are useful to edit from either side, while others are mainly useful for navigation. Example: On a Lesson, editors should probably edit the Chapter field directly. This keeps the “real reciprocal field” model, but gives schema designers a way to avoid clutter or accidental edits in the admin UI. 3. Include normal field UI options for reference fieldsReference fields will often be important editorial fields, so I think they should support the same practical field-level affordances as other fields where possible. I would consider adding: A few examples:
defaultValue should still go through the same validation as a manually selected reference. For single-cardinality fields it could be one target group id; for multi-cardinality fields it could be an ordered array. Not all of these have to be required for the first pass, but I think they are worth including in the spec so the reference field does not end up feeling more limited than other field types. 4. Make target status behavior explicitSince the current picker shows all statuses, I think the proposal should explicitly define the behavior rather than leaving it implied.Maybe something like:
My instinct is that the default should probably be all_visible, because that matches the current picker behavior and respects what the editor has permission to see. But the important part is making the rule visible and intentional. Different sites will expect different behavior:
The picker can still show status badges either way, but the field config should decide what is selectable. The initial proposal is already excellent @MA2153. Wanted to add my 2 cents thinking about additional features editors/content managers will deeply appreciate. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Current state
The
referencefield type exists throughout the codebase as a recognized type, but the admin UI was never built out. The scaffolding is all there — the type is defined, the DB column type is mapped, the manifest correctly surfaceskind: "reference"for DB-backed fields — but neither the schema editor nor the content editor has the UI to make it usable.What's missing
1. No collection picker when creating a reference field
FieldEditor(the dialog for adding fields to a collection) has type-specific configuration UI forselect/multiSelect(options list),string/text(min/max length, pattern), andnumber/integer(min/max value). Forreference, there is no step to select which collection the field points to.FieldWidgetOptionsalready hascollection?: stringwith the comment "For reference - which collection to reference", but it's never populated because the UI to collect it doesn't exist.2. Plain text input instead of a content picker when editing content
ContentEditor'sFieldRendererhas aswitch (field.kind)with cases for all the common types. There is nocase "reference":. It falls through todefault:, which renders a plain<Input>— so editors currently see a free-text box and would have to type a raw content ID by hand.ContentPickerModalalready exists (it's wired up inMenuEditorfor picking menu items) and is fully capable of browsing collections with search and pagination. It just isn't wired intoContentEditorfor reference fields.3.
isReferencemarker missing in the static field helperfields/reference.tsreturns a plainz.string()schema with noisReferenceflag. The manifest handler inapi/handlers/manifest.tschecksschema.isReferenceto detect reference fields in the staticlive.config.tspath — but since the flag is never set, that check never fires. Fields defined statically viareference()would getkind: "string"in the manifest instead ofkind: "reference". (The DB-backed path is unaffected — it usesFIELD_TYPE_TO_KINDdirectly and correctly maps to"reference".)Design questions that need answers before implementation
options.collectionpointer should be too.ContentPickerModalshows all statuses.allowMultiple?FieldWidgetOptionsalready hasallowMultiple?: booleanfor reference fields. Should multi-reference be in scope here or deferred?What a complete implementation would involve
FieldEditorwhenselectedType === "reference", persisting the chosen collection tooptions.collection.case "reference":toContentEditor'sFieldRenderer, openingContentPickerModal(or a similar picker) filtered to the collection stored infield.options.collection.fields/reference.tsto tag the schema withisReference: trueso the static manifest path works correctly.Beta Was this translation helpful? Give feedback.
All reactions