Skip to content

Cover the image widget in the mx check gate, and fix the layout reference docs - #376

Merged
ako merged 2 commits into
mainfrom
claude/mendix-default-styling-1fgvpm
Sep 2, 2026
Merged

Cover the image widget in the mx check gate, and fix the layout reference docs#376
ako merged 2 commits into
mainfrom
claude/mendix-default-styling-1fgvpm

Conversation

@ako

@ako ako commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Follow-up to the authorable-layouts arc (#304). Two gaps it left behind: the CI gate builds no image widget, and the user manual for layouts was never updated.

No behaviour changes — one test-coverage commit and one docs commit.

1. The doctype gate built zero image widgets

03-page-examples.mdl said "No pluggable replacement exists. Image examples are therefore not included in this test file." That was wrong — image routes to com.mendix.widget.web.image.Image, and only the built-in staticimage/dynamicimage are deprecated (CE0582).

The consequence: the gate ran green through two separate image defects, both fixed in 597db1b with nothing here to catch a regression. bug-tests/ documents them, but TestMxCheck_DoctypeScripts only executes doctype-tests/*.mdl — that is what CI runs.

Three variants, chosen so the coverage is not a smoke test:

Widget Why
pixels / 36 width is a visible property, taking the authored value by the ordinary route
default units width/height are hidden under auto — the path that actually regressed
imageUrl mode source lives in a text template, not the Image field

The middle one is the point. A hidden property must be written with its declared default rather than skipped; skipping leaves whatever the widget template captured, and image.json was extracted from a 48px logo — 48 against a declared 100 is CE0463 on every image widget. Nothing in the authored MDL distinguishes the two behaviours, which is why it needs a gate rather than a test asserting what the script says.

Non-vacuity measured, not assumed. With hiddenUnnamedProperties' default-writing stubbed back to the pre-597db1b2 skip, the gate reports CE0463 on all three widgets; with it in place, 0 errors. Omitting the Image: line likewise turns mx check red with "No image selected.".

Full gate run: green (578s).

2. The layout reference on the site was wrong, not just thin

docs-site/ was the one artifact the layouts arc never updated. create-layout.md predated all of it:

  • Its synopsis does not work. It documented CREATE LAYOUT module.Name { widget_tree } — no header. Run verbatim: Error: layout needs a layouttype.
  • class was absent, and it is load-bearing: Atlas scopes its layout rules to .layout-atlas, so a layout without one builds cleanly, passes mx check, and renders with no topbar bar and no sidebar rail.
  • Missing entirely: OR REPLACE, the scrollcontainer / region / placeholder / navigationtree vocabulary, and the Marketplace refusal.
  • It sent readers away: "For advanced layout customization, use Mendix Studio Pro" — for something mxcli has done since feat(pages): authorable layouts — CREATE, ALTER, repoint, and a scaffold for new projects #304.
  • Neither "Example" was a CREATE LAYOUT. Both were CREATE PAGE statements naming an Atlas layout.

alter-layout.md is new — ALTER LAYOUT and the bulk ALTER PAGES … SET LAYOUT migration form had no page on the site at all. It covers addressing a region by slot, why ALTER beats CREATE OR REPLACE for a layout you did not write, and the guard's refusal semantics.

alter-page.md already documented the single-page SET Layout correctly, so it gains only the placeholder-guard note and a pointer.

Also: layout is a real top-level syntax path but was missing from the hand-maintained topic list in help.go, so mxcli syntax layout worked only if you already knew the word.

Everything documented was executed

Every code block ran against a real 11.13 project (result: 0 errors), and every quoted error message was produced by running the case that raises it — the Marketplace refusal, the unknown-header-property error, the no-placeholder refusal, and the placeholder guard with its MAP remedy.

That caught one claim I would otherwise have written from memory: a cross-platform layouttype is not refused. layouttype: 'Popup' is accepted and creates a native Popup layout, because the platform is inferred from the type. The page says "inferred", because that is what happens.

Testing

  • Unit suite: green
  • TestMxCheck_DoctypeScripts (integration): green, 578s
  • Every documented statement exec'd against a real project → mx check 0 errors
  • Controls: pre-fix engine behaviour → 3× CE0463; missing Image:"No image selected."

Note on scope

An earlier version of this branch also carried a fix for the image defects. It turned out to be redundant — 597db1b2 had already fixed both on main, by a better route (changing the hidden-property invariant for every widget rather than editing one template's values). That work was dropped and the branch restarted from current main; only the coverage and docs remain.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JEZmExJUvn2nWTWE9mrd4i


Generated by Claude Code

This gate built ZERO image widgets, so it ran green through both image
defects fixed in 597db1b -- the CE0463 on every image widget mxcli wrote,
and the image reference that could not be authored at all. The file said
"no pluggable replacement exists" and skipped images entirely, which was
wrong: `image` routes to com.mendix.widget.web.image.Image. Only the
BUILT-IN staticimage/dynamicimage are deprecated (CE0582) and those stay
out. bug-tests/widget-image-collection-entry.mdl documents the fix, but
bug-tests/ is not what CI runs -- TestMxCheck_DoctypeScripts reads only
doctype-tests/.

Three variants, chosen so the coverage is not a smoke test:
  - pixels/36, where width is a VISIBLE property
  - default units, where width and height are HIDDEN -- the case that
    regressed, since a hidden property must be written with its declared
    default rather than skipped onto whatever the template captured
  - imageUrl mode, whose source is a text template rather than the Image
    field

Non-vacuity measured against the fix that is actually in the tree, not a
reconstruction of it: with the declared-default write in
hiddenUnnamedProperties reverted to a plain skip, this script reports
CE0463 on all three widgets; restored, 0 errors. Omitting the `Image:`
line likewise turns mx check red with "No image selected.".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEZmExJUvn2nWTWE9mrd4i
The user manual was the one artifact the authorable-layouts arc never
updated, and it was wrong rather than merely thin.

create-layout.md documented `CREATE LAYOUT module.Name { widget_tree }`
-- no header at all. Run verbatim that is an error, not a shortcut:
"layout needs a layouttype". It omitted `class`, which is load-bearing
(Atlas scopes its layout rules to .layout-atlas, so a layout without one
builds clean, passes mx check and renders with no topbar bar and no
sidebar rail), omitted OR REPLACE, the scrollcontainer/region/placeholder/
navigationtree vocabulary and the Marketplace refusal, and told the reader
"for advanced layout customization, use Mendix Studio Pro" -- for
something mxcli has done since #304. Neither of its two "Examples" was a
CREATE LAYOUT; both were CREATE PAGE statements naming an Atlas layout.

Rewritten from measurement: every statement in both pages was executed
against a real 11.13 project and every quoted error message was produced
by running the case that raises it, including the marketplace refusal, the
unknown-header-property error, the no-placeholder refusal and the
placeholder guard with its MAP remedy. The resulting project is 0 errors.

alter-layout.md is new: ALTER LAYOUT had no page on the site at all, nor
did the bulk `ALTER PAGES ... SET LAYOUT` migration form. It covers
addressing a region by slot, why ALTER beats CREATE OR REPLACE for a
layout you did not write, and the guard's refusal semantics. alter-page.md
already documented the single-page SET Layout, so that section gains only
the guard note and a pointer.

Also: `layout` is a top-level syntax path but was missing from the
hand-maintained topic list in help.go, so `mxcli syntax layout` worked
only if you already knew the word.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEZmExJUvn2nWTWE9mrd4i
@ako
ako merged commit f120e91 into main Sep 2, 2026
15 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants