Skip to content

Use a single @ for the Contents view resource routes - #268

Merged
sneridagh merged 6 commits into
feat/resource-routes-skip-contentfrom
fix/contents-resource-prefix
Oct 11, 2026
Merged

sneridagh merged 6 commits into
feat/resource-routes-skip-contentfrom
fix/contents-resource-prefix

Conversation

@sneridagh

@sneridagh sneridagh commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Stacked on #265. Merge that first, then retarget this one to main.

Problem

The convention: Aurora resource routes use a single @, like the REST API endpoints and the cmsui resources (@search, @objectBrowserWidget, @queryStringOptions). Views (routes that render a page) use @@, like @@edit, @@add and @@contents.

@plone/contents registered its action resource routes with @@, as if they were views: /@@contents/@@delete, @@upload, @@rename, @@workflow, @@tags, @@properties, @@order and @@paste. They only return data or handle an action, so they're resources. The convention wasn't written down anywhere.

Changes

  • Routes: the actions become /@@contents/@delete, /@@contents/@upload, /@@contents/@rename, /@@contents/@workflow, /@@contents/@tags, /@@contents/@properties, /@@contents/@order and /@@contents/@paste. As discussed below, they stay nested in the view's path, so they don't collide with other add-ons' resources. They're registered apart from the Contents layout, which their requests never rendered. Their single-@ segment makes them resources, so the root middleware skips the content for them by Let resource routes skip the root content middleware #265's convention, and their skipContent flags go away. The /* splat is kept, since paste uses it for the target folder.
  • Callers: the eight modals and ContentsTable use the new URLs.
  • Convention: written down in the routes how-to (docs/how-to-guides/routes.md) and in the AGENTS.md of cmsui and contents, including nesting a view's own resources in its path, and that the root middleware skips the content for resource routes.
  • News: a breaking fragment in @plone/contents, for any code that calls the old URLs, and a documentation fragment in the app.

Tests

The Contents actions had no acceptance tests. The new packages/contents/acceptance/tests/contents-actions.test.ts covers:

  • deleting an item (checked after a reload, since the listing drops the row right away);
  • renaming an item;
  • loading the workflow transitions of the selected items.

All three fail when the modals call URLs the routes don't match. The contents acceptance suite (7 tests) and contents vitest (33) pass. check:ts for @plone/contents reports the same 13 errors as on main, all in files this PR doesn't touch.

Resource routes use a single @, like the REST API endpoints and the
cmsui resources (@search, @objectBrowserWidget), and views use @@, like
@@edit. The Contents view actions were registered as views, nested in
the view's layout: /@@contents/@@delete and so on.

They move to their own /@contents prefix (/@contents/delete, upload,
rename, workflow, tags, properties, order and paste), outside the
layout, which their requests never rendered. The convention is now in
the routes how-to and the cmsui and contents AGENTS.md.

Adds acceptance tests for delete, rename and loading the workflow
transitions, which had none.
…source-prefix

* feat/resource-routes-skip-content:
  Document the skipContent route option
@sneridagh

Copy link
Copy Markdown
Member Author

@pnicolli uncertain about the convention with this one. Since they are resource (actions) routes, should be rooted to @@contents? And then add another @@ prefix? It feels to me weird... I made this PR with the convention:

@contents/delete... but I am not sure. Meaning "resource action route" + "variant". What do you think?

The alternative could be @@contents/delete might lead to content id collisions, of course...

@sneridagh
sneridagh requested a review from pnicolli October 9, 2026 22:14
@pnicolli

Copy link
Copy Markdown
Collaborator

Yeah I agree that what we have now is not optimal, I think it slipped in with the wrong convention in the years in the making of this package. I think the convention should be:

  • cmsui routes have @@ as a prefix
  • resource routes have @ as a prefix

This way we can avoid conflicts and keep consistency (also with how the restapi looks like, as an added bonus).

The reasoning behind nesting of dedicated resource routes here (i.e. /@@contents/@delete) is to avoid conflicts with other add-ons since this delete is specific for this use case. One could argue it can be made generic and global, but I'm not super sold on this because I don't really want to maintain a restapi replica.

…source-prefix

* feat/resource-routes-skip-content:
  Drop the object browser breadcrumbs news fragment
  Add the missing core widgets (#263)
  Type-check registered widgets and test them against the contract (#262)
  Give widgets a context instead of the route (#261)
  Add adapters for the remaining registered controls (#260)
  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)
As discussed in the PR: the Contents view actions stay nested in the
view's path, with a single @ because they are resources, so they don't
collide with other add-ons' resources: /@@contents/@delete instead of
/@contents/delete.
@sneridagh

Copy link
Copy Markdown
Member Author

@pnicolli right! implemented!

…source-prefix

* feat/resource-routes-skip-content:
  Skip the content for resource routes by convention
Their @ paths make them resources, so the root middleware skips the
content for them by convention. The routes how-to says so next to the
naming convention.
@sneridagh
sneridagh added this pull request to stack #276 October 11, 2026 23:38
@sneridagh
sneridagh merged commit 5729a62 into main Oct 11, 2026
40 checks passed
@sneridagh
sneridagh deleted the fix/contents-resource-prefix branch October 11, 2026 23:41
sneridagh added a commit that referenced this pull request Oct 11, 2026
…drasekhar-eab6cd

* commit '5729a626fba8358d111bc30925f0294b99346841':
  Use a single @ for the Contents view resource routes (#268)
  Let resource routes skip the root content middleware (#265)
  Update React Aria Components to 1.22 (#273)
  Add the missing core widgets (#263)
  Type-check registered widgets and test them against the contract (#262)
  Give widgets a context instead of the route (#261)
  Add adapters for the remaining registered controls (#260)
  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)

# Conflicts:
#	apps/aurora/app/middleware.server.ts
sneridagh added a commit that referenced this pull request Oct 11, 2026
* 'main' of github.com:plone/aurora:
  Use a single @ for the Contents view resource routes (#268)
  Let resource routes skip the root content middleware (#265)
  Update React Aria Components to 1.22 (#273)
  Add the missing core widgets (#263)
  Type-check registered widgets and test them against the contract (#262)
  Give widgets a context instead of the route (#261)
  Add adapters for the remaining registered controls (#260)
  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)
  Fix the recurrence modal crash for events ending on days 1 to 9 (#255)
  Scope widget lookups to their category (#249)
  Subscribe only to the form fields that are read (#248)
  Give each form its own store and remount it per item (#247)
  Wait for hydration in sharing acceptance tests (#250)

# Conflicts:
#	apps/aurora/app/middleware.server.ts
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