feat(editor): translate sidecar labels through language files beside each sidecar #258
No reviewers
Labels
No labels
bug
enhancement
needs-triage
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/deckle!258
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/227"
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?
Closes #227
What
Language files:
<family>/<name>.<tag>.yamlbeside a sidecar translates its text (elementlabel/description/category/items/params, page typelabel/fields, backend layoutlabel/columns, modulelabel), keyed by name.internal/sidecardirowns recognition (LangFile, viapagepath.ValidLangTag) and pairing; each family decodes its own keys. These are load errors against the language file: a file with no source, a param/field/column/items the source lacks, a non-text key, or a duplicate.yaml/.yml. Missing or empty entries fall back to the sidecar's own text, and a language file whose source failed to load is skipped silently.Wire: additive
i18n(tag → {label, description, category}, omitted when empty) on these objects:FieldInfo, filterFormField, the form's items description (i18n/itemI18n)layoutSites without language files serve byte-identical responses (checked on
testdata/site: noi18nkey in any of the four list endpoints).Client:
web/src/api/labels.tsresolveslabelCode→i18n[locale()]→label, and description/category the same way without the code step. The decoders resolve in place. The insert dialog groups by the written category, shows the translated one and sorts the side list by it; search matches both.Scaffold: 29
.de.yamlfiles (17 elements, 3 page types, 2 backend layouts, news and categories bundle sidecars and modules), followingweb/src/i18n/glossary.md. Bundle versions are bumped to news 6 and categories 3, so re-adding fills the language files in.harness add/removetreat language files as ordinary bundle files and never count them as types. That covers receipt type lists, bundle validation context and the children sweep.Docs and skills: AGENTS.md ("Languages", the new "Sidecar language files", the element, page-type and module sections), the theme README layout table, README (Scaffolding, Feature bundles, API shapes). Skills updated: add-element, add-page-type, add-backend-layout, create-feature, setup-site, verify-site, plus remove-element and redo-theme where a statement became false.
Tests
i18nchanges" invariant in every family. JSON tests showi18nabsent without language files.checkcmd: language-file load errors.TestShippedSidecarsHaveCompleteGermanFilesnames the German file and the missing key.TestShippedGermanSetLoadsruns the real loaders.harness sidecar.Verification
make build,go test ./...,go vet ./...,gofmt -l ., vitest (3143) andtsc --noEmitall pass. Hugo is not on PATH here, so the Hugo-backed tests skipped.harness init --lang de+harness add news+harness check: 0 problems, 29.de.yamlfiles, all listed in the receipts.icon:key each give a load error against the language file./api/elementsshows the German map forcards.🤖 Generated with Claude Code
[autoland] verdict: pass
PASS — validated by the lander.
Signal: CI aggregate
success(ci / build-and-test: npm build + vitest, go vet, go test ./... with Hugo 0.167.0, so the agentsdoc and skills drift tests ran). Also checked locally:tsc --noEmitclean (CI's vite build does not type-check), gofmt clean on the changed Go files. Branch is level with main (merge base = main head), so there is nothing to resolve.Conventions: Conventional Commits title;
Closes #227present; the diff matches #227's contract. It covers the language files in all four families via sidecardir.LangFile/Load, the additive omitemptyi18nwire map, client resolution in api/labels.ts, 29 .de.yaml files and the AGENTS.md, theme README, README and skills updates CLAUDE.md requires.One-owner check:
sidecardir.LangFileis the single language-file recogniser (loaders, receipts, children sweep, bundle validation).pagepath.ValidLangTagowns the tag. Element description/category rules are shared with the source through parseDescription/parseCategory. No sibling copies found.Notes (non-blocking):