Simplify your day to day tasks with WP-CLI even more

Type and run, automate

Jaime Martínez | @jmslbam | #wpm030 | 9 oct 2014



Jaime Martinez

Happy coder @ Level Level

Feature contributor and tester WP-CLI

Long time WordPress enthousiast

Prepare yourself,

the CLI is coming

CLI what?



A direct, text-based, interface to a computer.

New to the (WP-)CLI?

View my previous WP-CLI talk with some extra references

Made by

Setup by Andreas Creten, lead to success by Cristi Burcă a.k.a. Scribu and  Daniel Bachhuber.

Actively maintained by  Daniel Bachhuber and 98 other contributers ...


Uses WordPress to perform operations

  • Run long running tasks like without time-outs
  • Repetitive tasks
  • Saves time
  • Extensible with your own commands

Install WP-CLI

curl -O 

And move it to your ~/bin

Full instructions:


Add  ~/.wp-cli/bin/ to your $PATH

MAMP? Or Luc's info

Use Vagrant

Varying Vagrant Vagrants from 10up
Bedrock by Roots
Salty WordPress from HumanMade
Or others



Long running tasks

  • Imports / Exports
  • Regenerating images
  • Bulk processing posts 

Repetitive tasks

  • Cron jobs / nightly imports
  • Base WordPress install
  • Generate test content
  • Flushing rewrite rules

Handy commands

wp core update
wp core update-db 

wp db import
wp search-replace

wp user update 1 --user_pass=test

Handy commands

wp rewrite flush

wp option set blogname 

wp media regenerate 

wp transient delete-expired 

wp scaffold

Don’t copy & paste

wp scaffold cpt|tax|theme|plugin  

More info this topic on
Scaffolding Custom post types and taxonomies 

Combine commands

No need for new commands

--porcelain  is your friend

Output just the new post id.


Use the return value (post_id) to attach it to the imported file.
wp media import ~/Pictures/jaimemartinez.png --post_id=$(wp post create --post_name=wpmeetup --post_title='Profile picture of Jaime' --porcelain)

A. Bulk publish posts

wp post update $(wp post list --post_type='zombie' --format=ids) --post_status=publish
step 1
wp post list --post_type='zombie' --format=ids
step 2
wp post update 33 45 68 --post_status=publish

B. Regenerate last 50 uploaded images

wp media regenerate  $(wp post list --post_type=attachment --format=ids --posts_per_page=50)

C. Update multi-site installation

for url in $(wp site list --fields=url --format=csv | tail -n +2)do wp --url=$url core update-dbdone

D. Update WordPress settings

wp option update page_on_front $( wp post list --post_type=page --posts_per_page=1 --format=ids --s=homepage --procelain)

Nice, what else?

A. Simplify multiple steps

It’s no composer but it does the job

cat plugins.txt | xargs wp plugin install


B. Simplify multiple steps

wp core multisite-install --url="" --base="" --title="HBO network"  --admin_user=gaya --admin_password=wadup --admin_email="" 

# For each line add a new site within the multisite installation

while read show ;
    # Creating multisite {$show}
    wp site create --slug=$show --title=$show
done < shows.txt

Bash install a.k.a. shell provisioning

Bash script for a clean WordPress installation


Use it within deployments scripts
See Luc's talk

New stuff

New design (thanks @levellevel)

Search and replace speed

Possible 3,000% performance increase
when column doesn't contain serialized data

New commands

  • wp super-admin  for managing caped admins on multisite
  • wp menu  for managing navigation menus
  • wp widget  and wp sidebar  for managing widgets and sidebars 
  • wp theme mod  for managing theme mods
  • wp cron  for managing WordPress cron jobs

New commands

  • wp core verify-checksums  verifies WordPress install against checksums
  • wp cli version  WP-CLI self checking
  • wp core version  display the current version
  • wp core check-update  lists possible new versions
  • wp core language  manage new languages since 4.0

Skip plugins flag

Unload specific broken plugin with fatal error...

wp plugin deactivate my-broken-plugin --skip-plugins=my-broken-plugin
Or just offload all
wp custom-command --skip-plugins

Arbitrary command nesting


Only top-level commands, like  wp search-replace   
and second-level subcommands  wp core install


You can have commands at any depth, such as
  wp post meta update 

WP-CLI configuration

a YAML config file -

  1. Command-line flags
  2. wp-cli.local.yml file inside the current working directory (or upwards)

  1. wp-cli.yml file inside the current working directory (or upwards)

  1. ~/.wp-cli/config.yml file (path can be changed by setting the WP_CLI_CONFIG_PATH environment variable in .profile)
  2. Defaults

WP-CLI configuration

path: wp
 - ../wp-cli/dictator/dictator.php
 - ../wp-cli/importer/wordpress-importer-wp-cli.php
 - wp-elasticsearch
user: admin
color: false
  - db drop
  - plugin install

Almost there!

Extending WP-CLI

Community packages
Package index

Community commands

wp config pull active-plugins
wp dictator impose settings.yml 
wp wpmdb migrate
wp total-cache flush db
wp acf export

Community commands

WordPress Plugins can supply commands

Available per WordPress install

// Plugin Name: Sweet Plugin
if ( defined('WP_CLI') && WP_CLI ) {
	include __DIR__ . '/my-command.php';

Community packages

These commands are globally available for every install

Add them to the  ~/wp-cli/wp-cli.yml

  - ../wp-cli/dictator/dictator.php
  - ../bin/importer/wordpress-importer-wp-cli.php
How to install community packages


Inline PHP Doc blocks displayed when calling --help
wp post create --help

And displayed on the website as documentation :)



Turns something like  <object-id>... 
optional => false,
type => positional,
repeating => true,
name => object-id


 * @synopsis --handshake[=<secret>] [--a=<b>]

Brackets are optional and can be nested

... dots make it possible to pass 1 of multiple arguments

wp post delete 1 3 4 5 66 798 


* Description of what the command does
* <id>...
* : The first one it the positional variable $args
* [--flag]
* : You can descripe what a flag or an associated arguments does right beneath it
* [--<field>=<value>]
* : This is an associated argument. So if --posts_per_page=5 is used, you can check for $assoc_args['posts_per_page']
* --yo=<value>
* : So know $assoc_args['yo'] is available


 * wp command name-with-underscores --flag --post_type=page --post_title='A future post'
 * @subcommand name-with-underscore
# The @subcommand give you the option to rename the command in situations like
function name_with_underscores( $arg, $assoc_args ){



Any questions?

Jaime Martinez

Made with