New page field type with shared page-tree picker; news-list section becomes a picked page reference #83
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/deckle#83
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What to build
A ninth engine field type
page: a reference to a site page, stored as the canonical pretty URL (/news/) — the same value shape aslink, so the existinglinkrefswhole-value matching gives rename/move rewriting and delete-warnings for free (zero linkrefs changes). An optional sidecar keypageType:restricts selection: the picker shows the whole tree with non-matching pages visible but disabled. The server validates on save: 422 with an inline field error if the referenced page does not exist or is not the declaredpageType. No implicitTargetcompanion param.UI: extract the tree-browse from
LinkPicker's Internal tab into a shared component;LinkPickercomposes it, and a new thin page-picker dialog wraps it for thepagefield. The field widget follows theLinkFieldchip pattern (Choose… / Edit… / Clear, server-resolved label), no free-text path input.News bundle:
news-list.yamlflipssectionfromtexttopagewithpageType: news. The shortcode is unchanged, so existing hand-typed values likenewskeep resolving; already-vendored sites update by re-runningharness add news(no migration machinery).Key code:
internal/element/schema.go(FieldType),web/src/components/LinkPicker.tsx,web/src/components/fields.tsx,scaffold/features/news/editor/elements/news-list.yaml,scaffold/site/AGENTS.md,internal/element/agentsdoc_test.go(drift test).Acceptance criteria
page(element params and page-type fields) with optionalpageType:restriction; value stored as canonical pretty URLpageType; rendering still degrades to an empty list on a stale valueLinkPicker's Internal tab;LinkPickerbehavior unchangedpagefield widget: chip with Choose…/Edit…/Clear opening the page-picker dialog; non-matching page types visible but disabled whenpageType:is setnews-list.yaml:sectionispage+pageType: news; shortcode untouched; old plain-path values still renderpagevalues via existing linkrefs pass (test proves it)scaffold/site/AGENTS.mddocuments thepagetype andpageType:; drift test passesBlocked by
RawParam/element.Paramsidecar schema (internal/element/load.go,internal/element/schema.go) and both editscaffold/site/AGENTS.md; serialized to avoid conflicting parallel edits (no functional dependency)Triage addendum — verified against the codebase
The brief's core premise checks out; one acceptance criterion is softened below. Facts for the implementing agent:
Confirmed:
validFieldTypes(internal/element/schema.go~33–42). Page-type fields reuse the same vocabulary viaelement.ParseParams, so addingpagethere covers element params and page-type fields at once. The drift test (internal/element/agentsdoc_test.go) mechanically forces the new type to be named inscaffold/site/AGENTS.md.internal/linkrefs/linkrefs.godoes whole-value prefix matching over every string shortcode param and front-matter value — it never enumerates field types. Apagevalue stored as a canonical pretty URL gets rename/move rewriting (rewriteValue, viainternal/pageops/relocate.go) and delete-warnings (References, viainternal/server/linktargets.go) with zero linkrefs changes.pageType:restriction key is new (add toRawParamininternal/element/load.go+element.Param— both sidecar loaders are strict-YAML). A page's type for validation = front-mattertype, else the section-name convention — seeeffectiveTypeininternal/pagetree/build.go(~382–421).handlePageSettingsSaveininternal/server/pageops.go(~364–405) andelement.FieldError/Schema.ValidateValuesininternal/element/values.go.LinkTreeRowinweb/src/components/LinkPicker.tsx(~139–199) is already standalone behind theLinkTreeOpsinterface; what needs lifting into the shared component is the surrounding tree state (selected/expandedsignals,fetchTreeresource,findChain, the pre-fill effect). The right-pane commit rows and tab machinery stay LinkPicker-specific.LinkField(web/src/components/fields.tsx~518–637) is the chip pattern to mirror — note it resolves labels viaresolveLink, non-blocking with raw-href fallback.<name>Targetreservation is gated onType == TypeLink(schema.go~207–217), sopagesimply stays out of it.Softened criterion — shortcode: the brief says the shortcode is untouched, but
news-list.htmlresolves viasite.GetPage (.Get "section"), which takes a Hugo content path (news,/news). Whether it also accepts the stored canonical pretty URL/news/is unverified — nothing normalizes the value. Verify empirically (render a site with a/news/-form value); ifGetPagedoesn't resolve it, a minimal normalization inside the shortcode (e.g. trimming the trailing slash beforeGetPage) is in scope. Old hand-typed plain-path values must keep resolving either way, and rendering must still degrade to an empty list on a stale value.Coordination note: #81 also adds a key to
RawParam/element.Paramand touchesAGENTS.md— expect a small rebase if both are in flight simultaneously.Blocked by
RawParam/element.Paramsidecar schema (internal/element/load.go,internal/element/schema.go) and both editscaffold/site/AGENTS.md. Serializing behind #81 avoids a conflicting parallel edit; there is no functional dependency.(Supersedes the "Blocked by: None" section in the issue body, which cannot be edited via the tracker CLI.)