命令说明书
创建自己的自定义WP-CLI命令可能比看起来更容易 - 您可以使用(repo)动态生成除命令本身之外的所有内容。wp scaffold package
概述
WP-CLI的目标是提供WordPress管理员的完整替代方案;对于您可能希望在WordPress管理中执行的任何操作,应该有一个等效的WP-CLI命令。命令是 WP-CLI 功能的原子单元。 (doc) 就是这样一个命令,就像 (doc) 一样。命令对WordPress用户很有用,因为它们可以提供简单,精确的界面来执行复杂的任务。wp plugin install``wp plugin activate
但是,WordPress管理员是一把无限复杂的瑞士军刀。这个项目不可能只处理每个用例。这就是为什么WP-CLI包含一组常见的内部命令,同时还为第三方编写和注册自己的命令提供了丰富的内部API。
WP-CLI命令可以作为独立包分发,也可以与WordPress插件或主题捆绑在一起。对于前者,您可以使用 (repo) 动态生成除命令本身之外的所有内容。wp scaffold package
包之于WP-CLI,就像插件之于WordPress一样。创建WP-CLI包的方法存在明显差异。虽然WP-CLI是/wp-admin不断增长的替代品,但重要的是要注意,在考虑如何使用WordPress API之前,您必须首先编写软件包以使用WP-CLI内部API。
命令类型
捆绑的命令:
- 通常涵盖标准安装WordPress提供的功能。不过,这条规则也有例外,特别是(doc)。
wp search-replace
- 不要依赖其他组件,例如插件,主题等。
- 由 WP-CLI 团队维护。
第三方命令:
所有命令:
- 遵循文档标准。
命令剖析
WP-CLI 支持将任何可调用的类、函数或闭包注册为命令。 (doc) 用于内部和第三方命令注册。WP_CLI::add_command()
命令的概要定义命令接受哪些位置参数和关联参数。让我们来看看以下的概要:wp plugin install
$ wp plugin install
usage: wp plugin install <plugin|zip|url>... [--version=<version>] [--force] [--activate] [--activate-network]
在此示例中,是公认的位置参数。事实上,多次接受相同的位置参数(要安装的插件的 slug、ZIP 或 URL)。 是公认的关联论点之一。它用于表示要安装的插件的版本。还要注意参数定义周围的方括号;方括号表示参数是可选的。<plugin|zip|url>...``wp plugin install``[--version=<version>]
WP-CLI还具有一系列适用于所有命令的全局参数。例如,包含意味着您的命令执行将显示所有PHP错误,并为WP-CLI引导过程增加额外的冗长程度。--debug
必需的注册参数
注册命令时,需要两个参数:WP_CLI::add_command()
-
$name
是 WP-CLI 命名空间中的命令名称(例如 或 )。plugin install``post list
-
$callable
是命令的实现,作为可调用的类、函数或闭包。
在以下示例中,每个实例在功能上都是等效的:wp foo
// 1. Command is a function
function foo_command( $args ) {
WP_CLI::success( $args[0] );
}
WP_CLI::add_command( 'foo', 'foo_command' );
// 2. Command is a closure
$foo_command = function( $args ) {
WP_CLI::success( $args[0] );
}
WP_CLI::add_command( 'foo', $foo_command );
// 3. Command is a method on a class
class Foo_Command {
public function __invoke( $args ) {
WP_CLI::success( $args[0] );
}
}
WP_CLI::add_command( 'foo', 'Foo_Command' );
// 4. Command is a method on a class with constructor arguments
class Foo_Command {
protected $bar;
public function __construct( $bar ) {
$this->bar = $bar;
}
public function __invoke( $args ) {
WP_CLI::success( $this->bar . ':' . $args[0] );
}
}
$instance = new Foo_Command( 'Some text' );
WP_CLI::add_command( 'foo', $instance );
重要的是,类的行为与函数和闭包略有不同,因为:
- 类上的任何公共方法都注册为命令的子命令。例如,给定上面的示例,类上的方法将被注册为 .但。。。
bar()``Foo``wp foo bar
-
__invoke()
被视为一种神奇的方法。如果一个类实现,命令名称将被注册到该方法,并且该类的其他方法不会被注册为命令。__invoke()
_注意:_从历史上看,WP-CLI 提供了一个要扩展的基类,但是扩展此类不是必需的,也不会更改命令的行为方式。WP_CLI_Command
所有命令都可以注册到它们自己的顶级命名空间(例如 ),也可以作为子命令注册到现有命名空间(例如 )。对于后者,只需将现有命名空间作为命令定义的一部分包含在内。wp foo``wp core foo
class Foo_Command {
public function __invoke( $args ) {
WP_CLI::success( $args[0] );
}
}
WP_CLI::add_command( 'core foo', 'Foo_Command' );
快速而肮脏的执行
为一次性任务编写简短脚本,不需要正式注册 ? 是您的票证(文档)。WP_CLI::add_command()
wp eval-file
给定一个文件:simple-command.php
WP_CLI::success( "The script has run!" );
如果该命令不依赖于WordPress,或者WordPress不可用,则可以使用该标志来避免加载WordPress。wp eval-file simple-command.php
--skip-wordpress
可选注册参数
WP-CLI 支持两种为命令注册可选参数的方法:通过可调用对象的 PHPDoc,或作为第三个参数传递给 。$args``WP_CLI::add_command()
使用 PHPDoc 进行注释
典型的WP-CLI类如下所示:
/**
* Implements example command.
*/
class Example_Command {
function hello( $args, $assoc_args ) {
list( $name ) = $args;
// Print the message with type
$type = $assoc_args['type'];
WP_CLI::$type( "Hello, $name!" );
}
}
WP_CLI::add_command( 'example', 'Example_Command' );
此命令的 PHPDoc 以三种方式解释:
短描述
缩写是 PHPDoc 中的第一行:
longdesc
longdesc 是 PHPDoc 的中间部分:
longdesc 中定义的选项被解释为命令的概要:
-
<name>
是必需的位置参数。将其更改为意味着命令可以接受一个或多个位置参数。将其更改为意味着位置参数是可选的,最后,将其更改为意味着该命令可以接受多个可选的位置参数。<name>...``[<name>]``[<name>...]
-
[--type=<type>]
是一个可选的关联参数,默认为“成功”并接受“成功”或“错误”。将其更改为 会将参数更改为充当可选的布尔标志。[--error]
-
[--field[=<value>]]
允许将可选参数与值或不带值一起使用。这方面的一个例子是使用全局参数,该参数可以跳过加载所有插件,也可以跳过逗号分隔的插件列表。--skip-plugins[=<plugins>]
命令的概要用于在将参数传递给实现之前验证参数。
调用命令时也会显示 longdesc,例如 。它的语法是Markdown Extra,这里有一些关于WP-CLI如何处理它的更多说明:help``wp help example hello
- 长篇通常被视为自由格式的文本。和 节名称不是强制执行的,只是通用和推荐。
OPTIONS``EXAMPLES
- 节名称 () 以零缩进着色和打印。
## NAME
- 其他所有内容都缩进 2 个字符,选项说明进一步缩进另外 2 个字符。
- 自动换行有点棘手。如果要在每行上利用尽可能多的空间,并且不会在下一行获得像一两个单词这样的自动换行工件,请遵循以下规则:
- 冒号和空格后 75 个字符处的硬换行选项说明。
- 将其他所有内容硬包装在 90 个字符处。
有关如何格式化命令文档的更多详细信息,请参阅 WP-CLI 的文档标准。
文档块标签
这是最后一部分,它紧跟在 longdesc 之后开始:
```
- @when after_wp_load */
以下是已定义标记的列表:
**@subcommand**
在某些情况下,不能使方法名称具有子命令的名称。例如,不能有一个名为 的方法,因为 是 PHP 中的保留关键字。`list``list`
这时标签会派上用场:`@subcommand`
```
/**
* @subcommand list
*/
function _list( $args, $assoc_args ) {
...
}
/**
* @subcommand do-chores
*/
function do_chores( $args, $assoc_args ) {
...
}
@alias
使用该标记,您可以添加另一种调用子命令的方式。例:@alias
```
/** * @alias hi */ function hello( $args, $assoc_args ) { ... }
$ wp example hi Joe Success: Hello, Joe!
**@when**
这是一个特殊的标签,告诉WP-CLI何时执行命令。它支持[所有已注册的WP-CLI钩子](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-add-hook/)。
大多数WP-CLI命令在WordPress加载后执行。命令的默认行为为:
@when after_wp_load
要在WordPress加载之前运行WP-CLI命令,请使用:
@when before_wp_load
请记住,大多数WP-CLI钩子在加载WordPress之前触发。如果您的命令是从插件或主题加载的,则基本上将被忽略。`@when`
如果使用它的命令是从插件或主题加载的,则它不起作用,因为到那时WordPress本身已经加载了。
#### [WP\_CLI::add\_command() 的第三个$args参数](#wp_cliadd_commands-third-args-parameter)
PHPDoc 支持的每个配置选项都可以作为命令注册中的第三个参数传递:
$hello_command = function( $args, $assoc_args ) { list( $name ) = $args; $type = $assoc_args['type']; WP_CLI::$type( "Hello, $name!" ); if ( isset( $assoc_args['honk'] ) ) { WP_CLI::log( 'Honk!' ); } }; WP_CLI::add_command( 'example hello', $hello_command, array( 'shortdesc' => 'Prints a greeting.', 'synopsis' => array( array( 'type' => 'positional', 'name' => 'name', 'description' => 'The name of the person to greet.', 'optional' => false, 'repeating' => false, ), array( 'type' => 'assoc', 'name' => 'type', 'description' => 'Whether or not to greet the person with success or error.', 'optional' => true, 'default' => 'success', 'options' => array( 'success', 'error' ), ), array( 'type' => 'flag', 'name' => 'honk', 'optional' => true, ), ), 'when' => 'after_wp_load', 'longdesc' => '## EXAMPLES' . "\n\n" . 'wp example hello Newman', ) );
请注意,该属性将附加到从概要生成的选项的描述中,因此此参数非常适合添加用法示例。如果没有概要,将按原样使用该属性来提供描述。`longdesc``longdesc`
### [命令内部](#command-internals)
现在您知道如何注册命令,世界就是您的牡蛎。在回调中,命令可以做任何它想做的事情。
#### [接受参数](#accepting-arguments)
为了处理运行时参数,您必须向可调用对象添加两个参数:和 。`$args``$assoc_args`
function hello( $args, $assoc_args ) { /* Code goes here*/ }
`$args`变量将存储所有位置参数:
$ wp example hello Joe Doe
WP_CLI::line( $args[0] ); // Joe WP_CLI::line( $args[1] ); // Doe
`$assoc_args`变量将存储所有定义的参数,如或或`--key=value``--flag``--no-flag`
$ wp example hello --name='Joe Doe' --verbose --no-option
WP_CLI::line( $assoc_args['name'] ); // Joe Doe WP_CLI::line( $assoc_args['verbose'] ); // true WP_CLI::line( $assoc_args['option'] ); // false
此外,您还可以组合参数类型:
$ wp example hello --name=Joe foo --verbose bar
WP_CLI::line( $assoc_args['name'] ); // Joe WP_CLI::line( $assoc_args['verbose'] ); // true WP_CLI::line( $args[0] ); // foo WP_CLI::line( $args[1] ); // bar
#### [有效地重用 WP-CLI 内部 API](#effectively-reusing-wp-cli-internal-apis)
例如,假设您的任务是在多站点网络上查找所有未使用的主题 ([#2523](https://github.com/wp-cli/wp-cli/issues/2523))。如果您必须通过WordPress管理员手动执行此任务,则可能需要数小时甚至数天的努力。但是,如果您熟悉编写 WP-CLI 命令,则可以在 15 分钟或更短的时间内完成任务。
Here’s what such a command looks like:
/**
- Find unused themes on a multisite network.
- Iterates through all sites on a network to find themes which aren't enabled
- on any site. */ $find_unused_themes_command = function() { $response = WP_CLI::launch_self( 'site list', array(), array( 'format' => 'json' ), false, true ); $sites = json_decode( $response->stdout ); $unused = array(); $used = array(); foreach( $sites as $site ) { WP_CLI::log( "Checking {$site->url} for unused themes..." ); $response = WP_CLI::launch_self( 'theme list', array(), array( 'url' => $site->url, 'format' => 'json' ), false, true ); $themes = json_decode( $response->stdout ); foreach( $themes as $theme ) { if ( 'no' == $theme->enabled && 'inactive' == $theme->status && ! in_array( $theme->name, $used ) ) { $unused[ $theme->name ] = $theme; } else { if ( isset( $unused[ $theme->name ] ) ) { unset( $unused[ $theme->name ] ); } $used[] = $theme->name; } } } WP_CLI\Utils\format_items( 'table', $unused, array( 'name', 'version' ) ); }; WP_CLI::add_command( 'find-unused-themes', $find_unused_themes_command, array( 'before_invoke' => function(){ if ( ! is_multisite() ) { WP_CLI::error( 'This is not a multisite installation.' ); } }, ) );
让我们浏览一下此命令用于实现其目标[的内部 API](https://make.wordpress.org/cli/handbook/internal-api/):
* `WP_CLI::add_command()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-add-command/))用于将命令注册到闭包。通过该参数,可以验证命令是否在多站点安装上运行,如果不是,则出错。`find-unused-themes``$find_unused_themes_command``before_invoke`
* `WP_CLI::error()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-error/))呈现格式良好的错误消息并退出。
* `WP_CLI::launch_self()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-launch-self/))最初生成一个获取所有网站列表的过程,然后用于获取给定网站的主题列表。
* `WP_CLI::log()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-log/))向最终用户呈现信息输出。
* `WP_CLI\Utils\format_items()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-utils-format-items/))在命令完成发现后呈现未使用主题的列表。
### [帮助渲染](#help-rendering)
命令的 PHPDoc(或注册的定义)是使用该命令呈现的。输出的顺序如下:`help`
1. 简短描述
2. 概要
3. 详细描述(选项、示例等)
4. 全局参数
[编写测试](#writing-tests)
----------------------
WP-CLI使用基于Behat的测试框架,您也应该使用它。Behat是WP-CLI命令的绝佳选择,因为:
* 编写新测试很容易,这意味着它们实际上会被编写出来。
* 测试与命令的交互方式与用户界面与命令的交互方式相同。
Behat 测试存在于项目的目录中。下面是一个来自以下示例:`features/``features/cli-info.feature`
Feature: Review CLI information
Scenario: Get the path to the packages directory Given an empty directory
When I run `wp cli info --format=json`
Then STDOUT should be JSON containing:
"""
{"wp_cli_packages_dir_path":"/tmp/wp-cli-home/.wp-cli/packages/"}
"""
When I run `WP_CLI_PACKAGES_DIR=/tmp/packages wp cli info --format=json`
Then STDOUT should be JSON containing:
"""
{"wp_cli_packages_dir_path":"/tmp/packages/"}
"""
功能测试通常遵循以下模式:
* **鉴于**一些背景,
* **当用户**执行特定操作时,
* **那么**最终结果应该是 X(以及 Y 和 Z)。
相信?转到 [wp-cli/scaffold-package-command](https://github.com/wp-cli/scaffold-package-command) 开始。
[分配](#distribution)
-------------------
现在您已经生成了一个引以为豪的命令,是时候与世界分享它了。有两种常见的方法。
### [包含在插件或主题中](#include-in-a-plugin-or-theme)
共享WP-CLI命令的一种方法是将它们打包到您的插件或主题中。许多人通过基于常量的存在有条件地加载(和注册)命令来做到这一点。`WP_CLI`
if ( defined( 'WP_CLI' ) && WP_CLI ) { require_once dirname( FILE ) . '/inc/class-plugin-cli-command.php'; }
### [作为独立命令分发](#distribute-as-a-stand-alone-command)
独立的WP-CLI命令可以从任何git存储库,ZIP文件或文件夹安装。唯一的技术要求是包括有效的作曲家。带有自动加载声明的 JSON 文件。我们建议将项目明确区分为 WP-CLI 包。`"type": "wp-cli-package"`
下面是来自服务器命令的完整 composer.json 示例:
{ "name": "wp-cli/server-command", "description": "Start a development server for WordPress", "type": "wp-cli-package", "homepage": "https://github.com/wp-cli/server-command", "license": "MIT", "authors": [ { "name": "Package Maintainer", "email": "packagemaintainer@homepage.com", "homepage": "https://www.homepage.com" } ], "require": { "php": ">=5.3.29" }, "autoload": { "files": [ "command.php" ] } }
请注意声明,它加载 .`autoload``command.php`
将有效的 composer.json 文件添加到项目存储库后,WP-CLI 用户可以通过包管理器将其从您选择存储它的位置拉入。下面是存储位置的一些示例以及通过包管理器安装它的相应语法:
#### [Git 存储库](#git-repository)
要安装可在 git 存储库中找到的包,您可以向命令提供指向 git 存储库的 HTTPS 或 SSH 链接。`package install`
Installing the package using an HTTPS link
$ wp package install https://github.com/wp-cli/server-command.git
Installing the package using an SSH link
$ wp package install git@github.com:wp-cli/server-command.git
#### [压缩文件](#zip-file)
您可以通过提供命令的 ZIP 文件的路径来从该文件安装包。`wp package install`
Installing the package using a ZIP file
$ wp package install ~/Downloads/server-command-main.zip