By Jeff Cleverley, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
This is the final part in our 3-part deep dive into the advanced WordPress management abilities provided by WP-CLI.
In the previous tutorials we installed WP-CLI on our instances, prepared the correct permissions and user roles for it to work properly, and used it to manage your WordPress content. Then we dove deeper into more advanced functionality to managing our installations, plugins, themes, users and performed database operations. We also configured default parameters to allow us to manage many sites on a server with each command.
In the final tutorial, I am going to demonstrate how to further leverage WP-CLI to manage hundreds of sites across many different server instances, all from your local machine. We will explore commands that can be used to speed up development of feature plugins and themes, before finally extending WP-CLI to provide custom functionality via custom commands.
As ever, this tutorial assumes you already have an Alibaba Instance provisioned and with one (or several) WordPress sites running on it.
Throughout the series, I will be using my superuser 'new_user' and will be issuing 'root' commands using the sudo command. When you follow the commands please remember to replace my user with your own.
I will also be using my test domains 'an-example-domain.com' and 'another-example-domain.com' in the code examples, remember to replace my site domains with your own when you issue the commands.
1. Managing Multiple WordPress sites using WP-CLI
It's now obvious that using a CLI is much more efficient and productive than the browser to manage your WordPress sites. Things work much more quickly, and the commands are really quite easy once you get used to them.
We are getting an impression of the power that may be available if used properly. Still, it might not seem that much more efficient than doing it from the dashboard, especially when there are many services available that let you manage many WordPress installations at the same time.
So how can we do that? Well as is often the way, there are multiple methods. Today we will look at two of those.
Alias Groups and BASH scripts.
1a.Use Alias Groups to manage multiple sites
In the previous example I used Aliases to check the plugins on two sites with the following commands:
$ cd ~
$ wp @example plugin list
$ wp @another plugin list
But WP-CLI provides us with a solution to this inefficiency too. We can combine Aliases into Alias groups to perform actions on multiple sites with once command.
Let's create an Alias Group. Open your configuration file again for editing:
$ nano ~/.wp-cli/config.yml
And this time add another line below your previous aliases, like so:
# Alias Groups
@all-examples:
- @example
- @another
Your full configuration file should now look like this:
<Add an Alias Group to your configuration>
Now we can issue a single command. Let's list all the plugins on both our sites for example:
$ wp @all-examples plugin list
<Use an Alias Group to manage many sites>
In actual fact, this is redundant as WP-CLI also has a built in @all alias that will run any commands against all defined Aliases:
$ wp @all plugin list
But it serves for the demonstrative purposes required by this series of tutorials.
1b.Use BASH scripts with WP-CLI to manage multiple sites
We can achieve a similar result to the above by adding WP-CLI commands to BASH Scripts in the following way.
Create the a script file in your PATH:
$ sudo touch /usr/local/bin/wp-plugin-list.sh
$ sudo nano /usr/local/bin/wp-plugin-list.sh
Then add this code:
#!/bin/bash
declare -a sites=(
'/var/www/an-example-domain.com/htdocs'
'/var/www/another-example-domain.com/htdocs'
)
for site in "${sites[@]}";
do
echo “List plugins for:
echo $site
wp --path=$site plugin list
echo “ “
done
Save, exit, and make the script executable:
$ sudo chmod +x /usr/local/bin/wp-plugin-list.sh
Now we are ready to run our scripts. First run the script to check the plugins:
$ wp-plugin-list.sh
<List all your plugins using WP-CLI commands and a script>
In general using Aliases can be considered more optimal than creating BASH scripts, but there may be times a script may prove better. With a script you can combine WP-CLI commands with other non WP-CLI commands in different combinations that may prove more effective for managing many sites. We could for example backup our databases and then copy them to a different directory on our server or a third party storage solution.
The process of logging into each of your sites via the WP Admin, and checking for plugin updates would have taken much longer than either of these methods.
Note
From this point forwards, any commands demonstrated in this series of tutorials may be issued using an Alias if it is more appropriate. Please use your own aliases or replace any Alias with the full path to any WordPress directory you are acting upon.
2. Using SSH with WP-CLI for remote management
So far so good. We are now using the power of WP-CLI to manage multiple WordPress sites on the same server. If we have dozens or hundreds of sites this will save an incredible amount of valuable time.
But we can still improve our workflow.
At the moment we:
1.SSH into the remote server from our local server.
2.Either run WP-CLI commands in WordPress site directories or use scripts from within the server to run commands across many WordPress site directories on that server.
3.Repeat the process for any other servers.
What if we could combine these, and perhaps even run WP-CLI management commands across not just one Alibaba instance, but many instances, all from our Local machine?
That is not only possible, but often preferable.
To do this, you will need to have WP-CLI running on both your local machine and on all your Alibaba instances.
Instructions to install WP-CLI on your Windows PC.
Instructions to install WP-CLI on your Mac.
You will need to complete installation before you can complete this section.
From my local machine I can issue WP-CLI commands and use the '--ssh=' path command to have those WP-CLI command run on my remote server.
List my remote plugins with:
$ wp --ssh=new_user@an-example-domain.com/var/www/an-example-domain.com/htdocs/ plugin list
Or list my remote themes with:
$ wp --ssh=new_user@an-example-domain.com/var/www/an-example-domain.com/htdocs/ theme list
As you can see, this works perfectly:
<Use WP-CLI locally to manage WP sites hosted remotely>
Using Aliases and SSH
Having to type of the SSH command appended with the full path will become quite tiring and is inefficient. In a previous section we used Aliases to allow us to issue WP-CLI commands from anywhere within our Instance without requiring the full path, now we can use them again to do the same for SSH logins and paths.
Using Aliases Globally
We might not have a .wp-cli directory or Global configuration file yet created on our Local machine. If not first make them, then open the configuration file for editing:
(If one already exists, just open it for editing)
$ sudo mkdir ~/.wp-cli && sudo touch ~/.wp-cli/config.yml
$ sudo nano ~/.wp-cli/config.yml
We will add our Aliases in a very similar manner to how we added them to the Global configuration file on our instance. The only difference is that instead of using 'path' we will set them with the 'ssh' parameter. You should probably set your 'disabled_commands' at the same time:
#Global Parameter Defaults
disabled_commands:
- db drop
# Aliases
@example:
ssh: new_user@an-example-domain.com/var/www/an-example-domain.com/htdocs/
@another:
ssh: new_user@another-example-domain.com/var/www/another-example-domain.com/htdocs/
Our Global WP-CLI configuration file on our local machine should now look like this:
<Add remote Aliases to your local Global configuration file>
Now we can use WP-CLI locally and just add the Alias '@name' between the 'wp' command and the subcommands to easily run WP-CLI management tasks on our remote Alibaba instances.
From our Local machine, issue commands to our remote instances like so:
$ wp @example plugin list
or
$ wp @another core check-update
Using Alias Groups to manage multiple sites by SSH
Just like on our server, we can use Alias Groups locally to manage many multiple sites remotely.
The difference is, that now we can create Alias Groups that contain Aliases to WordPress sites on different serves. That means we can now use Alias Groups to issue commands from our Local machine that will manage many different WordPress sites on many different Alibaba instances.
Reopen your local Global configuration file:
$ nano ~/.wp-cli/config.yml
Add the following lines underneath the existing Aliases:
@all-examples:
- @example
- @another
Your configuration file should now look like this:
<Add Alias Group to your local Global configuration file>
Using Aliases within a Project
Sometimes we are using WP-CLI as part of a modern WordPress development and Deployment workflow. In other tutorials we have set up Staging, Local and Production environments and implemented a Git version controlled workflow.
WP-CLI works very well in this situation, and allows you to set specific Aliases per project within the project's local WP-CLI configuration file:
If you have a local development version of your production site, then we can add a 'wp-cli.yml' file to configure global parameters for this workflow.
Change directories to the root of one of your local development sites and create a 'wp-cli.yml' file in it:
$ cd /local/sites/anotherexampledomain/app/public
$ sudo nano wp-cli.yml
Within this file add different aliases for each of your remote sites:
@test:
ssh: new_user@another-example-domain.com/var/www/test.another-example-domain.com/htdocs
@staging:
ssh: new_user@another-domain.com/var/www/staging.another-domain.com/htdocs/
@production:
ssh: new_user@another-domain.com/var/www/another-domain.com/htdocs/
Your project 'wp-cli.yml' configuration file should now look like this:
<Add the SSH path to your staging and production sites>
Now when we are working locally, we can issue WP-CLI commands to our remote servers using these aliases, like so:
$ wp @production plugin list
And just like with Global Aliases we can create Alias Groups:
@test:
ssh: new_user@another-example-domain.com/var/www/test.another-example-domain.com/htdocs
@staging:
ssh: new_user@another-domain.com/var/www/staging.another-domain.com/htdocs/
@production:
ssh: new_user@another-domain.com/var/www/another-domain.com/htdocs/
@prerelease:
- @test
- @staging
We could now issue commands to a Project Alias Group like so:
$ wp @prerelease plugin list
3. Using WP-CLI Scaffold to speed up development
WP-CLI has a command called 'wp scaffold' that is used to generate the boilerplate code necessary for many of the standard WordPress development tasks.
These generating the basic code needed for:
- Child Themes
- Feature Plugins
- Custom Post Types
- Custom Taxonomies
- PHPunit testing of plugins
- PHPunit testing of themes
Demonstrating the PHPunit testing code generation is beyond the scope of this tutorial as it requires a series in itself. But let's quickly run through some of the other cool things 'wp scaffold' can do:
If we want to create our basic directory structure and minimum necessary files for a theme to be activated, we can do that with the following command:
wp @example scaffold child-theme twentyseventeen-child --parent_theme=twentyseventeen --theme_name="Twenty Seventeen Child" --author="New User" --author_uri="an-example-domain.com" --theme_uri="an-example-theme.com" —activate
Notice how I am creating a Child theme on our Alibaba instance from my local machine, using an Alias? Incredibly efficient.
We can see in the terminal the theme has been created:
<Create a Child theme with WP-CLI scaffold>
And it is activated on the site:
<Our new Child theme in the WP Admin>
What about a plugin, I hear you asking? Well that is just as simple:
wp @example scaffold plugin custom-plugin --plugin_name="Custom Plugin" --plugin_description="A custom plugin for custom functionality" --plugin_author="New User" --plugin_author_uri=https://an-example-domain.com --plugin_uri=https://custom-plugin.com —activate
And now we have a plugin installed and activated:
<Our new Plugin in the WP Admin>
One of the most common developer tasks with WordPress is building custom post types and taxonomies for true Custom WordPress development.
We can create the Custom Post type boilerplate code, and add it to either a plugin or theme, with the necessary directory structure using:
wp @example scaffold post-type tutorials --label="Tutorials" --plugin=custom-plugin --dashicon=welcome-learn-more
Likewise, with a Custom taxonomy:
wp @example scaffold taxonomy wpcli --post_types=posts --label="wpcli" --plugin=custom-plugin
You can inspect the code and directory structure generated in the WP Admin:
<Custom Post Type Boilerplate code and files generated in a plugin>
<Custom Taxonomy Boilerplate code and files generated in a plugin>
4 Extending WP-CLI
If you have followed through these tutorials and gotten to this point, it is my hope that you now consider WP-CLI an indispensable tool in your WordPress toolset.
Even if we ended here, then this is great!
Our journey doesn't end here though, WP-CLI is the gift that keeps on giving, as WP-CLI is extensible!
This can be achieved in two ways, you can either load PHP in from a file and execute it in WP-CLI, or you can build a plugin that creates a custom command.
To demonstrate both methods, I will use a similar example output.
Execute a PHP file
If you have a PHP snippet you want to test to see if it works, you don't need to go to the lengths of including it in a WordPress plugin, or your functions.php theme file to test it.
You can quickly test it using the 'wp eval-file' command provided by WP-CLI. This will execute your PHP file after having loaded WordPress.
Create a 'random-post.php' file in your home directory, and open it for editing:
$ nano random-post.php
Inside the file add the following code:
<?php
global $wpdb;
$random_example_post = $wpdb->get_var(
"SELECT post_title
FROM $wpdb->posts
WHERE post_type = 'post'
AND post_status = 'publish'
ORDER BY rand()
LIMIT 1"
);
echo "A random example post: $random_example_post \n";
In your editor your PHP script:
<Your PHP script file to run>
This is just a basic function that queries the database for a random post and displays it out.
Now run the following command, either using an Alias or from within a WordPress directory:
$ wp @example eval-file random-post.php
Your terminal will now display a random post title:
<Execute a PHP file in WordPress with WP-CLI eval-file>
Create Custom Commands in a Plugin
We can also extend WP-CLI's inbuilt functionality by creating our own WordPress plugins. In this manner we can extend WP-CLI by adding our own custom functionality accessed through WP-CLI commands we define.
First, we shall put the 'wp scaffold' function to good use to create our plugin boilerplate:
wp @example scaffold plugin wp-cli-custom-commands —plugin_name=“WP-CLI Custom Commands" --plugin_description="A custom plugin for creating a WP-CLI custom command“ --plugin_author="New User" --activate
Now change directory to the plugin root directory and open the plugin file:
$ sudo nano wp-cli-custom-commands.php
$ cd /var/www/an-example-domain.com/htdocs/wp-content/plugins/wp-cli-custom-commands
The Plugin file requires a class for each command, and public methods for each subcommand.
To demonstrate this, we recreate the same functionality as contained in the previous script and have it execute on a the 'random-post' command.
We will create a class, called 'Custom_Commands', that contains a single public method, 'random_post' for our subcommand - this executes the same simple database query to return a random post as in the above script.
We will then register our class as a WP-CLI command using an 'add-command' call. This function takes the name of the command and the name of the class as it's arguments.
in your 'wp-cli-custom-commands.php' add the following code:
if( defined( 'WP_CLI' ) && WP_CLI ) {
class Custom_Commands {
function random_post ( $args, $assoc_args ) {
global $wpdb;
$random_post = $wpdb->get_var(
"SELECT post_title FROM $wpdb->posts
WHERE post_type = 'post'
AND post_status = 'publish'
ORDER BY rand()
LIMIT 1");
WP_CLI::success( "Random post: $random_post" );
}
}
WP_CLI::add_command( 'custom_commands', 'Custom_Commands' );
}
Our plugin's main file should look like this in the editor:
<Your custom command plugin file>
The Plugin URI and Author URI are missing as I didn't define them in the 'wp scaffold' command, you could include them in yours.
Now we can confirm that the command has been registered by executing:
$ wp @example custom_commands
This will list the available subcommands; we only have one 'random_post'. We can execute that command now:
$ wp @example custom_commands random_post
In your terminal WP-CLI should return a 'Success' message followed by a randomly selected Post title from your WordPress site:
<Congratulations - You have successfully extended WP-CLI>
Well done, you have now created and executed your very first WP-CLI custom command!
You should now be able to see how you can use Plugins to create Commands that will perform any number of functions on your WordPress site and create a simple way to perform any administrative WordPress task you can think of.
We have reached the end of this series of tutorials. It has been quite a long in depth dive into the possibilities of WP-CLI, but believe me when I tell you… this is just scratching the surface of the possibilities.
If you want to find out more, make sure you check the official resources: