editor: engine-generated form labels stay English in a translated editor #236
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#236
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?
Summary
Every form label and note the engine composes in Go (not a sidecar) carries a message code next to its English text, so the editor translates it through the catalog the way it already translates the Enabled switch and the Yes/No filter options. In a German editor the translation properties form, a page's Appearance tab and the module list headers stop showing English.
Current behavior
The engine builds a few form fields and labels itself, as plain English strings, and the client shows them as written. Verified sites (2026-10-13):
internal/pageops/translation_settings.go:translationSlugField(label "Address segment"), on every translation's properties form, andtranslationReadOnlyNote("Follows the default-language page; change it there."), set asFormField.Noteon each read-only field of a translation form.internal/pageops/settings.go: the implicit title field (label "Title") and the two Appearance-tab selectsFieldBackendLayout("Backend layout") andFieldBackendLayoutNextLevel("Backend layout for sub-pages").internal/editormodule/load.go:builtinLabel("Title", "Date", "Status") — theFieldInfo.Labela module's columns, cards and sort control get for a built-in field no listed page type declares.The wire already has the pattern for this:
element.FormField.LabelCodeandeditormodule.FilterOption.LabelCodecarry anapimsgcode (label.enabled,label.yes, …), and the client translates by code indecodeFormDescription(web/src/api/forms.ts) and infetchModules(web/src/api/modules.ts). The five sites above have no code;FormField.Notehas no code field at all;FieldInfohas noLabelCode.Desired behavior
label.*in theapimsgregistry, next to the existinglabel.home,label.enabled…) on the wire, in the field the existing pattern uses:labelCodeonFormFieldand onFieldInfo. The Englishlabeltext is unchanged, byte for byte.FormField.NotegainsnoteCodethe same way; the read-only translation note is the first user.server.<code>entry for every new code, so the parity test (which reads the exported registry) passes; the German wording followsweb/src/i18n/glossary.md(register and terms; "Seite", "Bereich", …).labelCode/noteCodeit receives in one place: one helper in the api layer that resolves a label-bearing object's display text (code → catalog, else the text as sent).decodeFormDescriptionandfetchModulestoday each inline the same code→label step; replace both with the helper rather than adding a third copy. #227 extends this same helper with site-authored translations, so it must be the single point where "what label do I show" is answered.Decisions
labelCodefield and thelabel.*namespace rather than a newengine.*scheme — the field and the client path exist; a parallel mechanism would be a second owner of the same rule.Key interfaces
apimsgregistry (internal/apimsg/codes_core.goholds theLabel*codes) and its export test that writesweb/src/i18n/servermessages.json.element.FormField(internal/element/form.go):LabelCode, newNoteCode.editormodule.FieldInfo(internal/editormodule/schema.go) andbuiltinLabel/fieldLabelinload.go.pageopssettings builders insettings.goandtranslation_settings.go.web/src/api/forms.ts(decodeFormDescription),web/src/api/modules.ts(fetchModules),serverMessagein the api layer;web/src/widgets/FormFields.tsxshowsfield.noteas the hint.web/src/i18n/en.json,de.json; parity testweb/src/test/i18nParity.test.ts.labelCode) in the API section — addnoteCodeand theFieldInfocode there.Acceptance criteria
Accept-Language: de, a translation's properties form shows the address-segment label and the read-only note in German; a page's Appearance tab shows both backend-layout selects in German; the properties form's title field is "Titel"; a module whose page type does not declare title/date shows German column headers and sort labels.en.jsonandde.json; the parity test passes.forms.tsandmodules.tsboth call it and no longer inline the lookup.noteCodeand the module field'slabelCode.How to verify
make test;make build.harness serve --site testdata/multilingual-site, browser in German: open a translation's properties (address segment + note), a page's Appearance tab, and the news module ontestdata/siteafter removingtitlefrom a listed page type's fields to see the built-in label.curl -s http://127.0.0.1:8090/api/formfor a translation page: the fields carrylabelCode/noteCodenext to unchangedlabel/note.Assumptions to check
label.*code cannot land untranslated.Label:string literals ininternal/pageopsandinternal/editormodulebefore closing.Out of scope
Blocked by
None - can start immediately
Original report
Found during the German layout pass (#226).
A few form fields and notes are not authored by the site but generated by the engine in Go, as plain English strings, so they stay English when the editor runs in German:
internal/pageops/translation_settings.go:translationSlugField.Label"Address segment" (shown on every translation's properties form) andtranslationReadOnlyNote"Follows the default-language page; change it there."internal/pageops/settings.go: the implicit "Title" field label (line ~85), and the backend-layout selects "Backend layout" / "Backend layout for sub-pages" (line ~427).These are not site-authored labels (which #225/#226 deliberately leave untranslated), so the editor's catalog should cover them. #226 kept the server unchanged (out of scope there), so this needs a small server-side change: send a stable label key (or code, as #224 did for errors) next to the English label, and translate it in the client catalog with an
engine.*/form.engine.*key inen.jsonandde.json.Acceptance: with
Accept-Language: de, a translation's properties form and a page's Appearance tab show German labels for these fields; the parity test covers the new keys.