Get Started Making Your Own WP-CLI Commands ![rw-book-cover](https://webdevstudios.com/wp-content/uploads/2019/10/Maintainn-Blog-Social-Template-72.png) ## Metadata - Author: [[Scott Anderson]] - Full Title: Get Started Making Your Own WP-CLI Commands - Category: #articles - Summary: Have you ever wanted to generate hundreds of user accounts or publish thousands of posts to your blog without ever once logging into your WordPress dashboard? You can do that and so much more with WordPress Command Line Interface (WP-CLI). - URL: https://webdevstudios.com/2019/10/08/making-wp-cli-commands/ Have you ever wanted to generate hundreds of user accounts or publish thousands of posts to your [blog](https://webdevstudios.com/blog/) without ever once logging into your WordPress dashboard? You can do that and so much more with WordPress Command Line Interface (WP-CLI). ![](https://webdevstudios.com/wp-content/uploads/2019/09/get-started-on-making-your-own-wp-cli-commands.gif) #### What is a command-line interface (CLI)? A CLI, put simply, is a way to interact with a computer program using commands in the form of successive lines of text instead of using a graphical interface. For example, to install the plugin **[Hello Dolly](https://wordpress.org/plugins/hello-dolly/)** instead of going to your **WP Dashboard > Plugins > Add New > Search “Hello Dolly” > Click Install > and finally Click Activate**, you can simply run the command `wp plugin install hello-dolly --activate` and it does it all at once. #### Our First Command Now that we know what a WP-CLI command is, let’s get started with our first Hello World! To create your first command, use the command `WP_CLI::add_command('**IDENTIFIER**', '**CLASS\_NAME**')` where the identifier is what you’ll use in the CLI to call subcommands and class name being the class containing all your CLI commands. With our CLI registered, any public function declared in our class will be made accessible as a subcommand under our identifier. For the time being, we’ll simply use **hello\_world()** and return the universal string to make sure our commands are registering. Finally, if we run `wp wds hello_world` we should have ‘Hello World’ returned. | | | | --- | --- | | | <?php | | | /\* | | | Plugin Name: WDS Hello World | | | Plugin URI: https://webdevstudios.com/ | | | Description: Teaching the basics of WP-CLI | | | Author: Web Dev Studios | | | Version: 1.0.0 | | | Author URI: https://webdevstudios.com/ | | | \*/ | | | | | | class WDS\_CLI { | | | | | | /\*\* | | | \* Returns 'Hello World' | | | \* | | | \* @since 0.0.1 | | | \* @author Scott Anderson | | | \*/ | | | public function hello\_world() { | | | WP\_CLI::line( 'Hello World!' ); | | | } | | | | | | } | | | | | | /\*\* | | | \* Registers our command when cli get's initialized. | | | \* | | | \* @since 1.0.0 | | | \* @author Scott Anderson | | | \*/ | | | function wds\_cli\_register\_commands() { | | | WP\_CLI::add\_command( 'wds', 'WDS\_CLI' ); | | | } | | | | | | add\_action( 'cli\_init', 'wds\_cli\_register\_commands' ); | If we run the command `wp wds --help` we can see the subcommand we just registered. #### Adding Arguments Now it’s time to spice things up. More than likely, you’ll want to pass variables to your CLI command; when in CLI, these are called **arguments.** In order for your command to support arguments, add the variables **$args** and **$assoc\_args** to the function declaration. The **$args** array will contain all positional arguments (arguments that don’t have a flag on it **—** ). The **$assoc\_args** contain all arguments declared with flags **–key=value –option** or **–no-flag**. The **–key=value** will use the **key** to access the value assigned to it **$assoc\_args[‘key’]** . The **–option** will return true, if its flag is present **$assoc\_args[‘option’]**, and **–no-flag** will return the false for a given flag used in the key **$assoc\_args[‘flag’]** . Let’s see all these arguments in practice by running `wp wds display_arguments John Doe 'Jane Doe' 32 --title='Moby Dick' --author='Herman Melville' --published=1851 --publish --no-archive`. | | | | --- | --- | | | /\*\* | | | \* Returns all arguments passed into command to demonstrate how to access them. | | | \* | | | \* @param Array $args Arguments in array format. | | | \* @param Array $assoc\_args Key value arguments stored in associated array format. | | | \* @since 1.0.0 | | | \* @author Scott Anderson | | | \*/ | | | public function display\_arguments( $args, $assoc\_args ) { | | | | | | // Run command wp wds display\_arguments John Doe 'Jane Doe' 32 --title='Moby Dick' --author='Herman Melville' --published=1851 --publish --no-archive | | | | | | // Examples of Arguments. | | | WP\_CLI::line( var\_export($args[0]) ); // John | | | WP\_CLI::line( var\_export($args[1]) ); // Doe | | | WP\_CLI::line( var\_export($args[2]) ); // Jane Doe | | | WP\_CLI::line( var\_export($args[3]) ); // 32 | | | | | | // Example of Associated Arguments | | | WP\_CLI::line( var\_export($assoc\_args['title']) ); // Moby Dick | | | WP\_CLI::line( var\_export($assoc\_args['author']) ); // Herman Melville | | | WP\_CLI::line( var\_export($assoc\_args['published']) ); // 1851 | | | | | | // Example of Associated Arguments as flag | | | WP\_CLI::line( var\_export($assoc\_args['publish']) ); // True | | | WP\_CLI::line( var\_export($assoc\_args['archive']) ); // False | | | | | | } | #### Spicing Up Our Output Up to now, we have only used **WP\_CLI::line** to return data to the command line, which can be rather boring. For more message offerings in addition to **line**, we can use **log,** **success,** **warning, error, error\_multi\_line, halt**. When the flag **–quiet** is used, all **messages**, except those noted, will be silenced and not return a message. Let’s see these message types in practice by running `wp wds display_messages`. **Note:** Colorize has multiple colors and output formats. For a full list, see the [Colorize Codex.](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-colorize/) | | | | --- | --- | | | /\*\* | | | \* Returns multiple messages to demonstrate different command return types. | | | \* | | | \* @since 1.0.0 | | | \* @author Scott Anderson | | | \*/ | | | public function display\_messages( $args, $assoc\_args ) { | | | | | | // No prepends. | | | WP\_CLI::line( 'Standard line return.' ); // No prefix on line return. | | | WP\_CLI::log( 'Standard line returned that wont be silenced.' ); // No prefix on line but ignores --quiet | | | | | | // Color make sure to use %n at the end of a style or else the style will apply to the next output. | | | WP\_CLI::line(WP\_CLI::colorize( '%BBlue text%n' )); // Returns text in blue color. Ignores --quiet. | | | WP\_CLI::line(WP\_CLI::colorize( '%MMagenta text%n' )); // Returns text in magenta. Ignores --quiet. | | | WP\_CLI::line(WP\_CLI::colorize( '%UUnderline text%n' )); // Returns text underlined. Ignores --quiet. | | | | | | // Only prepends. | | | WP\_CLI::success( 'Post updated!' ); // Prepends Success to message | | | WP\_CLI::warning( 'No match was found.' ); // Prepends Warning to message. | | | | | | // Special conditions. | | | WP\_CLI::debug( 'Breakpoint comment.' ); // Displays only when --debug flag is used. | | | | | | WP\_CLI::error\_multi\_line( ['Error found!', 'Post not updated!','User not updated!'] ); // Displays multi-line error in red box. Doesn't exit script. Ignores --quiet but looses formating. | | | | | | | | | //Returns error message if --error custom flag is added. | | | if( isset($assoc\_args['error']) && $assoc\_args['error']) { | | | WP\_CLI::error( 'Error found!' ); // Prepends message with Error and exits script. | | | } | | | | | | WP\_CLI::halt( 200 ); // Halts script execution with a specific return code. Could for calling your subcommand from another. | | | | | | } | #### Loading, Loading, Loading… When you are making a lot of operations, instead of leaving the user guessing how far along a process might be, it would be helpful to provide a progress bar keeping track of changes. Luckily WP-CLI has a progress bar baked right in. To use the progress bar, simply declare it `$progress = \WP_CLI\Utils\make_progress_bar( $label, $count )` where **$label** is a message shown before the progress bar and **$count** is the total number of ticks that should be performed. With your progress bar initialized, it is most common to use it in a conditional loop. Once a stage of your process is complete, you can call the `$progress->tick()` command to increment the progress bar. Finally, at the end of your loop, you may call `$progress->finish()` to complete the progress bar. Let’s see the progress bar in practice by running `wp wds generate_posts_progress_bar 100`. | | | | --- | --- | | | /\*\* | | | \* Displays progress bar to demonstrate progression through a time consuming process. | | | \* | | | \* @param Array $args Arguments in array format. | | | \* @param Array $assoc\_args Key value arguments stored in associated array format. | | | \* @since 1.0.0 | | | \* @author Scott Anderson | | | \*/ | | | public function generate\_posts\_progress\_bar( $args, $assoc\_args ) { | | | | | | $desired\_posts\_to\_generate = (int) $args[0]; | | | | | | $progress = \WP\_CLI\Utils\make\_progress\_bar( 'Generating Posts', $desired\_posts\_to\_generate ); | | | | | | for ( $i = 0; $i < $desired\_posts\_to\_generate; $i++ ) { | | | // Code used to generate a post. | | | $progress->tick(); | | | } | | | | | | $progress->finish(); | | | | | | } | #### Putting It All Together Up to this point, we have covered how to register commands, pass arguments, display information, and keep track of a task with a progress bar. Let’s round up with one final working example putting all of these elements together in one final command. The following will generate posts where the first argument is how many posts to generate, second argument is title to be used in the posts generated, third argument is the ID of the author to associate it to, finally, any –key=value pairs will be stored as metadata for the post. We’ll wrap this with a progress bar to finish it up. We can generate 1000 posts with dummy metadata running the following command `wp wds generate_posts 1000 'Testing Titles' 1 --locale="en_ca" --location="Toronto"`. #### Finale That’s it. If you want to learn more, see the official [WP-CLI documentation](https://wp-cli.org/). If you want to see all the commands together, see the entire [WP-CLI 101 Codefile](https://gist.github.com/Oceas/87fde5ed13c697bc49f9253155fd70df#file-wds-hello-world-php)., Get Started Making Your Own WP-CLI Commands, Scott Anderson, 01gnmcxemw96evkeq4b8zch9t6.