Repository navigation
feat: bind the image widget to an image object in context (Image: $currentObject) - #1482
Closed
tgolembiewski wants to merge 1 commit into
Closed
tgolembiewski wants to merge 1 commit into
tgolembiewski wants to merge 1 commit into
Conversation
…#1476) MDL had no way to show an uploaded image (an object of a System.Image specialisation) on a React-client page. `Image:` on the pluggable Image widget could only name an image collection entry. The legacy `dynamicimage` is CE0582 in React. `image i (Image: $currentObject)` failed check with MDL-WIDGET22 and MDL-WIDGET42. Describe of a Studio Pro page bound this way printed a bare `image i`, which re-executes into "No image selected." `Image: $currentObject` now binds the widget to the enclosing data view's, list view's or gallery's object. The stored shape is Studio Pro's. Measured on 11.12.1 with Image widget 1.5.0 by setting "Image source" to a data view's object and decoding the unit before and after, exactly two values change: imageObject Image '' and EntityRef DirectEntityRef{Entity} defaultImageDynamic EntityRef DirectEntityRef{Entity} `DefaultImage:` is the fallback on `defaultImageDynamic`, written as a plain collection image. The Studio Pro page set no fallback, so this shape was measured in the running app, on an object whose HasContents is false. With the EntityRef beside the image, the widget renders hidden with no src. Without it, the fallback renders. Both shapes pass mx check. Results: - Written by mxcli on the same page, the unit is identical to Studio Pro's once $IDs and TypePointers are stripped. mx check: 0 errors. - describe -> exec reports "Unchanged page". - In a running app, an image uploaded through the File Uploader renders as /file?guid=... with naturalWidth 40 for a 40-pixel PNG. With its contents cleared, the fallback renders instead. These are refused before the write: - an entity that is not an image (mxbuild: CE7247, once per bound property); - a widget with no enclosing data container; - a page parameter or an association path, whose stored shapes have not been measured. Describe prints the binding back. A stored shape MDL cannot spell gets a NOT re-executable note.
AI Code ReviewReview SummaryThis PR implements the ability to bind the Image widget to an image object in context ( What Looks Good
Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
Contributor
Author
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.
Closes #1476
What does it do?
The pluggable Image widget (
image,com.mendix.widget.web.image) can now show animage a user uploaded: an object of an entity that extends
System.Image, taken fromthe enclosing data view, list view or gallery.
dataview Photo_View_Form (DataSource: $Photo) { image Photo_View_Image (Image: $currentObject, DefaultImage: 'Atlas_Core.Content.Mendix') }DefaultImage:is optional. It is the image shown while the object holds none.Before this,
Image:could only name an image collection entry. The legacydynamicimagegets CE0582 in a React-client app, so MDL had no way to show an uploadedphoto on a Mendix 11 page.
Image: $currentObjectresolves to the enclosing data container's entity.It is written as Studio Pro writes it (see below), through a new
WidgetObjectBuilder.SetImageObject.DefaultImageis mapped ontodefaultImageDynamicinimage.def.jsonand written as a plain collectionimage, without the EntityRef (see Measurements for why).
describe pageprintsImage: $currentObjectandDefaultImage:back.Before, a Studio Pro page bound this way described as a bare
image Photo_View_Image,which re-executes into "No image selected.". Stored shapes MDL has no spelling for (an
association path, a page parameter) print a
-- NOT re-executablenote instead of awrong
$currentObject.System.Image(mxbuild would answer CE7247"Widget expects entity of type System.Image.", once per bound property);
$currentObject. Studio Pro also offers a page parameter,but that stored shape has not been measured.
DefaultImagewithout a binding (Studio Pro hides it then) and a binding under anotherImageType. MDL-WIDGET42 no longer calls$currentObjectan expression on thisproperty.
check --referencesresolvesDefaultImagelikeImage.Studio Pro reference shape
Measured with Studio Pro 11.12.1 and Image widget 1.5.0:
image Photo_View_Image (Image: 'Atlas_Core.Content.Mendix')inside
dataview (DataSource: $Photo), wherePhoto extends System.Image.The "Select Entity" dialog offered the page parameter and the data view; the data
view was chosen.
No
SourceVariablewas stored, anddatasourcestaysimage. The reference pageset no default image, so this diff does not cover a chosen
DefaultImage. That shapewas settled in the running app instead (below).
Repro on a blank app
mdl-examples/bug-tests/widgets-1476-image-object-binding.mdlruns on a new Mendix11.12.1 app (React client). It creates
MyFirstModule.Photo extends System.Image, apopup page with the image in a data view, and an overview list with
DefaultImage.mxcli checkofimage (Image: $currentObject)mx checkdescribe page→ exec, both pagesUnchanged pagedescribe pageof a Studio Pro page bound to the data view's objectimage Photo_View_Image(binding dropped)image Photo_View_Image (Image: $currentObject)Measurements
binding by this build. The unit was decoded with
$IDs andTypePointers strippedand keys sorted. It is identical to Studio Pro's "after" unit, and
diffprintsnothing.
mx check: 0 errors.describe→ exec of that page reportsUnchanged page. The storedunit compared with the same normalisation is identical.
mx checkreports CE7247 twice,once for
imageObjectand once fordefaultImageDynamic. With the fix, exec refusesthe script before writing.
run --local, Chromium via playwright-cli). This was a test app usingthe Marketplace File Uploader 2.5.0. Its product page had shown the photo through a
JavaScript-computed URL stored in a String attribute. That image was replaced, by
alter page, withlistview (DataSource: $currentObject/Mod.Product_Photos) { image (Image: $currentObject) }; the overview grid got the same plusDefaultImage.mx check: 0 errors. A 40×40 PNG was uploaded through the File Uploader. The productpage and the overview grid then each render
<img src="/file?guid=…&changedDate=…&name=red40.png">withnaturalWidth40, aftera reload too. Console errors: 0.
HasContentswas set to false inthe database and the page was reloaded:
DirectEntityRef(Studio Pro's shape for an unset fallback), the widget rendered
class="… hidden"with nosrc.<img src="/img/Atlas_Core$Content$Mendix.png?…">withnaturalWidth512.mx check, so only the runtime tells them apart. The writer usesthe second.
written for it was run against the stub. 18 of 18 fail.
Testing
Run locally on macOS, with
TMPDIR=/tmp/tandMX_BINARY=~/.mxcli/mxbuild/11.12.1/modeler/mx(mxbuild 11.12.1; CI's 11.12.2 isLinux-only):
make buildmake testcmd/mxcli/dockerfails on twoSyncJavaDependenciestests (#1396: the orphaned-daemon pipe hangs, then the package times out); both fail the same way on the base commit, and the rest of the package passes with them skippedmake lint-go(aftergit add -A)make check-mdlmake check-findingsmake check-wiki-pages./scripts/check-tunnel-deps.sh./scripts/check-skill-mdl.sh ./bin/mxcli .claude/skills/mendix./scripts/check-skill-mdl.sh ./bin/mxcli docs-site/srcmake test-integrationmdl/roundtrip(484 s) andmdl/executor(500 s).cmd/mxcli/dockeragain: the #1396 hang, plusTestMxBuildCmd_HungBuildIsKilledfailing under the package's load; that test passes alone on this branch and on the base commitgovulncheck ./...mdbook build docs-site(mdBook 0.5.2)language/versions.md, untouched hereMendix validation
mx checkwith 0 errors, and so does03-page-examples.mdlwith the newP042b_ImageObject.object without contents.
Agentic Code Testing
widget in a data view over the object, or use an entity that extends
System.Image.
create-pageSKILL.md andreference/widgets.md,mxcli syntax page,docs-site/src/language/widget-types.md,MDL_QUICK_REFERENCE.md.from the CLI on macOS.
session. The issue came from an agent session that tried three wrong variants;
the syntax help and the MDL-WIDGET22 suggestion now name this form.
Not in this PR
ImageTypeis still stored as written. For example,ImageType: dynamicImagepasses check andmx checkbut is not a value of the widgetenumeration. This is a separate concern and will get a separate PR.
Image: $Photo,Image: $currentObject/Mod.Assoc) is refused. The Studio Pro shapes for thesebindings have not been measured. A data view over the object is the supported route.
mdl/backend/mcp) reportsSetImageObjectas unsupportedrather than guessing its payload.
Image: $currentObjectforany stored
DirectEntityRefwithout a source variable, and does not compare thatentity with the enclosing container's. A Studio Pro page bound to a different
image entity than its container would re-execute to the container's entity. This
case has not been seen or measured.
check. Exec refuses beforewriting, but
mxcli check --referencesdoes not yet report it.