34
Saving Time with WP-CLI

Saving Time with WP-CLI

Embed Size (px)

DESCRIPTION

WP-CLI is an awesome WordPress plugin that can be used to automate a bunch of difficult WordPress tasks. This presentation walks you through basic WP-CLI commands and creating custom commands.

Citation preview

Page 1: Saving Time with WP-CLI

Saving Timewith WP-CLI

Page 2: Saving Time with WP-CLI

Who Am I?

• My name is Taylor Lovett

Senior Strategic Engineer at 10upPlugin Author (Safe Redirect Manager, Feed Pull)Plugin Contributor (WP-CLI and others)Core Contributor

Page 3: Saving Time with WP-CLI

We’re hiring!

Page 4: Saving Time with WP-CLI

What Is WP-CLI?• WP-CLI is a WordPress plugin that enables you

to interact with your WordPress installations via the command line (Unix).

• WP-CLI lets you do a ton of things - create new sites, install plugins, import, export, batch create/delete posts, etc.

• WP-CLI is extensible. You can easily write your own WP-CLI commands.

Page 5: Saving Time with WP-CLI

Why Use WP-CLI?

• Doing certain tasks from within WP admin are very difficult…

- Bulk deleting posts, bulk editing posts, bulk tagging posts, importing, exporting, etc.

Page 6: Saving Time with WP-CLI

Don’t be scared of the command line!

Page 7: Saving Time with WP-CLI

Installing WP-CLI

• Installation is very easy!

• Instructions here: http://wp-cli.org/

Page 8: Saving Time with WP-CLI

Tons of cool commands are built-

in!

Page 9: Saving Time with WP-CLI

Search and replace

wp search-replace <old-string> <new-string> …(Full list of command options at http://wp-cli.org/commands/search-replace/)

Example:

wp search-replace testsite.com livesite.com wp_posts

Page 10: Saving Time with WP-CLI

Generating Dummy Data

• Ever wish you had a bunch of test data when building a new theme or plugin?

wp generate posts --count=500wp generate users --role=contributor

Page 11: Saving Time with WP-CLI

Regenerate Post Thumbnails

• Easily regenerate post thumbnails without having to deal with plugins and WP admin:

wp media regenerate

(From http://wp-cli.org/commands/media/regenerate/)

Page 12: Saving Time with WP-CLI

Create Database Dumps

• WP-CLI lets you easily create database dumps:

wp db dump

(From http://wp-cli.org/commands/db/)

Page 13: Saving Time with WP-CLI

Export

wp export [--dir=<dirname>] [--skip_comments] …(From http://wp-cli.org/commands/export/)

• Example

wp export --dir=~/temp --max_file_size=5 --start_date=2012-05-12 --end_date=2014-01-10

Page 14: Saving Time with WP-CLI

Import

wp import <file> --authors=<authors> …(From http://wp-cli.org/commands/import/)

• Example

wp import import.xml --authors=create

Page 15: Saving Time with WP-CLI

Global Command Parameters

--user=set the current user

--url=set the current URL

--path=set the current path to the WP install

--require=load a certain file before running the command

--versionprint WP-CLI version

• These parameters can be supplied to any WP-CLI command

Page 16: Saving Time with WP-CLI

Global Command Parameters

• The --path argument is especially useful. You can call the “wp” command from anywhere in the file system and specify an instance of WordPress to interact with.

• This is helpful if you are writing a crontab file, for example.

Page 17: Saving Time with WP-CLI

WP-CLI and Multisite

• WP-CLI works great with multisite! The global url parameter mentioned earlier lets you specify on which site to run the command. For example

wp --url=http://mysite.com/site2 post delete 3

Page 18: Saving Time with WP-CLI

Command and Subcommands

• WP-CLI has this notion of commands and subcommands.

wp post delete 476

• “post” is the command. “delete” is the subcommand

Page 19: Saving Time with WP-CLI

Community Commands

• There is a large community of people developing WP-CLI commands:

http://wp-cli.org/package-index/

Page 20: Saving Time with WP-CLI

Creating New Commands

• Sometimes we need to create new WP-CLI commands because the built-in ones don’t do what we want and an HTTP request just isn’t cutting it.

Page 21: Saving Time with WP-CLI

Creating Commands

• You can create a new WP-CLI command in a plugin or a theme. For a theme, this code can be added to functions.php, for a plugin, any PHP file that is parsed:

<?php

if ( defined( 'WP_CLI' ) && WP_CLI ) { include( 'includes/class-prefix-cli-utils.php' );}

Note: We don’t want to include our CLI class on normal HTTP requests which is why we check if WP_CLI is defined.

Page 22: Saving Time with WP-CLI

Creating Commands

• Remember how I mentioned commands and sub-commands? I generally create one command per plugin or theme and group everything as subcommands under it.

Page 23: Saving Time with WP-CLI

Creating Commands

• Here is includes/class-prefix-cli-utils.php:

<?php

/** * Utility commands for my theme/plugin */class Prefix_CLI_Utils extends WP_CLI_Command {

...}

WP_CLI::add_command( 'prefix-utils', 'Prefix_CLI_Utils' );

Note: We prefix classes and everything that is in a shared namespace so we don’t get any conflicts.

Page 24: Saving Time with WP-CLI

Creating Commands

• Now that our base command is scaffolded. Let’s build something cool.

Page 25: Saving Time with WP-CLI

A Problem to Solve

• Let’s imagine we are running a WordPress website with ~15,000 posts. We’ve decided we want to start making better use of post formats, specifically gallery. We want every post that has a [gallery] shortcode to have a post format of gallery. Is there anyway to do this without going through each post manually?

Page 26: Saving Time with WP-CLI

Yes!! WP-CLI!

Page 27: Saving Time with WP-CLI

Creating Our Command

<?php

/** * Utility commands for my theme/plugin */class Prefix_CLI_Utils extends WP_CLI_Command {

/** * Mark posts as gallery format if a gallery shortcode is in the post. * * ###OPTIONS * * [—-post_type=<post_type>] * : Restrict processing to certain post types * * [--status=<status>] * : Only process posts with this status * * @subcommand format-gallery-posts * @synopsis [—-post_type=<post_type>] [--status=<status>] */public function format_gallery_posts( $args, $assoc_args ) {

}}

WP_CLI::add_command( 'prefix-utils', 'Prefix_CLI_Utils' );

Page 28: Saving Time with WP-CLI

<?php

/** * Utility commands for my theme/plugin */class Prefix_CLI_Utils extends WP_CLI_Command {

/** * Mark posts as gallery format if a gallery shortcode is in the post. * * ###OPTIONS * * [--post_type=<post_type>] * : Restrict processing to certain post types * * [--status=<status>] * : Only process posts with this status * * @subcommand format-gallery-posts * @synopsis [--post_type=<post_type>] [--status=<status>] */public function format_gallery_posts( $args, $assoc_args ) {

$status = 'publish';if ( ! empty( $assoc_args['status'] ) ) {

$status = $assoc_args['status'];}

$post_type = 'post';if ( ! empty( $assoc_args['post_type'] ) ) {

$post_type = $assoc_args['post_type'];}

$page = 1;$posts_changed = 0;$posts_processed = 0;

WP_CLI::line( 'Start processing posts...' );

while ( true ) {

Page 29: Saving Time with WP-CLI

$query_args = array('status' => $status,'post_type' => $post_type,'cache_results' => false,'posts_per_page' => 50,'paged' => $page,'tax_query' => array(

array('taxonomy' => 'post_format','field' => 'slug','terms' => array( 'gallery' ),'operator' => 'NOT IN'

),)

);

$query = new WP_Query( $query_args );

if ( ! $query->have_posts() ) {break;

}

while ( $query->have_posts() ) {global $post;$query->the_post();

$posts_processed++;

if ( strpos( $post->post_content, '[gallery' ) !== false ) {set_post_format( $post, 'gallery' );$posts_changed++;

}}

$page++;}

wp_reset_postdata();

WP_CLI::success( $posts_processed . ' posts processed. ' . $posts_changed . ' posts changed.' );

}}

WP_CLI::add_command( 'prefix-utils', 'Prefix_CLI_Utils' );

Page 30: Saving Time with WP-CLI

Another Problem

• We’ve been running a blog for a few years with around ~4000 posts. We decide that we want to restructure our categories. For the last few years we have prepended “Breaking News: “ to important news posts. We want to categorize all these posts into a “News” category. We don’t want to go through each post manually.

Page 31: Saving Time with WP-CLI

WP-CLI!

Page 32: Saving Time with WP-CLI

Creating Our Command

<?php/** * Utility commands for my theme/plugin */class Prefix_CLI_Utils extends WP_CLI_Command {

/** * Tag posts that have titles starting with "Breaking News: " with the * category "News" * * ## EXAMPLES * * wp prefix-utils tag-news-posts * * @alias tag-news * @subcommand tag-news-posts */public function tag_news_posts( $args, $assoc_args ) {

}}

WP_CLI::add_command( 'prefix-utils', 'Prefix_CLI_Utils' );

Page 33: Saving Time with WP-CLI

public function tag_news_posts( $args, $assoc_args ) {

$page = 1;$posts_changed = 0;$posts_processed = 0;

WP_CLI::line( 'Start tagging posts...' );

while ( true ) {

$query_args = array('status' => 'publish','post_type' => 'post','cache_results' => false,'posts_per_page' => 50,'paged' => $page,

);

$query = new WP_Query( $query_args );

if ( ! $query->have_posts() ) {break;

}

while ( $query->have_posts() ) {$query->the_post();

$posts_processed++;

if ( preg_match( '#^Breaking News:#i', get_the_title() ) !== false ) {wp_set_object_terms( get_the_ID(), array( 'News' ), 'category', true );$posts_changed++;

}}

$page++;}

wp_reset_postdata();

WP_CLI::success( $posts_processed . ' posts processed. ' . $posts_changed . ' posts changed.' );

}

Page 34: Saving Time with WP-CLI

Questions?

Twitter: tlovett12Email: [email protected]