Repository navigation
Conversation
Widgets learned where the form is from the edit route's loader data or the URL. The image widget guessed its path from the URL, which on the add form is /@@add/..., so its object browser asked the API for /@@add and the error page replaced the form (#163). Forms now provide a widget context: mode, path (the edited object, or the container a new object goes to), and containerPath (where uploads go). ContentForm takes the path from its route, control panels use the site root, and block settings inherit the content form's. - ObjectBrowserWidget starts from the context, and follows its field's value when it changes outside the browser. - QuerystringWidget no longer reads the edit route's data. - ImageWidget browses and uploads from the context. With the extraFields widget option it stores a picked image's details in sibling fields; the image block's url field uses it, so images picked in the sidebar keep their scales. - RecurrenceWidget reads its own value prop. - The object browser listing returns no items for a path the API rejects, instead of failing the page. Closes #163 Refs #243
This was referenced Oct 9, 2026
Adds a Core widgets reference page: for each widget cmsui registers, what it is registered for, the value it reads and writes, and its widget options, including the image widget's new extraFields, with the image block's schema as the example. It also documents the object browser's value (the selected items, with their selectedItemAttrs), and that Volto's link and image modes and allowExternals aren't supported yet.
Member
Author
|
LGTM |
Resolves the TODO in the @objectBrowserWidget loader. The root middleware already loads the browsed folder for this request, with its breadcrumbs expanded, so they are as fresh as the loader's separate getBreadcrumbs call, which is dropped. The loader's error handling only ever covered the search: if the folder doesn't exist, the middleware fails the request before the loader runs. Its comment now says so. Adds unit tests for the loader, and checks in the acceptance test that the browser shows the folder in its breadcrumbs.
…widget-context * origin/feat/widget-adapters: Restore files the pre-commit hook reformatted Validate schema-driven forms (#256) Move the recurrence modal off TanStack Form (#254) Move the forms onto the helpers form store (#253) Add a Jotai-native form layer to helpers (#252) Render every schema form through one field renderer (#251) Document and type the form widget contract (#97) Match utility dependencies exactly in the registry (#259)
…widget-context * origin/feat/widget-adapters: Add the components changelog entry for the picker rename
sneridagh
added this pull request to stack #270
October 10, 2026 22:48
This branch has not been deployed
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.
#243 step 5. Stacked on #260. Closes #163.
Problem
Widgets learned where the form is by reading the route:
ObjectBrowserWidgetandQuerystringWidgetread the edit route's loader data (useLoaderData<typeof editLoader>()).QuerystringWidgetdidn't even use the result.ImageWidgetguessed its path fromwindow.location. On the add form, the URL is/@@add/<container>?type=…, so its object browser asked for/@objectBrowserWidget/@@add. plone.restapi rejected the path, the resource route threw, and the error page replaced the whole add form. That's Add Image Content tab crashes because the image field is rendered as a TextField #163: the Image add form, and any type with an image field, crashed on its Content tab.Changes
WidgetContext(components/Form/WidgetContext.tsx):useWidgetContext()gives:mode:add,editorsettings;path: the edited object, or the container a new object is added to;containerPath: where new objects go (the parent when editing, the container when adding).ContentFormprovides it from a newpathprop, set by the edit and add routes. Control panels provide the site root. Block settings render inside the content form, so they inherit its context. Without a provider (Storybook), it's the site root.ObjectBrowserWidgetstarts browsing frompath, and its selection follows the field's value when it changes outside the browser (before, it only read it on mount).QuerystringWidget: the unused edit-route read is removed.ImageWidgetbrowses frompathand uploads tocontainerPath; explicitcurrentPath/uploadPathprops still win. Its extras (image_field,image_scales) were dropped by the form, which only forwardsvalue. With the newextraFieldswidget option, it writes them to the sibling fields of the same name, in one change. The image block'surlfield declares it, so an image picked in the sidebar keeps its scales, as one picked in the block's own placeholder does. Without the option (content forms, the block's placeholder), nothing extra is written.RecurrenceWidgetreads its ownvalueprop instead of reading its field from the form. It still readsstart/endthrough the form hooks, which is how widgets read sibling fields.The
@objectBrowserWidgetloader:breadcrumbsexpanded. They're just as fresh, and the separategetBreadcrumbscall (and its TODO) is gone.Docs:
@plone/helpershooks, location throughuseWidgetContext);versionaddedstep in the upgrade guide;docs/reference/widgets.md): for each registered widget, what it's registered for, the value it reads and writes, and its widget options, includingextraFieldswith the image block's schema as the example. It also documents the object browser's value shape, and that Volto'slink/imagemodes andallowExternals(still set by some block schemas) aren't supported yet.Tests
ImageWidget(the Add Image Content tab crashes because the image field is rendered as a TextField #163 crash).WidgetContext: path rules for each mode, and the default without a provider;ImageWidgetextras: the declared sibling fields are written (an external URL clears stale scales), and nothing is written withoutextraFields;optimizeDepsaudit are clean.