Page tree browsing: content/<lang>/ tree UI with page selection and element list #4
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/deckle#4
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
The TYPO3-style left pane, read-only (docs/DECISIONS.md D8, D17): read the
content/<lang>/directory (single language for now, but page identity is (path, lang) internally), render sections and leaf-bundle pages as a tree ordered byweight, and on selection show the page's element list (element type labels + icons from sidecars) in the center pane.Acceptance criteria
_index.md) and leaf bundles from the sample site, ordered by weight then titledraft: true) are visually distinct in the treeBlocked by
Agent Brief
Category: enhancement
Summary: Replace the placeholder page-tree pane with a real, read-only tree of the site's
content/<lang>/directory — sections and leaf-bundle pages ordered by weight then title, drafts visually distinct — and on page selection show the page's element list (schema-derived labels + icons) in the center pane.Dependency note: this issue is hard-blocked by #1 (walking skeleton), which is merged: it provides the harness binary, the embedded SolidJS shell with a placeholder tree pane, the supervised Hugo preview, and the
/api/statuspolling pattern. It also consumes #2's shortcode round-trip engine (merged) for element lists. #3 (sidecar schemas + generated form) is not a hard block and may run concurrently — the scheduler handles ordering; see below for how to integrate with it either way. The issue body'sdocs/DECISIONS.mdD8/D17 references point at a file that is not committed — this brief is self-contained.Current behavior:
The tree pane in the SPA renders a hard-coded fake tree with a "Page tree coming soon" hint. No API exposes the content directory structure; the only content-related endpoint is a debug endpoint that returns one page's parsed element tree given a content-relative path. The content engine parses a file into a document whose front matter is kept as a raw, undecoded string — nothing currently extracts
title,weight, ordraft. The sample site is a flatposts/section of plain.mdfiles: no leaf bundles, no_index.mdsections, no weights.Desired behavior:
Tree data. The harness API gains an endpoint returning the page tree for a language. It walks the language's content root, building a nested structure of:
_index.mdindex.md.mdpages, which existing sites contain (the sample site does today); the read-only view must not hide content, so these appear as leaf pages even though leaf bundles are the canonical form going forward (#9 only ever creates bundles)Each node carries: page identity, kind (section vs page), title,
weight, anddraft, extracted by decoding the page's front matter. Siblings are ordered by ascending weight then title, with unweighted pages sorting after weighted ones (matching Hugo's ordering, so the tree mirrors site navigation). A page whose front matter fails to decode still appears in the tree (fallback title from its slug/filename) with the problem surfaced rather than breaking the whole tree.Page identity is (path, lang). Internally and on the wire, a page is identified by the pair (content-relative path, language) — never by a bare path. The site is single-language for now and the language's content root is resolved in exactly one place, so a multilingual layout (
content/en/,content/de/) later plugs in without reworking callers. No code path may assume a flatcontent/root is the only shape. Paths crossing outside the content root are rejected.Tree pane. The SPA tree pane renders this data with expand/collapse for sections and single selection. Disabled pages (
draft: true) are visually distinct (e.g. dimmed and/or badged). This is read-only: no create/rename/delete affordances (that is #9).Element list. Selecting a page fetches its parsed element tree and lists the page's elements in document order in the center pane. Shortcode elements display a label and icon derived from the element sidecar schemas (#3's schema API) when a matching schema exists; elements with no matching schema fall back to the shortcode name and a generic icon. Plain text/markdown runs between shortcodes may be shown as a generic body item or omitted — implementer's choice, but element ordering must be preserved.
#3 integration. Selecting an element in the list opens the schema-generated form from #3 if that feature is present in the codebase. If #3 has not landed yet, put the selection behind a minimal interface — a narrow "element selected" hook carrying the page identity plus the element's position within the page — with a placeholder implementation (e.g. a neutral detail pane), so #3's form can be wired in without reworking the tree or element list.
State survival. Expanded nodes and the current selection survive a preview LiveReload and any tree-data refresh: the preview iframe reloading must not disturb the SPA, and re-fetching the tree (poll or change-triggered refresh) must not collapse expansion or drop selection — follow the same "don't touch signals whose values haven't changed" discipline the status polling already uses. Nodes that disappeared on disk are pruned gracefully (a deleted selected page results in a cleared selection, not a broken UI).
Sample site. Extend the sample site so the feature is demonstrable and testable: at least one section with
_index.md, leaf-bundle pages withweights that exercise the ordering, and a draft page (one already exists).Key interfaces:
Acceptance criteria:
_index.md), leaf bundles, and existing plain.mdpages, each with identity, kind, title, weight, and draft flag, ordered by weight then title (unweighted after weighted)draft: true) are visually distinct in the treeOut of scope: