Saving Time with WP-CLI

Taylor Lovett
Taylor LovettDirector of Web Engineering at 10up
Saving Time
with WP-CLI
Who Am I?
• My name is Taylor Lovett
Senior Strategic Engineer at 10up
Plugin Author (Safe Redirect Manager, Feed Pull)
Plugin Contributor (WP-CLI and others)
Core Contributor
We’re hiring!
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.
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.
Don’t be scared of the
command line!
Installing WP-CLI
• Installation is very easy!
• Instructions here: http://wp-cli.org/
Tons of cool commands
are built-in!
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
Generating Dummy Data
• Ever wish you had a bunch of test data when
building a new theme or plugin?
wp generate posts --count=500
wp generate users --role=contributor
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/)
Create Database Dumps
• WP-CLI lets you easily create database dumps:
wp db dump
(From http://wp-cli.org/commands/db/)
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
Import
wp import <file> --authors=<authors> …
(From http://wp-cli.org/commands/import/)
• Example
wp import import.xml --authors=create
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
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.
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
Command and
Subcommands
• WP-CLI has this notion of commands and
subcommands.
wp post delete 476
• “post” is the command. “delete” is the subcommand
Community Commands
• There is a large community of people developing
WP-CLI commands:
http://wp-cli.org/package-index/
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.
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.
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.
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.
Creating Commands
• Now that our base command is scaffolded. Let’s
build something cool.
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?
Yes!! 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' );
<?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 ) {
$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.' );
}
}
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.
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' );
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.' );
}
Questions?
Twitter: tlovett12
Email: taylor.lovett@10up.com
1 of 34

Recommended

You Got React.js in My PHP by
You Got React.js in My PHPYou Got React.js in My PHP
You Got React.js in My PHPTaylor Lovett
7.2K views31 slides
Best Practices for WordPress in Enterprise by
Best Practices for WordPress in EnterpriseBest Practices for WordPress in Enterprise
Best Practices for WordPress in EnterpriseTaylor Lovett
10.8K views59 slides
Best Practices for Building WordPress Applications by
Best Practices for Building WordPress ApplicationsBest Practices for Building WordPress Applications
Best Practices for Building WordPress ApplicationsTaylor Lovett
6.1K views50 slides
Best Practices for WordPress by
Best Practices for WordPressBest Practices for WordPress
Best Practices for WordPressTaylor Lovett
11.3K views51 slides
Isomorphic WordPress Applications with NodeifyWP by
Isomorphic WordPress Applications with NodeifyWPIsomorphic WordPress Applications with NodeifyWP
Isomorphic WordPress Applications with NodeifyWPTaylor Lovett
14K views32 slides
JSON REST API for WordPress by
JSON REST API for WordPressJSON REST API for WordPress
JSON REST API for WordPressTaylor Lovett
23K views24 slides

More Related Content

What's hot

The JSON REST API for WordPress by
The JSON REST API for WordPressThe JSON REST API for WordPress
The JSON REST API for WordPressTaylor Lovett
30.9K views37 slides
Modernizing WordPress Search with Elasticsearch by
Modernizing WordPress Search with ElasticsearchModernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with ElasticsearchTaylor Lovett
1.5K views39 slides
Unlocking the Magical Powers of WP_Query by
Unlocking the Magical Powers of WP_QueryUnlocking the Magical Powers of WP_Query
Unlocking the Magical Powers of WP_QueryDustin Filippini
5.8K views17 slides
Here Be Dragons - Debugging WordPress by
Here Be Dragons - Debugging WordPressHere Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPressRami Sayar
2K views45 slides
CouchDB for Web Applications - Erlang Factory London 2009 by
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009Jason Davies
2.2K views52 slides
WordPress CLI in-depth by
WordPress CLI in-depthWordPress CLI in-depth
WordPress CLI in-depthSanjay Willie
339 views25 slides

What's hot(20)

The JSON REST API for WordPress by Taylor Lovett
The JSON REST API for WordPressThe JSON REST API for WordPress
The JSON REST API for WordPress
Taylor Lovett30.9K views
Modernizing WordPress Search with Elasticsearch by Taylor Lovett
Modernizing WordPress Search with ElasticsearchModernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with Elasticsearch
Taylor Lovett1.5K views
Unlocking the Magical Powers of WP_Query by Dustin Filippini
Unlocking the Magical Powers of WP_QueryUnlocking the Magical Powers of WP_Query
Unlocking the Magical Powers of WP_Query
Dustin Filippini5.8K views
Here Be Dragons - Debugging WordPress by Rami Sayar
Here Be Dragons - Debugging WordPressHere Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPress
Rami Sayar2K views
CouchDB for Web Applications - Erlang Factory London 2009 by Jason Davies
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009
Jason Davies2.2K views
Perl in the Real World by OpusVL
Perl in the Real WorldPerl in the Real World
Perl in the Real World
OpusVL661 views
Caching, Scaling, and What I've Learned from WordPress.com VIP by Erick Hitter
Caching, Scaling, and What I've Learned from WordPress.com VIPCaching, Scaling, and What I've Learned from WordPress.com VIP
Caching, Scaling, and What I've Learned from WordPress.com VIP
Erick Hitter3K views
Software Development with Open Source by OpusVL
Software Development with Open SourceSoftware Development with Open Source
Software Development with Open Source
OpusVL773 views
Introduction to CouchDB by OpusVL
Introduction to CouchDBIntroduction to CouchDB
Introduction to CouchDB
OpusVL1.4K views
Optimization of modern web applications by Eugene Lazutkin
Optimization of modern web applicationsOptimization of modern web applications
Optimization of modern web applications
Eugene Lazutkin2K views
DSpace UI Prototype Challenge: Spring Boot + Thymeleaf by Tim Donohue
DSpace UI Prototype Challenge: Spring Boot + ThymeleafDSpace UI Prototype Challenge: Spring Boot + Thymeleaf
DSpace UI Prototype Challenge: Spring Boot + Thymeleaf
Tim Donohue1.4K views
Save Time by Managing WordPress from the Command Line by Shawn Hooper
Save Time by Managing WordPress from the Command LineSave Time by Managing WordPress from the Command Line
Save Time by Managing WordPress from the Command Line
Shawn Hooper2.9K views
10 things every developer should know about their database to run word press ... by Otto Kekäläinen
10 things every developer should know about their database to run word press ...10 things every developer should know about their database to run word press ...
10 things every developer should know about their database to run word press ...
Otto Kekäläinen5.7K views
WordPress Theme and Plugin Optimization - WordPress Arvika March '14 by slobodanmanic
WordPress Theme and Plugin Optimization - WordPress Arvika March '14WordPress Theme and Plugin Optimization - WordPress Arvika March '14
WordPress Theme and Plugin Optimization - WordPress Arvika March '14
slobodanmanic676 views
Day 7 - Make it Fast by Barry Jones
Day 7 - Make it FastDay 7 - Make it Fast
Day 7 - Make it Fast
Barry Jones897 views
Exciting JavaScript - Part II by Eugene Lazutkin
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part II
Eugene Lazutkin1.7K views

Similar to Saving Time with WP-CLI

WordPress and The Command Line by
WordPress and The Command LineWordPress and The Command Line
WordPress and The Command LineKelly Dwan
3.9K views34 slides
[Bristol WordPress] Supercharging WordPress Development by
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress DevelopmentAdam Tomat
889 views68 slides
Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car... by
Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car...Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car...
Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car...Andrea Cardinali
3.1K views82 slides
WP-CLI - A Good Friend of Developer by
WP-CLI - A Good Friend of DeveloperWP-CLI - A Good Friend of Developer
WP-CLI - A Good Friend of DeveloperChandra Patel
35 views27 slides
Supercharging WordPress Development - Wordcamp Brighton 2019 by
Supercharging WordPress Development - Wordcamp Brighton 2019Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019Adam Tomat
612 views64 slides
Administer WordPress with WP-CLI by
Administer WordPress with WP-CLIAdminister WordPress with WP-CLI
Administer WordPress with WP-CLISuwash Kunwar
682 views53 slides

Similar to Saving Time with WP-CLI(20)

WordPress and The Command Line by Kelly Dwan
WordPress and The Command LineWordPress and The Command Line
WordPress and The Command Line
Kelly Dwan3.9K views
[Bristol WordPress] Supercharging WordPress Development by Adam Tomat
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development
Adam Tomat889 views
Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car... by Andrea Cardinali
Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car...Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car...
Gestione avanzata di WordPress con WP-CLI - WordCamp Torino 2017 - Andrea Car...
Andrea Cardinali3.1K views
WP-CLI - A Good Friend of Developer by Chandra Patel
WP-CLI - A Good Friend of DeveloperWP-CLI - A Good Friend of Developer
WP-CLI - A Good Friend of Developer
Chandra Patel35 views
Supercharging WordPress Development - Wordcamp Brighton 2019 by Adam Tomat
Supercharging WordPress Development - Wordcamp Brighton 2019Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019
Adam Tomat612 views
Administer WordPress with WP-CLI by Suwash Kunwar
Administer WordPress with WP-CLIAdminister WordPress with WP-CLI
Administer WordPress with WP-CLI
Suwash Kunwar682 views
WP-CLI - WordCamp Miami 2015 by Shawn Hooper
WP-CLI - WordCamp Miami 2015WP-CLI - WordCamp Miami 2015
WP-CLI - WordCamp Miami 2015
Shawn Hooper1.7K views
WordCamp Vancouver 2012 - Manage WordPress with Awesome using wp-cli by GetSource
WordCamp Vancouver 2012 - Manage WordPress with Awesome using wp-cliWordCamp Vancouver 2012 - Manage WordPress with Awesome using wp-cli
WordCamp Vancouver 2012 - Manage WordPress with Awesome using wp-cli
GetSource1.1K views
Developers, Be a Bada$$ with WP-CLI by WP Engine
Developers, Be a Bada$$ with WP-CLIDevelopers, Be a Bada$$ with WP-CLI
Developers, Be a Bada$$ with WP-CLI
WP Engine1.1K views
WP-CLI Talk from WordCamp Montreal by Shawn Hooper
WP-CLI Talk from WordCamp MontrealWP-CLI Talk from WordCamp Montreal
WP-CLI Talk from WordCamp Montreal
Shawn Hooper954 views
Windows Server 2008 (PowerShell Scripting Uygulamaları) by ÇözümPARK
Windows Server 2008 (PowerShell Scripting Uygulamaları)Windows Server 2008 (PowerShell Scripting Uygulamaları)
Windows Server 2008 (PowerShell Scripting Uygulamaları)
ÇözümPARK1.4K views
Take Command of WordPress With WP-CLI by Diana Thompson
Take Command of WordPress With WP-CLITake Command of WordPress With WP-CLI
Take Command of WordPress With WP-CLI
Diana Thompson148 views
Manage WordPress with Awesome using wp cli by GetSource
Manage WordPress with Awesome using wp cliManage WordPress with Awesome using wp cli
Manage WordPress with Awesome using wp cli
GetSource2.5K views
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT) by Mike Schinkel
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Mike Schinkel10.5K views
Take Command of WordPress With WP-CLI by Diana Thompson
Take Command of WordPress With WP-CLITake Command of WordPress With WP-CLI
Take Command of WordPress With WP-CLI
Diana Thompson424 views
Custom Post Types in WP3 by gregghenry
Custom Post Types in WP3Custom Post Types in WP3
Custom Post Types in WP3
gregghenry1.5K views
WordPress by risager
WordPressWordPress
WordPress
risager1.2K views
Take Command of WordPress With WP-CLI by Diana Thompson
Take Command of WordPress With WP-CLITake Command of WordPress With WP-CLI
Take Command of WordPress With WP-CLI
Diana Thompson339 views
Creating Your First WordPress Plugin by Brad Williams
Creating Your First WordPress PluginCreating Your First WordPress Plugin
Creating Your First WordPress Plugin
Brad Williams4.8K views
Take Command of WordPress With WP-CLI at WordCamp Long Beach by Diana Thompson
Take Command of WordPress With WP-CLI at WordCamp Long BeachTake Command of WordPress With WP-CLI at WordCamp Long Beach
Take Command of WordPress With WP-CLI at WordCamp Long Beach
Diana Thompson212 views

Recently uploaded

DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme... by
DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...
DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...Deltares
5 views28 slides
Software evolution understanding: Automatic extraction of software identifier... by
Software evolution understanding: Automatic extraction of software identifier...Software evolution understanding: Automatic extraction of software identifier...
Software evolution understanding: Automatic extraction of software identifier...Ra'Fat Al-Msie'deen
9 views33 slides
DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the... by
DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the...DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the...
DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the...Deltares
6 views22 slides
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft... by
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...Deltares
7 views18 slides
Copilot Prompting Toolkit_All Resources.pdf by
Copilot Prompting Toolkit_All Resources.pdfCopilot Prompting Toolkit_All Resources.pdf
Copilot Prompting Toolkit_All Resources.pdfRiccardo Zamana
8 views4 slides
Keep by
KeepKeep
KeepGeniusee
75 views10 slides

Recently uploaded(20)

DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme... by Deltares
DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...
DSD-INT 2023 Salt intrusion Modelling of the Lauwersmeer, towards a measureme...
Deltares5 views
Software evolution understanding: Automatic extraction of software identifier... by Ra'Fat Al-Msie'deen
Software evolution understanding: Automatic extraction of software identifier...Software evolution understanding: Automatic extraction of software identifier...
Software evolution understanding: Automatic extraction of software identifier...
DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the... by Deltares
DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the...DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the...
DSD-INT 2023 Leveraging the results of a 3D hydrodynamic model to improve the...
Deltares6 views
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft... by Deltares
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...
DSD-INT 2023 Process-based modelling of salt marsh development coupling Delft...
Deltares7 views
Copilot Prompting Toolkit_All Resources.pdf by Riccardo Zamana
Copilot Prompting Toolkit_All Resources.pdfCopilot Prompting Toolkit_All Resources.pdf
Copilot Prompting Toolkit_All Resources.pdf
Riccardo Zamana8 views
Quality Engineer: A Day in the Life by John Valentino
Quality Engineer: A Day in the LifeQuality Engineer: A Day in the Life
Quality Engineer: A Day in the Life
John Valentino6 views
Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI... by Marc Müller
Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI...Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI...
Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI...
Marc Müller37 views
DSD-INT 2023 Delft3D FM Suite 2024.01 1D2D - Beta testing programme - Geertsema by Deltares
DSD-INT 2023 Delft3D FM Suite 2024.01 1D2D - Beta testing programme - GeertsemaDSD-INT 2023 Delft3D FM Suite 2024.01 1D2D - Beta testing programme - Geertsema
DSD-INT 2023 Delft3D FM Suite 2024.01 1D2D - Beta testing programme - Geertsema
Deltares17 views
Gen Apps on Google Cloud PaLM2 and Codey APIs in Action by Márton Kodok
Gen Apps on Google Cloud PaLM2 and Codey APIs in ActionGen Apps on Google Cloud PaLM2 and Codey APIs in Action
Gen Apps on Google Cloud PaLM2 and Codey APIs in Action
Márton Kodok5 views
Advanced API Mocking Techniques by Dimpy Adhikary
Advanced API Mocking TechniquesAdvanced API Mocking Techniques
Advanced API Mocking Techniques
Dimpy Adhikary19 views
Navigating container technology for enhanced security by Niklas Saari by Metosin Oy
Navigating container technology for enhanced security by Niklas SaariNavigating container technology for enhanced security by Niklas Saari
Navigating container technology for enhanced security by Niklas Saari
Metosin Oy14 views
Generic or specific? Making sensible software design decisions by Bert Jan Schrijver
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium... by Lisi Hocke
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Lisi Hocke30 views
Fleet Management Software in India by Fleetable
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India
Fleetable11 views
Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ... by Donato Onofri
Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ...Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ...
Unmasking the Dark Art of Vectored Exception Handling: Bypassing XDR and EDR ...
Donato Onofri825 views
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t... by Deltares
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...
DSD-INT 2023 Thermobaricity in 3D DCSM-FM - taking pressure into account in t...
Deltares9 views
FIMA 2023 Neo4j & FS - Entity Resolution.pptx by Neo4j
FIMA 2023 Neo4j & FS - Entity Resolution.pptxFIMA 2023 Neo4j & FS - Entity Resolution.pptx
FIMA 2023 Neo4j & FS - Entity Resolution.pptx
Neo4j7 views

Saving Time with WP-CLI

  • 2. Who Am I? • My name is Taylor Lovett Senior Strategic Engineer at 10up Plugin Author (Safe Redirect Manager, Feed Pull) Plugin Contributor (WP-CLI and others) Core Contributor
  • 4. 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.
  • 5. 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.
  • 6. Don’t be scared of the command line!
  • 7. Installing WP-CLI • Installation is very easy! • Instructions here: http://wp-cli.org/
  • 8. Tons of cool commands are built-in!
  • 9. 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
  • 10. Generating Dummy Data • Ever wish you had a bunch of test data when building a new theme or plugin? wp generate posts --count=500 wp generate users --role=contributor
  • 11. 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/)
  • 12. Create Database Dumps • WP-CLI lets you easily create database dumps: wp db dump (From http://wp-cli.org/commands/db/)
  • 13. 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
  • 14. Import wp import <file> --authors=<authors> … (From http://wp-cli.org/commands/import/) • Example wp import import.xml --authors=create
  • 15. 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
  • 16. 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.
  • 17. 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
  • 18. Command and Subcommands • WP-CLI has this notion of commands and subcommands. wp post delete 476 • “post” is the command. “delete” is the subcommand
  • 19. Community Commands • There is a large community of people developing WP-CLI commands: http://wp-cli.org/package-index/
  • 20. 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.
  • 21. 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.
  • 22. 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.
  • 23. 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.
  • 24. Creating Commands • Now that our base command is scaffolded. Let’s build something cool.
  • 25. 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?
  • 27. 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' );
  • 28. <?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 ) {
  • 29. $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.' ); } }
  • 30. 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.
  • 32. 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' );
  • 33. 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.' ); }