You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now, actions can only be registered and removed in JavaScript, using registerEntityAction and unregisterEntityAction, and only on the Gutenberg plugin. The actions each post type has are computed on the client by registerPostTypeSchema, which uses three resolvers (post type, canUser, and current theme) for information the server already has.
This issue proposes a plan so plugins can add and remove the actions of an entity from PHP. The actions show on the DataViews lists of both site editors and on the editor inspector.
Actions are defined in a registry and placed with the view config.
As #83368 does for fields, PHP has the plain data of an action (id, label, isPrimary, supportsBulk, context, modal options), and a script module has the parts PHP cannot serialize (callback, RenderModal, isEligible, function labels).
Which actions an entity has, and their order, comes from a new actions key in the view config, as #77343 prototyped. So plugins use the same merge(), replace(), set() and remove() calls they use for fields:
GET /wp/v2/actions?kind=postType&name=product returns the actions placed on that entity in order, each definition merged with its view config entry, plus the script modules to import. It has the same shape as /wp/v2/fields, so both can share the client loader.
I considered using only the registry to decide which actions an entity has, as, unlike fields, users can't show or hide actions. But that would give plugins different calls for actions and fields, so I opted for placing actions with the view config.
The work is divided into four PRs/stages.
PR 1: Move the core actions into a script module.
Moves the 13 actions registerPostTypeSchema registers (view-post, view-post-revisions, duplicate-post, duplicate-template-part, duplicate-pattern, rename-post, order-pages, export-pattern, restore, reset-post, delete-post, move-to-trash, permanently-delete) into a @wordpress/fields/server-actions script module keyed by action id, the equivalent of server-fields on Fields API #83368.
Adds the module as a dynamic module_dependencies entry of wp-editor, and makes sure the extensible site editor routes have it on their import map.
Makes registerPostTypeSchema import the module. No PHP and no behavior change.
PR 2: Add the actions key to the view config and move the core action list to the server.
Adds actions to the view config keys and REST schema.
Makes registerPostTypeSchema read the list from the view config and removes its gating.
Makes the inspector request context: 'single', so an entry can target only the lists or only the inspector.
Stops placing move-to-trash on attachments and makes permanently-delete accept them, so the v2 post list no longer needs its attachment tweaks.
After this PR, plugins can remove, reorder, and change core actions from PHP.
PR 3: Add the actions registry and the /wp/v2/actions endpoint.
Adds the actions_api_init action, passing a registry with register( $actions, $script_module ) and unregister( $ids ).
Registers the core actions at priority 0, moving their plain data from the module to PHP.
Adds GET /wp/v2/actions?kind&name and makes the client use it with the loader from Fields API #83368. The loader should wait for all the imports and merge in the order the server lists the modules, so replacing the behavior of an action is deterministic.
Adds an e2e test plugin that adds, changes, and removes actions, and adds a core action to a custom post type.
After this PR, plugins can add new actions from PHP.
PR/Stage 4: Core readiness / tweaks.
Preloads the endpoint on both editors and the extensible site editor routes.
Documents the actions key and the registry next to the view config reference, including that the filter only exists per entity and that merging a bare id over an entry with keys replaces the entry.
Fixes the stale registerPostTypeActions entry on docs/private-apis.md.
Decides if registerEntityAction stays plugin-only.
Backports to wordpress-develop with a dev note.
Some notes:
Actions that navigate inside the app keep using onActionPerformed on each host.
Only the postType kind is covered. The view config also supports taxonomies and root entities, but nothing shows entity actions for them yet.
WordPress 7.1 ignores unknown view config keys with a notice, so plugins supporting 7.1 should check in_array( 'actions', $data::CONFIG_KEYS, true ) first.
cc: @oandregal, @ntsekouras as people inside the fields API, view config, and actions work.
Part of #61084 and #81228.
Similar to #76544, but for actions.
Right now, actions can only be registered and removed in JavaScript, using
registerEntityActionandunregisterEntityAction, and only on the Gutenberg plugin. The actions each post type has are computed on the client byregisterPostTypeSchema, which uses three resolvers (post type,canUser, and current theme) for information the server already has.This issue proposes a plan so plugins can add and remove the actions of an entity from PHP. The actions show on the DataViews lists of both site editors and on the editor inspector.
Actions are defined in a registry and placed with the view config.
As #83368 does for fields, PHP has the plain data of an action (id, label,
isPrimary,supportsBulk,context, modal options), and a script module has the parts PHP cannot serialize (callback,RenderModal,isEligible, function labels).Which actions an entity has, and their order, comes from a new
actionskey in the view config, as #77343 prototyped. So plugins use the samemerge(),replace(),set()andremove()calls they use for fields:The script module exports the JavaScript parts keyed by action id:
GET /wp/v2/actions?kind=postType&name=productreturns the actions placed on that entity in order, each definition merged with its view config entry, plus the script modules to import. It has the same shape as/wp/v2/fields, so both can share the client loader.I considered using only the registry to decide which actions an entity has, as, unlike fields, users can't show or hide actions. But that would give plugins different calls for actions and fields, so I opted for placing actions with the view config.
The work is divided into four PRs/stages.
PR 1: Move the core actions into a script module.
registerPostTypeSchemaregisters (view-post,view-post-revisions,duplicate-post,duplicate-template-part,duplicate-pattern,rename-post,order-pages,export-pattern,restore,reset-post,delete-post,move-to-trash,permanently-delete) into a@wordpress/fields/server-actionsscript module keyed by action id, the equivalent ofserver-fieldson Fields API #83368.module_dependenciesentry ofwp-editor, and makes sure the extensible site editor routes have it on their import map.registerPostTypeSchemaimport the module. No PHP and no behavior change.PR 2: Add the
actionskey to the view config and move the core action list to the server.actionsto the view config keys and REST schema.form, portingget_actions()from View Config: Serve supported action IDs from the REST controller #77343 and updating it to trunk. Only actions that can apply are placed, e.g.:reset-postis not placed on pages.set-as-homepageandset-as-posts-pageon pages for users withmanage_options. In paralell to this effort we will work on Register set-as-homepage and set-as-posts-page as entity actions #76668 using option C isEligible needs access to the registry.registerPostTypeSchemaread the list from the view config and removes its gating.context: 'single', so an entry can target only the lists or only the inspector.move-to-trashon attachments and makespermanently-deleteaccept them, so the v2 post list no longer needs its attachment tweaks.After this PR, plugins can remove, reorder, and change core actions from PHP.
PR 3: Add the actions registry and the
/wp/v2/actionsendpoint.actions_api_initaction, passing a registry withregister( $actions, $script_module )andunregister( $ids ).GET /wp/v2/actions?kind&nameand makes the client use it with the loader from Fields API #83368. The loader should wait for all the imports and merge in the order the server lists the modules, so replacing the behavior of an action is deterministic.After this PR, plugins can add new actions from PHP.
PR/Stage 4: Core readiness / tweaks.
actionskey and the registry next to the view config reference, including that the filter only exists per entity and that merging a bare id over an entry with keys replaces the entry.registerPostTypeActionsentry ondocs/private-apis.md.registerEntityActionstays plugin-only.Some notes:
onActionPerformedon each host.postTypekind is covered. The view config also supports taxonomies and root entities, but nothing shows entity actions for them yet.in_array( 'actions', $data::CONFIG_KEYS, true )first.cc: @oandregal, @ntsekouras as people inside the fields API, view config, and actions work.