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:
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:
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
:
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:
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:
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:
#!/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:
chmod +x /path/to/slider-posts.sh
Run the script passing the number of posts and alias as arguments:
/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:
<?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:
launchctl load "${HOME}/Library/LaunchAgents/com.tech-otaku.slider.posts"