Introducing the WordPress Command Palette API

WordPress 6.3 ships with a new command palette. Initially included in the post and site editors, users can open the command palette using the ctrl + k or command + k keyboard shortcuts.

An overview on how the command palette appears in the editor.

Registering commands

The command palette includes a number of coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. commands that you can use by default including things like:

  • Navigating the site editor.
  • Creating new posts and pages.
  • Toggling UIUI User interface elements.
  • Toggling editor preferences.
  • and more.

It also offers an APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. for third-party developers to register or unregister commands.

There are two ways to register commands: static commands and dynamic commands.

Static commands

Static commands can be registered using the wp.data.dispatch( wp.commands.store ).registerCommand action or using the wp.commands.useCommand ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. hook. Both methods receive a command object as an argument, which provides a unique name, a label, an icon, a callback function that is called when the command is selected, and potentially a context.

Example:

wp.commands.useCommand( {
	name: 'myplugin/my-command-name',
	label: __( 'Add new post' ),
	icon: plus,
	callback: ({ close }) => {
		document.location.href = 'post-new.php';
		close();
	},
} );

Dynamic commands

Dynamic commands, on the other hand, are registered using “command loaders.” These are needed when the command list depends on the search term entered by the user in the command palette input or when some commands are only available when some conditions are met.

For example, when a user types “contact”, the command palette need to filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. the available pages using that input.

function usePageSearchCommandLoader( { search } ) {
	// Retreiving the pages for the "search" term
	const { records, isLoading } = useSelect(
		( select ) => {
			const { getEntityRecords } = select( coreStore );
			const query = {
				search: !! search ? search : undefined,
				per_page: 10,
				orderby: search ? 'relevance' : 'date',
			};
			return {
				records: getEntityRecords( 'postType', 'page', query ),
				isLoading: ! select( coreStore ).hasFinishedResolution(
					'getEntityRecords',
					[ 'postType', 'page', query ]
				),
			};
		},
		[ search ]
	);

	// Creating the commands
	const commands = useMemo( () => {
		return ( records ?? [] ).slice( 0, 10 ).map( ( record ) => {
			return {
				name: record.title?.rendered + ' ' + record.id,
				label: record.title?.rendered
					? record.title?.rendered
					: __( '(no title)' ),
				icon: icons[ postType ],
				callback: ( { close } ) => {
					const args = {
						postType,
						postId: record.id,
						...extraArgs,
					};
					document.location = addQueryArgs( 'site-editor.php', args );
					close();
				},
			};
		} );
	}, [ records, history ] );

	return {
		commands,
		isLoading,
	};
}

useCommandLoader( {
	name: 'myplugin/page-search',
	hook: usePageSearchCommandLoader,
} );

Contextual commands

Commands can be contextual. This means that in a given context (for example, when navigating the site editor, or when editing a template), some specific commands are given more priority and are visible as soon as you open the command palette. And when typing the command palette, these contextual commands are shown above the rest of the commands.

At the moment, two contexts have been implemented:

  • site-editor This is the context that is set when you are navigating in the site editor (sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. visible).
  • site-editor-edit This is the context that is set when you are editing a document (template, template part or page) in the site editor.

As the usage of the command palette expands, more contexts will be added. 

To attach a command or a command loader to a given context, it is as simple as adding the context property (with the right context value from the available contexts above) to the useCommand or useCommandLoader calls.

WordPress Data API

The command palette also offers a number of selectors and actions to manipulate its state which includes:

  • Retrieving the registered commands and command loaders using the following selectors getCommands and getCommandLoader
  • Checking if the command palette is open using the isOpen selector.
  • Programmatically open or close the command palette using the open and close actions.

Props to @bph, @annezazu, and @leonnugraha for reviewing.

#6-3, #dev-notes, #dev-notes6-3