feat(properties): support nested YAML frontmatter via dot-notation keys#1157
Merged
Conversation
When a property key contains dots (e.g. "a.b"), the editor now stores it as proper nested YAML (a:\n b: value) instead of a flat literal dot-key. Sibling dot-keys sharing a parent are grouped under one YAML block. The backend flattens nested ExtraFields maps with dot-joined keys so the properties index (a.b = value) and the page API response both reflect the nested structure. Guards added: depth limit (20) in extractFlatEntry, leafwiki_ prefix filter for child segments, and conflict detection in the field tree (scalar vs. mapping at the same path falls back to flat output).
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds end-to-end support for nested YAML frontmatter properties by treating dot-notation keys as structured YAML in the editor, while flattening nested YAML maps back into dot-joined keys on the backend for indexing and API responses.
Changes:
- UI: Parse nested YAML maps into dot-notation keys and serialize dot-notation keys back into nested YAML blocks (with sibling grouping and conflict fallback).
- Backend: Flatten nested YAML maps into dot-notation keys when extracting page metadata and indexing properties, with added recursion-depth and reserved-prefix guards for indexing.
- Tests: Add Vitest coverage for editor frontmatter round-trips and Go tests for nested-map property extraction.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/leafwiki-ui/src/features/editor/frontmatter.ts | Adds nested-map parsing and a field-tree serializer to emit nested YAML for dot-notation keys. |
| ui/leafwiki-ui/src/features/editor/frontmatter.test.ts | Adds Vitest coverage for nested map parsing/building and round-trip behavior. |
| internal/wiki/pages/routes.go | Updates page metadata extraction to flatten nested YAML maps into dot-notation properties for API responses. |
| internal/properties/properties_service.go | Flattens nested YAML maps into dot-notation keys for the properties index with depth and reserved-prefix protections. |
| internal/properties/properties_service_test.go | Adds tests validating nested map flattening, reserved child filtering, and depth limiting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- addToFieldTree: return false when an identical-path leaf already exists,
preventing silent overwrites when two keys collapse to the same path
after split('.').filter(Boolean)
- flatFallbacks: serialize list-type conflicted fields correctly instead
of emitting them as bare scalars
- flattenMetadataEntry (routes.go): add depth limit (20) and skip child
segments starting with leafwiki_ — mirrors the guards already present
in extractFlatEntryDepth
- Rename misleading test case that described a list block as
"unsupported nested content"
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.
When a property key contains dots (e.g. "a.b"), the editor now stores it as proper nested YAML (a:\n b: value) instead of a flat literal dot-key. Sibling dot-keys sharing a parent are grouped under one YAML block.
The backend flattens nested ExtraFields maps with dot-joined keys so the properties index (a.b = value) and the page API response both reflect the nested structure. Guards added: depth limit (20) in extractFlatEntry, leafwiki_ prefix filter for child segments, and conflict detection in the field tree (scalar vs. mapping at the same path falls back to flat output).