Fix datetime round-trip in page properties (#133), shared news cards, shown fields per page type #151

Closed
opened 2026-10-06 00:09:19 +02:00 by dominik.polakovics · 0 comments

This was generated by AI during triage.

Summary

Four follow-ups from the news-workflow analysis, in one pull request:

  1. Page properties refuse to save a page whose date isn't spelled as exact RFC3339 in front matter, so a hand-written or agent-written news item can't be saved. This was reported in #133, which is closed as a duplicate of this issue.
  2. The "Latest news" element renders different cards than the news archive.
  3. A page type can't choose which fields its properties form shows, so some types show backend-layout pickers that make no sense for them.
  4. Page properties show the raw page-type id instead of its label.

(List pagination was part of this issue until the List module was dropped; paging now lives in #153's module screen.)

Current behavior

Dates (#133)

  • The settings read (fieldValue in internal/pageops/settings.go) stringifies every string-shaped value with cast.ToStringE, datetime fields included.

  • Reproduced in triage on main (after #155), with a datetime field date (as news-item declares it). The read hands over these values, and saving them untouched fails on the server with "must be a valid RFC3339 datetime" (element.ValidateValues). The form's own check ("Must be a valid date and time") mirrors that rule, so the browser blocks the save first:

    Front matter Decoded as Handed to the form
    TOML date = 2026-07-10T09:00:00Z time.Time 2026-07-10 09:00:00 +0000 UTC
    TOML date = 2026-07-10T11:00:00+02:00 time.Time 2026-07-10 11:00:00 +0200 +0200
    TOML date = 2026-07-10T09:00:00 go-toml LocalDateTime 2026-07-10T09:00:00
    TOML date = 2026-07-10 go-toml LocalDate 2026-07-10
    YAML date: 2026-07-10, JSON "date": "2026-07-10" string 2026-07-10
    YAML date: 2026-07-10 09:00:00 string 2026-07-10 09:00:00
  • Exact RFC3339 strings work: quoted TOML, YAML (Hugo's YAML decoder hands timestamps over as strings, never time.Time) and JSON. Editor-created pages are unaffected, because the editor writes quoted RFC3339 strings.

  • #153 added content.DateRFC3339 (internal/content/meta.go), "the one wire format every datetime the editor serves uses". The page tree and the module entries endpoint go through it. Triage checked it on every spelling above: each comes out as RFC3339 (offset-less values read in UTC), and an unreadable value reports not-ok.

News cards

  • The news-list shortcode (scaffold/features/news/layouts/shortcodes/news-list.html) has its own copy of the teaser card markup, without image or categories.
  • The section list (layouts/news/list.html) and the category term page (layouts/term.html) render through the shared partials/news-teasers.html, which exists so that their cards cannot drift. The partial draws its own <section class="ce-teasers ce-news-list"> wrapper and renders nothing for an empty list.
  • The element's root tag carries the element's anchor and editor markers (partials/ce/attrs.html: id="c-<uid>" always, data-ce-* under hugo server). ce/attrs.html reads the shortcode context (.Get "uid", .Name, .Page, the ordinal path). The root renders even when the section has no items or doesn't resolve; a theme test pins that.

Fields in page properties

  • The properties form shows the title (the type's own title field, else an implicit one), every field the type declares, and, on a site that declares backend layouts, two implicit pickers (settingsFields and layoutPickers in internal/pageops/settings.go): "Backend layout" (front-matter backendLayout) and "Backend layout for sub-pages" (backendLayoutNextLevel). A page type has no say in which of them show.
  • The sub-pages picker also appears on types that cannot have children (children: [], e.g. news-item). The scaffold ships one-col and two-col, so every new site with news shows it there.

Type label

  • Properties show the raw type id ("Type: news-item") in PageSettings (web/src/components/PageSettings.tsx), both in the page module and on the News module's Properties tab.

Desired behavior

Dates

  • A datetime field's value reaches the properties form as RFC3339 whatever front-matter spelling Hugo reads: every row of the table above.
  • An untouched date saves cleanly, and the saved value is the same instant. A save stores it as the RFC3339 string the form holds, so its spelling may change: a native TOML datetime becomes a quoted string, and a date-only value gains T00:00:00Z.
  • A stored value that can't be read as a time falls back to the field's default, else empty, like every other unconvertible settings value. A required date then asks for one.

Cards

  • news-list renders its cards through news-teasers.html, so "Latest news" and the archive show identical cards for the same item, image and categories included.
  • The element's root tag stays in the shortcode, with its anchor and editor markers, and still renders when there are no items.
  • news-list gains a bool param allNewsLink (label Show "All news" link, default false). When it is on and the section resolves, the element ends with an "All news →" link to the section's URL. It is off by default, so existing elements render as before, apart from the cards.

Fields shown per page type

  • A new optional page-type key, shownFields, lists which fields the type's properties form shows. A name is either a field the type declares in fields:, or one of the two implicit layout pickers, named by the front-matter keys they write: backendLayout and backendLayoutNextLevel.
  • Without the key, every field shows, except backendLayoutNextLevel on a type with children: []. With [], only the title shows. With a list, the title and exactly the listed fields show; a listed backendLayoutNextLevel shows even on a childless type.
  • The title always shows, listed or not, whether it is the type's own title field or the implicit one.
  • These are load errors naming the file:
    • an unknown or repeated name;
    • a required field (other than the title) left out.
  • The key only filters. The form keeps its order whatever the list order: title, declared fields in fields: order, own layout, sub-pages layout.
  • It governs the properties form only: the page module's properties and an editor module's Properties tab. The create dialog keeps its own rule (create:), and editor modules may still list, sort and filter by a field the form doesn't show.
  • On a site without backend layouts the pickers don't show, listed or not, as today.
  • A field the form doesn't show keeps its stored front-matter value untouched, a type: link field's <name>Target companion included. The value keeps working: templates, modules and layout resolution read front matter, not the form.

Type label

  • Properties read "Type: News item": the page type's label. A type without a sidecar shows its id, as today.

Docs

scaffold/site/AGENTS.md and the README (CLAUDE.md rule):

  • document shownFields in the page-type schema: the names it takes, the default, the title and required-field rules, and the untouched stored values;
  • AGENTS.md says a front-matter date may be written in any spelling Hugo reads, and that a properties save stores it back as a quoted RFC3339 string (its datetime paragraph and "Editing content by hand").

Decisions

  • Fix dates on the server's read side, not in the client validator. The wire contract is RFC3339: the server's own ValidateValues rejects anything else, and the client mirrors Go's time.RFC3339.
  • One conversion. The settings read uses content.DateRFC3339, as the page tree and the module entries endpoint already do, so every datetime the editor serves comes from one function. #158 extends the same standard to every other datetime read.
  • Every spelling Hugo reads, not just native TOML datetimes. Triage found local datetimes, date-only values in all three formats and YAML's space-separated form failing the same way.
  • A save may change a date's spelling, never its instant. Front-matter writes are canonical (content.Set always rewrites a set key) and have no time value type. Keeping the original spelling would need one, with no visible gain.
  • Unreadable stored dates fall back like any other unconvertible value (fieldValue's contract: settings reads never fail on odd data).
  • One shared card partial for every rendering: that is the reason the partial exists. The element's root tag stays in the shortcode, because ce/attrs.html needs the shortcode context. The theme's teasers.html partial and page-teasers element are the precedent: the partial draws the list, each caller owns its wrapper.
  • The "All news" link is a plain checkbox with fixed text, off by default, so existing pages render unchanged. Fixed English text matches the theme's other strings (the pager's "Previous" / "Next"); a site owner can change it in the vendored template.
  • The news bundle's version goes up by one (to 3), because its vendored files change; version is what tells bundle revisions apart. No migration or upgrade path: there are no existing sites (maintainer, 2026-10-06).
  • Which fields show is declared per page type, by one generic key (maintainer, in triage): "that way each type can define which fields to show and which not". It covers every field of the properties form, not only the layout pickers. The maintainer prefers a declared key to a hard-coded rule; the children: [] rule becomes the default.
  • shownFields lists what shows (maintainer, in triage). It works like deckle's other lists (children, elements, allowedAt): no key means everything, [] means nothing, a list means exactly those. TYPO3's per-doktype showitem is the same idea. The accepted cost: once a type uses the key, a field added to fields: later stays hidden until it is listed. A hide-list (hiddenFields: [backendLayoutNextLevel]) was rejected: shorter for one hidden field, but a second kind of list.
  • The title always shows. The home page can't be renamed, so hiding its title would leave no way to change it in the editor. On other pages only Rename… would remain, and it also moves the URL.
  • A required field must be listed, as create: on a required field is already a load error: a required field is always asked for.
  • Properties form only. The create dialog has its own key (create:), and module columns, sorts and filters name the fields they use.
  • One issue, one pull request (maintainer, in triage). Each part is small, and #152 waits for this one anyway, because both change the news-list element.

Key interfaces

  • Dates: fieldValue / ReadSettings (internal/pageops/settings.go) and content.DateRFC3339 (internal/content/meta.go). Its other callers are pagetree and entryValue (internal/server/modules.go). element.ValidateValues and the client's isRFC3339 (web/src/components/fields.tsx) stay as they are.
  • Shown fields: settingsFields, layoutPickers and reconcileLayoutOptions (internal/pageops/settings.go) build the form's fields. SaveSettings sets or deletes only those, so a field left out keeps its stored value. pagetype.Schema, its strict loader (rawSchema) and the package doc (internal/pagetype) get the key and its load errors.
  • Type label: PageSettings (web/src/components/PageSettings.tsx), used by PagePane and EntryEditor. Labels already reach the client through /api/pagetypes; pageTypeLabel (web/src/pagemanage.ts) is the existing lookup.
  • The news bundle (scaffold/features/news/): layouts/shortcodes/news-list.html, layouts/partials/news-teasers.html and its callers layouts/news/list.html and layouts/term.html, editor/elements/news-list.yaml, feature.yaml. The theme's partials/ce/attrs.html, partials/teasers.html and shortcodes/page-teasers.html are the precedent. Theme tests: internal/theme/news_test.go.

Acceptance criteria

  • A page with a datetime field date spelled as each row of the table (TOML offset and local datetimes, TOML local date, YAML and JSON date-only strings, YAML 2026-07-10 09:00:00) reads as RFC3339 and saves without touching the date; the saved value is the same instant. The regression test fails before the fix and passes after it.
  • A stored datetime that can't be read as a time reads as the field's default, else empty.
  • "Latest news" and the news section list render identical card markup for the same item, image and categories included.
  • The news-list root keeps id="c-<uid>" and, under hugo server, its data-ce-* markers, and still renders with no items or a stale section.
  • The "All news →" link renders only when allNewsLink is on, and points to the section's URL.
  • Without shownFields, a news-item shows "Backend layout" but not "Backend layout for sub-pages", and a news page shows both.
  • A type with shownFields shows the title and exactly the listed fields, in the usual order; [] shows only the title.
  • An unknown name, a repeated name, and a required field (other than the title) left out of shownFields are each a load error naming the file.
  • Saving properties leaves the stored front-matter key and value of every field the form doesn't show as they were.
  • The create dialog still asks for a create: true field that shownFields leaves out.
  • Properties read "Type: News item" in the page module and on the News module's Properties tab; a type without a sidecar shows its id.
  • The news bundle's version is 3.
  • AGENTS.md and the README document shownFields, and AGENTS.md says how a properties save stores front-matter dates.
  • The PR body links #133.

How to verify

  • make test. It builds web/dist first, which web/embed.go needs; a bare go test ./... fails in a fresh worktree. At triage, go test ./internal/... was green and cd web && npm test passed 65 files, 1818 tests.
  • The theme's Hugo build tests skip silently without hugo on PATH. CI installs extended 0.163.3; run the card tests with it installed.
  • Go: settings regression tests for each date spelling, page-type load tests for shownFields, settings tests for shown and hidden fields, and theme tests for the shared cards and the link.
  • In a browser against harness serve, on a site with harness add news:
    • hand-write a news item with date = 2026-07-10T09:00:00Z (unquoted TOML), open its properties and save without touching the date. The save succeeds, and the file holds the same instant;
    • the item's properties show "Type: News item" and only "Backend layout";
    • add shownFields to a page type and check its properties and its create dialog;
    • compare the "Latest news" cards with /news/ in the preview, and turn the "All news" link on and off.

Assumptions to check

  • Hugo reads an offset-less front-matter date in UTC when the site sets no timeZone (the scaffold's hugo.toml sets none), which matches how content.DateRFC3339 reads it.

Out of scope

  • Every other datetime read (element params, sidecar defaults): #158.
  • Keeping a date's original spelling on save, and honoring a site's timeZone for offset-less dates.
  • Reordering or grouping the properties form (TYPO3's showitem also does that); shownFields only filters.
  • Styling the news cards (the theme has no rules for the card image, date or categories).
  • Which layouts a picker offers: the layouts' allowedAt stays the filter.
  • The category param and the duplicated category option lists (#152 replaces them).
  • List or module pagination (#153).
  • A shared category system (#152).
  • Pruning hidden children from the /api/tree payload: route repair and the link pickers read them.
  • Scheduled publishing (#78).
  • deckle-hosted.

Blocked by

None - can start immediately

> *This was generated by AI during triage.* ## Summary Four follow-ups from the news-workflow analysis, in one pull request: 1. Page properties refuse to save a page whose date isn't spelled as exact RFC3339 in front matter, so a hand-written or agent-written news item can't be saved. This was reported in #133, which is closed as a duplicate of this issue. 2. The "Latest news" element renders different cards than the news archive. 3. A page type can't choose which fields its properties form shows, so some types show backend-layout pickers that make no sense for them. 4. Page properties show the raw page-type id instead of its label. (List pagination was part of this issue until the List module was dropped; paging now lives in #153's module screen.) ## Current behavior ### Dates (#133) - The settings read (`fieldValue` in `internal/pageops/settings.go`) stringifies every string-shaped value with `cast.ToStringE`, `datetime` fields included. - Reproduced in triage on `main` (after #155), with a `datetime` field `date` (as `news-item` declares it). The read hands over these values, and saving them untouched fails **on the server** with "must be a valid RFC3339 datetime" (`element.ValidateValues`). The form's own check ("Must be a valid date and time") mirrors that rule, so the browser blocks the save first: | Front matter | Decoded as | Handed to the form | | --- | --- | --- | | TOML `date = 2026-07-10T09:00:00Z` | `time.Time` | `2026-07-10 09:00:00 +0000 UTC` | | TOML `date = 2026-07-10T11:00:00+02:00` | `time.Time` | `2026-07-10 11:00:00 +0200 +0200` | | TOML `date = 2026-07-10T09:00:00` | go-toml `LocalDateTime` | `2026-07-10T09:00:00` | | TOML `date = 2026-07-10` | go-toml `LocalDate` | `2026-07-10` | | YAML `date: 2026-07-10`, JSON `"date": "2026-07-10"` | string | `2026-07-10` | | YAML `date: 2026-07-10 09:00:00` | string | `2026-07-10 09:00:00` | - Exact RFC3339 strings work: quoted TOML, YAML (Hugo's YAML decoder hands timestamps over as strings, never `time.Time`) and JSON. Editor-created pages are unaffected, because the editor writes quoted RFC3339 strings. - #153 added `content.DateRFC3339` (`internal/content/meta.go`), "the one wire format every datetime the editor serves uses". The page tree and the module entries endpoint go through it. Triage checked it on every spelling above: each comes out as RFC3339 (offset-less values read in UTC), and an unreadable value reports not-ok. ### News cards - The `news-list` shortcode (`scaffold/features/news/layouts/shortcodes/news-list.html`) has its own copy of the teaser card markup, without image or categories. - The section list (`layouts/news/list.html`) and the category term page (`layouts/term.html`) render through the shared `partials/news-teasers.html`, which exists so that their cards cannot drift. The partial draws its own `<section class="ce-teasers ce-news-list">` wrapper and renders nothing for an empty list. - The element's root tag carries the element's anchor and editor markers (`partials/ce/attrs.html`: `id="c-<uid>"` always, `data-ce-*` under `hugo server`). `ce/attrs.html` reads the shortcode context (`.Get "uid"`, `.Name`, `.Page`, the ordinal path). The root renders even when the section has no items or doesn't resolve; a theme test pins that. ### Fields in page properties - The properties form shows the title (the type's own `title` field, else an implicit one), every field the type declares, and, on a site that declares backend layouts, two implicit pickers (`settingsFields` and `layoutPickers` in `internal/pageops/settings.go`): "Backend layout" (front-matter `backendLayout`) and "Backend layout for sub-pages" (`backendLayoutNextLevel`). A page type has no say in which of them show. - The sub-pages picker also appears on types that cannot have children (`children: []`, e.g. `news-item`). The scaffold ships `one-col` and `two-col`, so every new site with news shows it there. ### Type label - Properties show the raw type id ("Type: news-item") in `PageSettings` (`web/src/components/PageSettings.tsx`), both in the page module and on the News module's Properties tab. ## Desired behavior ### Dates - A `datetime` field's value reaches the properties form as RFC3339 whatever front-matter spelling Hugo reads: every row of the table above. - An untouched date saves cleanly, and the saved value is the same instant. A save stores it as the RFC3339 string the form holds, so its spelling may change: a native TOML datetime becomes a quoted string, and a date-only value gains `T00:00:00Z`. - A stored value that can't be read as a time falls back to the field's default, else empty, like every other unconvertible settings value. A required date then asks for one. ### Cards - `news-list` renders its cards through `news-teasers.html`, so "Latest news" and the archive show identical cards for the same item, image and categories included. - The element's root tag stays in the shortcode, with its anchor and editor markers, and still renders when there are no items. - `news-list` gains a `bool` param `allNewsLink` (label `Show "All news" link`, default `false`). When it is on and the section resolves, the element ends with an "All news →" link to the section's URL. It is off by default, so existing elements render as before, apart from the cards. ### Fields shown per page type - A new optional page-type key, `shownFields`, lists which fields the type's properties form shows. A name is either a field the type declares in `fields:`, or one of the two implicit layout pickers, named by the front-matter keys they write: `backendLayout` and `backendLayoutNextLevel`. - Without the key, every field shows, except `backendLayoutNextLevel` on a type with `children: []`. With `[]`, only the title shows. With a list, the title and exactly the listed fields show; a listed `backendLayoutNextLevel` shows even on a childless type. - The title always shows, listed or not, whether it is the type's own `title` field or the implicit one. - These are load errors naming the file: - an unknown or repeated name; - a required field (other than the title) left out. - The key only filters. The form keeps its order whatever the list order: title, declared fields in `fields:` order, own layout, sub-pages layout. - It governs the properties form only: the page module's properties and an editor module's Properties tab. The create dialog keeps its own rule (`create:`), and editor modules may still list, sort and filter by a field the form doesn't show. - On a site without backend layouts the pickers don't show, listed or not, as today. - A field the form doesn't show keeps its stored front-matter value untouched, a `type: link` field's `<name>Target` companion included. The value keeps working: templates, modules and layout resolution read front matter, not the form. ### Type label - Properties read "Type: News item": the page type's label. A type without a sidecar shows its id, as today. ### Docs `scaffold/site/AGENTS.md` and the README (CLAUDE.md rule): - document `shownFields` in the page-type schema: the names it takes, the default, the title and required-field rules, and the untouched stored values; - AGENTS.md says a front-matter date may be written in any spelling Hugo reads, and that a properties save stores it back as a quoted RFC3339 string (its `datetime` paragraph and "Editing content by hand"). ## Decisions - **Fix dates on the server's read side, not in the client validator.** The wire contract is RFC3339: the server's own `ValidateValues` rejects anything else, and the client mirrors Go's `time.RFC3339`. - **One conversion.** The settings read uses `content.DateRFC3339`, as the page tree and the module entries endpoint already do, so every datetime the editor serves comes from one function. #158 extends the same standard to every other datetime read. - **Every spelling Hugo reads, not just native TOML datetimes.** Triage found local datetimes, date-only values in all three formats and YAML's space-separated form failing the same way. - **A save may change a date's spelling, never its instant.** Front-matter writes are canonical (`content.Set` always rewrites a set key) and have no time value type. Keeping the original spelling would need one, with no visible gain. - **Unreadable stored dates fall back like any other unconvertible value** (`fieldValue`'s contract: settings reads never fail on odd data). - **One shared card partial for every rendering:** that is the reason the partial exists. The element's root tag stays in the shortcode, because `ce/attrs.html` needs the shortcode context. The theme's `teasers.html` partial and `page-teasers` element are the precedent: the partial draws the list, each caller owns its wrapper. - **The "All news" link is a plain checkbox with fixed text**, off by default, so existing pages render unchanged. Fixed English text matches the theme's other strings (the pager's "Previous" / "Next"); a site owner can change it in the vendored template. - **The news bundle's `version` goes up by one** (to 3), because its vendored files change; `version` is what tells bundle revisions apart. No migration or upgrade path: there are no existing sites (maintainer, 2026-10-06). - **Which fields show is declared per page type, by one generic key** (maintainer, in triage): "that way each type can define which fields to show and which not". It covers every field of the properties form, not only the layout pickers. The maintainer prefers a declared key to a hard-coded rule; the `children: []` rule becomes the default. - **`shownFields` lists what shows** (maintainer, in triage). It works like deckle's other lists (`children`, `elements`, `allowedAt`): no key means everything, `[]` means nothing, a list means exactly those. TYPO3's per-doktype `showitem` is the same idea. The accepted cost: once a type uses the key, a field added to `fields:` later stays hidden until it is listed. A hide-list (`hiddenFields: [backendLayoutNextLevel]`) was rejected: shorter for one hidden field, but a second kind of list. - **The title always shows.** The home page can't be renamed, so hiding its title would leave no way to change it in the editor. On other pages only Rename… would remain, and it also moves the URL. - **A required field must be listed**, as `create:` on a required field is already a load error: a required field is always asked for. - **Properties form only.** The create dialog has its own key (`create:`), and module columns, sorts and filters name the fields they use. - **One issue, one pull request** (maintainer, in triage). Each part is small, and #152 waits for this one anyway, because both change the `news-list` element. ## Key interfaces - **Dates:** `fieldValue` / `ReadSettings` (`internal/pageops/settings.go`) and `content.DateRFC3339` (`internal/content/meta.go`). Its other callers are `pagetree` and `entryValue` (`internal/server/modules.go`). `element.ValidateValues` and the client's `isRFC3339` (`web/src/components/fields.tsx`) stay as they are. - **Shown fields:** `settingsFields`, `layoutPickers` and `reconcileLayoutOptions` (`internal/pageops/settings.go`) build the form's fields. `SaveSettings` sets or deletes only those, so a field left out keeps its stored value. `pagetype.Schema`, its strict loader (`rawSchema`) and the package doc (`internal/pagetype`) get the key and its load errors. - **Type label:** `PageSettings` (`web/src/components/PageSettings.tsx`), used by `PagePane` and `EntryEditor`. Labels already reach the client through `/api/pagetypes`; `pageTypeLabel` (`web/src/pagemanage.ts`) is the existing lookup. - **The news bundle** (`scaffold/features/news/`): `layouts/shortcodes/news-list.html`, `layouts/partials/news-teasers.html` and its callers `layouts/news/list.html` and `layouts/term.html`, `editor/elements/news-list.yaml`, `feature.yaml`. The theme's `partials/ce/attrs.html`, `partials/teasers.html` and `shortcodes/page-teasers.html` are the precedent. Theme tests: `internal/theme/news_test.go`. ## Acceptance criteria - [ ] A page with a `datetime` field `date` spelled as each row of the table (TOML offset and local datetimes, TOML local date, YAML and JSON date-only strings, YAML `2026-07-10 09:00:00`) reads as RFC3339 and saves without touching the date; the saved value is the same instant. The regression test fails before the fix and passes after it. - [ ] A stored datetime that can't be read as a time reads as the field's default, else empty. - [ ] "Latest news" and the news section list render identical card markup for the same item, image and categories included. - [ ] The `news-list` root keeps `id="c-<uid>"` and, under `hugo server`, its `data-ce-*` markers, and still renders with no items or a stale section. - [ ] The "All news →" link renders only when `allNewsLink` is on, and points to the section's URL. - [ ] Without `shownFields`, a `news-item` shows "Backend layout" but not "Backend layout for sub-pages", and a `news` page shows both. - [ ] A type with `shownFields` shows the title and exactly the listed fields, in the usual order; `[]` shows only the title. - [ ] An unknown name, a repeated name, and a required field (other than the title) left out of `shownFields` are each a load error naming the file. - [ ] Saving properties leaves the stored front-matter key and value of every field the form doesn't show as they were. - [ ] The create dialog still asks for a `create: true` field that `shownFields` leaves out. - [ ] Properties read "Type: News item" in the page module and on the News module's Properties tab; a type without a sidecar shows its id. - [ ] The news bundle's `version` is 3. - [ ] AGENTS.md and the README document `shownFields`, and AGENTS.md says how a properties save stores front-matter dates. - [ ] The PR body links #133. ## How to verify - `make test`. It builds `web/dist` first, which `web/embed.go` needs; a bare `go test ./...` fails in a fresh worktree. At triage, `go test ./internal/...` was green and `cd web && npm test` passed 65 files, 1818 tests. - The theme's Hugo build tests skip silently without `hugo` on PATH. CI installs extended 0.163.3; run the card tests with it installed. - Go: settings regression tests for each date spelling, page-type load tests for `shownFields`, settings tests for shown and hidden fields, and theme tests for the shared cards and the link. - In a browser against `harness serve`, on a site with `harness add news`: - hand-write a news item with `date = 2026-07-10T09:00:00Z` (unquoted TOML), open its properties and save without touching the date. The save succeeds, and the file holds the same instant; - the item's properties show "Type: News item" and only "Backend layout"; - add `shownFields` to a page type and check its properties and its create dialog; - compare the "Latest news" cards with `/news/` in the preview, and turn the "All news" link on and off. ## Assumptions to check - Hugo reads an offset-less front-matter date in UTC when the site sets no `timeZone` (the scaffold's `hugo.toml` sets none), which matches how `content.DateRFC3339` reads it. ## Out of scope - Every other datetime read (element params, sidecar defaults): #158. - Keeping a date's original spelling on save, and honoring a site's `timeZone` for offset-less dates. - Reordering or grouping the properties form (TYPO3's `showitem` also does that); `shownFields` only filters. - Styling the news cards (the theme has no rules for the card image, date or categories). - Which layouts a picker offers: the layouts' `allowedAt` stays the filter. - The `category` param and the duplicated category option lists (#152 replaces them). - List or module pagination (#153). - A shared category system (#152). - Pruning hidden children from the `/api/tree` payload: route repair and the link pickers read them. - Scheduled publishing (#78). - deckle-hosted. ## Blocked by None - can start immediately
dominik.polakovics changed title from Fix datetime round-trip in page properties (#133), shared news cards, layout pickers per page type, List pagination to Fix datetime round-trip in page properties (#133), shared news cards, layout pickers per page type 2026-10-06 00:26:25 +02:00
dominik.polakovics changed title from Fix datetime round-trip in page properties (#133), shared news cards, layout pickers per page type to Fix datetime round-trip in page properties (#133), shared news cards, shown fields per page type 2026-10-07 01:23:38 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/deckle#151
No description provided.