块编辑器开发文档

@wordpress/commands

💡 云策文档标注

概述

@wordpress/commands 是一个通用包,用于注册和修改命令,以在命令菜单(Command Palette)中显示。命令菜单可通过 cmd+k 在编辑器中访问,支持静态和动态命令注册,并提供上下文和分类功能。

关键要点

  • 命令类型:支持静态命令(使用 wp.data.dispatch 或 useCommand)和动态命令(使用 useCommandLoader),两者均接收包含 name、label、icon、callback 等属性的命令对象。
  • 上下文命令:命令可附加到特定上下文(如 site-editor、entity-edit、block-selection-edit),以在相关环境中优先显示。
  • 命令分类:命令可分配类别(如 command、view、edit、action),用于在命令菜单中视觉区分,默认类别为 action。
  • WordPress Data API:提供选择器(如 getCommands、isOpen)和动作(如 open、close)来管理命令菜单状态。
  • 安装与样式:需通过 npm 安装,并引入 @wordpress/components 和 @wordpress/commands 的样式表以确保正确样式。

代码示例

// 使用 useCommand 注册静态命令
import { useCommand } from '@wordpress/commands';
import { plus } from '@wordpress/icons';

useCommand( {
    name: 'myplugin/my-command-name',
    label: __( 'Add new post' ),
    icon: plus,
    category: 'command',
    callback: ( { close } ) => {
        document.location.href = 'post-new.php';
        close();
    },
} );
// 使用 useCommandLoader 注册动态命令
import { useCommandLoader } from '@wordpress/commands';

function usePageSearchCommandLoader( { search } ) {
    // 检索页面逻辑
    const { records, isLoading } = useSelect( /* ... */ );
    const commands = useMemo( () => {
        return ( records ?? [] ).slice( 0, 10 ).map( ( record ) => ({
            name: record.title?.rendered + ' ' + record.id,
            label: record.title?.rendered ? record.title?.rendered : __( '(no title)' ),
            icon: page,
            category: 'edit',
            callback: ( { close } ) => {
                document.location = addQueryArgs( 'site-editor.php', { p: '/page', postId: record.id } );
                close();
            },
        }) );
    }, [ records ] );
    return { commands, isLoading };
}

useCommandLoader( {
    name: 'myplugin/page-search',
    hook: usePageSearchCommandLoader,
} );
// 使用 useCommands 注册多个静态命令
import { useCommands } from '@wordpress/commands';
import { plus, pencil } from '@wordpress/icons';

useCommands( [
    {
        name: 'myplugin/add-post',
        label: __( 'Add new post' ),
        icon: plus,
        category: 'command',
        callback: ( { close } ) => {
            document.location.href = 'post-new.php';
            close();
        },
    },
    {
        name: 'myplugin/edit-posts',
        label: __( 'Edit posts' ),
        icon: pencil,
        category: 'view',
        callback: ( { close } ) => {
            document.location.href = 'edit.php';
            close();
        },
    },
] );

注意事项

  • 命令对象必须包含唯一的 name 和有效的 callback 函数,可选属性如 category 和 context 可增强命令功能。
  • 动态命令依赖于用户输入或条件,需使用 useCommandLoader 并实现命令加载器钩子。
  • 上下文属性需从已实现的上下文(如 site-editor)中选择,以优化命令显示优先级。
  • 若未指定类别或提供无效值,命令将默认使用 action 类别,并在开发模式下发出警告。
  • 安装时需确保环境支持 ES2015+,否则需包含 polyfill,并正确引入样式表。

📄 原文内容

Commands is a generic package that allows registering and modifying commands to be displayed using the commands menu, also called the Command Palette. The Command Palette can be accessed in the Editor using cmd+k.

Types of commands

There are two ways to register commands: static or dynamic. Both methods receive a command object as an argument, which provides:

  • name: A unique machine-readable name for the command
  • label: A human-readable label
  • icon: An SVG icon
  • callback: A callback function that is called when the command is selected
  • category: (Optional) The category of the command. See Command categories below
  • context: (Optional) The context of the command
  • keywords: (Optional) An array of keywords for search matching

Static commands

Static commands can be registered using the wp.data.dispatch( wp.commands.store ).registerCommand action or using the wp.commands.useCommand React hook. Static commands are commonly used to perform a specific action. These could include adding a new page or opening a section of the Editor interface, such as opening the Editor Preferences modal. See the useCommand code example below.

Dynamic commands

Dynamic commands, on the other hand, are registered using “command loaders”, wp.commands.useCommandLoader. These loaders are needed when the command list depends on a 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 needs to filter the available pages using that input to try and find the Contact page. See the useCommandLoader code example below.

Contextual commands

Static and dynamic commands can be contextual. This means that in a given context (for example, when navigating the Site Editor or editing a template), some specific commands are given more priority and are visible as soon as you open the Command Palette. Also, when typing the Command Palette, these contextual commands are shown above the rest of the commands.

At the moment, three contexts have been implemented:

  • site-editor: This is the context that is set when you are navigating in the site editor (sidebar visible).
  • entity-edit: This is the context that is set when you are editing a document (template, template part or page).
  • block-selection-edit: This is the context that is set when a block is selected.

As the usage of the Command Palette expands, more contexts will be added.

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

Command categories

Each command can be assigned a category that describes what kind of action it performs. Categories are used by the Command Palette to visually differentiate commands. The following categories are available:

  • command: Executes code or toggles a command (e.g., Add block, duplicating a block).
  • view: Navigates to an area in the admin or opens a panel (e.g., “Go to: Templates”).
  • edit: Navigates to edit a document (e.g., editing a template, editing a page).
  • action: A generic fallback for commands that don’t fit the other categories. This is also the default when an invalid category is provided.

If no category is specified, the command will have action set. If an invalid value is provided, a warning is emitted in development mode and the category defaults to action.

WordPress Data API

The Command Palette also offers a number of selectors and actions to manipulate its state, which include:

  • 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.

See the Commands Data documentation for more information.

Installation

Install the module

npm install @wordpress/commands --save

This package assumes that your code will run in an ES2015+ environment. If you’re using an environment that has limited or no support for such language features and APIs, you should include the polyfill shipped in @wordpress/babel-preset-default in your code.

This package requires the following stylesheets to be included for proper styling:

/* From node_modules: */
@import '@wordpress/components/build-style/style.css';
@import '@wordpress/commands/build-style/style.css';

API

store

Store definition for the commands namespace.

Related

Usage

import { store as commandsStore } from '@wordpress/commands';
import { useDispatch } from '@wordpress/data';
...
const { open: openCommandCenter } = useDispatch( commandsStore );

Type

  • Object

useCommand

Attach a command to the command palette. Used for static commands.

Usage

import { useCommand } from '@wordpress/commands';
import { plus } from '@wordpress/icons';

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

Parameters

  • command import('../store/actions').WPCommandConfig: command config.

useCommandLoader

Attach a command loader to the command palette. Used for dynamic commands.

Usage

import { __ } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';
import { useCommandLoader } from '@wordpress/commands';
import { page } from '@wordpress/icons';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { useMemo } from '@wordpress/element';

function usePageSearchCommandLoader( { search } ) {
    // Retrieve 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 ]
    );

    // Create 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: page,
                category: 'edit',
                callback: ( { close } ) => {
                    const args = {
                        p: '/page',
                        postId: record.id,
                    };
                    document.location = addQueryArgs( 'site-editor.php', args );
                    close();
                },
            };
        } );
    }, [ records ] );

    return {
        commands,
        isLoading,
    };
}

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

Parameters

  • loader import('../store/actions').WPCommandLoaderConfig: command loader config.

useCommands

Attach multiple commands to the command palette. Used for static commands.

Usage

import { useCommands } from '@wordpress/commands';
import { plus, pencil } from '@wordpress/icons';

useCommands( [
    {
        name: 'myplugin/add-post',
        label: __( 'Add new post' ),
        icon: plus,
        category: 'command',
        callback: ( { close } ) => {
            document.location.href = 'post-new.php';
            close();
        },
    },
    {
        name: 'myplugin/edit-posts',
        label: __( 'Edit posts' ),
        icon: pencil,
        category: 'view',
        callback: ( { close } ) => {
            document.location.href = 'edit.php';
            close();
        },
    },
] );

Parameters

  • commands import('../store/actions').WPCommandConfig[]: Array of command configs.

Contributing to this package

This is an individual package that’s part of the Gutenberg project. The project is organized as a monorepo. It’s made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to npm and used by WordPress as well as other software projects.

To find out more about contributing to this package or Gutenberg as a whole, please read the project’s main contributor guide.