Using WP-CLI to Update WordPress Theme Options

U

WordPress theme’s can have a multitude of options requiring manual configuration to tailor the theme to your liking. This post looks at using WP-CLI to configure theme options from the macOS command line. To demonstrate, I’ll use the option that controls the posts appearing in the slider at the top of this site’s home page.

For information on installing WP-CLI, some basic configuration tips and examples of using aliases please refer to Installing and Configuring WP-CLI on macOS.

This site uses the Typology theme by Meks. The theme option that controls which posts appear in the slider is front_page_cover_posts_manual and requires a comma-separated string of post IDs.

I can use WP-CLI to get the current value of this option:

Dummy Content
wp @production option pluck typology_settings front_page_cover_posts_manual
1789,6090,1860,5524,1282

 

 

The constituent parts of the command string are:

wp The WP-CLI binary. Usually located in /usr/local/bin.
@production The alias for the WordPress installation being targeted. Aliases are configured in ~/.wp-cli/config.yaml.
option pluck The WP-CLI command to retrieve a nested option.
typology_settings The option_name value in the wp_options table. Contains all the theme options.
front_page_cover_posts_manual The nested option name within the typology_settings option.

 

 

To update which posts appear in the slider I replace the WP-CLI command option pluck with option patch update and provide a new comma-separated list of post IDs:

Dummy Content
wp @production option patch update typology_settings front_page_cover_posts_manual '4825,5232,2163,6090,245'
Success: Updated 'typology_settings' option.

 

 

Rather than manually creating a comma-separated list of post IDs, one can be automatically generated using post list:

Dummy Content
wp @production post list --posts_per_page=5 --post_status=publish --post_type=post --orderby=rand --format=ids
4737 940 6554 250 6473

 

 

The post list command uses any argument supported by WP_Query to return post data. Here I’m selecting 5 published posts in random order. The --format=ids argument ensures that only the ID of each post is returned.

The output from this command isn’t in the correct format. The post IDs are separated by spaces not commas, but by piping the output of the command to tr the spaces can be changed to commas:

Dummy Content
wp @production post list --posts_per_page=5 --post_status=publish --post_type=post --orderby=rand --format=ids | tr ' ' ,
4737,940,6554,250,6473

 

 

By passing the command string that generates random post IDs as an argument to the command string that updates the theme option I can change what appears in the slider with a set of randomly selected posts:

Dummy Content
wp @production option patch update typology_settings front_page_cover_posts_manual $(wp @production post list --posts_per_page=5 --post_status=publish --post_type=post --orderby=rand --format=ids | tr ' ' ,)
Success: Updated 'typology_settings' option.

 

 

For convenience the command can be placed in a script:

Dummy Content
#!/bin/bash

# USAGE [/bin/bash] /path/to/slider-posts.sh <number-of-posts> <alias>
# $1 = Number of posts to include in the slider
# $2 = The alias to the WordPress installation

if [ $# -ne 2 ]; then
	printf "ERROR: 2 arguments are required: <number-of-posts> <alias>"
	exit 1
elif [[ ! $(/usr/local/bin/wp cli alias get @"${2}" 2>/dev/null) ]]; then 
	printf "ERROR: The alias \"@${2}\" doesn't exist."
	exit 1
fi

/usr/local/bin/wp @"${2}" option patch update typology_settings front_page_cover_posts_manual $(/usr/local/bin/wp @"${2}" post list --posts_per_page="${1}" --post_status=publish --post_type=post --orderby=rand --format=ids | tr ' ' ,)

 

 

NOTE: The script explicitly uses the full path to the WP-CLI binary: /usr/local/bin/wp. This is to allow the script to be executed by launchd. When the script is executed from the command-line, it searches the directories defined in the user’s $PATH environment variable for the WP-CLI binary. The $PATH environment variable will invariably contain the /usr/local/bin directory. However, launchd has a default search path limited to /usr/bin:/bin:/usr/sbin:/sbin. Consequently, if launchd attempted to run this script without the script using the full path to the WP-CLI binary it would fail.

The script requires two arguments: the number of posts to include in the slider and the alias to the WordPress install being targeted. In addition, the script uses WP-CLI to check the alias and exit with an error if the alias doesn’t exist.

Make the script executable:

Dummy Content
chmod +x /path/to/slider-posts.sh

 

 

Run the script passing the number of posts and alias as arguments:

Dummy Content
/path/to/slider-posts.sh 5 production
Updated 'typology_settings' option.

 

 

Now I have a working script I can use launchd to execute the script at a regular interval by first creating a job definition file. This file should have a .plist extension and be located in the ~/Library/LaunchAgents directory:

Dummy Content
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.tech-otaku.slider.posts</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/slider-posts.sh</string>
        <string>5</string>
        <string>production</string>
    </array>
    <key>StandardErrorPath</key>
    <string>/tmp/com.tech-otaku.slider.posts.stderr</string>
    <key>StandardOutPath</key>
    <string>/tmp/com.tech-otaku.slider.posts.stdout</string>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>23</integer>
            <key>Minute</key>
            <integer>0</integer>
        </dict>
    </array>
</dict>
</plist>

 

 

When active, this job definition will execute /path/to/slider-posts.sh 5 production at 23:00 everyday.

To activate a job definition, it needs to be loaded. All enabled job definitions are loaded automatically when your Mac powers-on or you login, but to load it explicitly:

Dummy Content
launchctl load "${HOME}/Library/LaunchAgents/com.tech-otaku.slider.posts"

 

 

About the author

A native Brit exiled in Japan, Steve spends too much of his time struggling with the Japanese language, dreaming of fish & chips and writing the occasional blog post he hopes others will find helpful.

Add comment

Steve

Recent Comments

Recent Posts