Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

WordPress – Working with CLI

Working with CLI

Basic work with posts

Search post content.

wp post list --s="text" --fields=ID,post_title,url

Find posts with ping status “open”.

wp post list --ping_status="open"

And if you only want to get the post IDs:

wp post list --ping_status="open" --fields=ID

Update ping status to “closed” where the value is “open”.

wp post update $(wp post list --ping_status="open" --format=ids) --ping_status="closed";

Search and replace

Search and replace post content.

bashwp search-replace "old thing" "new thing" --all-tables

Post meta

List all metadata associated with a post.

bashwp post meta list 1422 --format=json

Get specific post meta for a post.

bashwp post meta get 1422 "meta_key" --format=json

Update post meta.

bashwp post meta update 1422 "meta_key" "meta_value"

Update post meta from a file.

bashwp post meta update 1422 "post_meta" < file.json --format=json

Delete post meta.

bashwp post meta delete 1422 "post_meta"

Delete all post meta by specific key. (With wp db query.)

bashwp db query "DELETE FROM `wp_postmeta` WHERE `meta_key` = 'NAME_OF_YOUR_META_KEY'"

List posts by meta key or value.

bashwp post list --fields=ID,post_title,url --meta_key="meta_key"
wp post list --fields=ID,post_title,url --meta_key="meta_key" --meta_compare="NOT EXISTS"
wp post list --post_type="post_type" --fields=ID,post_title,url --meta_key="meta_key" --meta_compare="NOT EXISTS"
wp post list --fields=ID,post_title,url --meta_key="_wp_page_template" --meta_value="page-templates/post-full-grid.php"

The meta_compare flag also accepts "LIKE" as a value, so that you can do:

phpwp post list --fields=ID,post_title,url --meta_key='meta_key' --meta_compare='LIKE' --meta_value='value'

Update meta where it’s missing.

bashwp post meta update $(wp post list --post_type="post_type" --meta_key="meta_key" --meta_compare="NOT EXISTS" --format=ids) "meta_key" "meta_value"

Update post meta for all posts in a category.

bashwp post meta update $(wp post list --category_name="category" --format=ids) "meta_key" "meta_value"

Save meta value based on an existing meta value. In this example I’m looping through all post with a specific post type and saving the URL of the featured image to the post’s meta.

bashfor id in $(wp post list --post_type="post_type" --fields=ID --meta_key="meta_key" --meta_compare="NOT EXISTS")
    wp post meta update $id "meta_key" $(wp post meta pluck $(wp post meta get $id _thumbnail_id) _wp_attachment_metadata file)

Show specific meta value for posts based on a category.

bashfor id in $(wp post list --post_type="post_type" --fields=ID --category="category name")
    wp post meta get $id "meta_key"

Export/import all meta.

bashwp post meta list 1422 --format=json > 1422_meta.json
wp post update 1422 --meta_input= < 1422_meta.json

Working with post terms

Move posts from one tag to another.

bashfor id in $(wp post list --tag=OLD_TAG --format=ids)
    wp post term remove $id post_tag OLD_TAG --by=slug
    wp post term add $id post_tag NEW_TAG --by=slug

Delete Posts

Delete all posts from a custom post type. (Adding --force will skip the trash and remove the posts completely.)

bashwp post delete $(wp post list --post_type='activity' --format=ids) --force

If you’re trying to delete too many posts at once, you might get an error like this:

bashPHP Fatal error: Allowed memory size of xxx bytes exhausted

Or perhaps this one:

bashArgument list too long

One way around this is to limit how many posts you’re deleting at once using the posts_per_page option, for example:

bashwp post delete $(wp post list --post_type='activity' --posts_per_page=50000 --format=ids) --force

Delete posts with specific meta key.

bashwp post delete $(wp post list --format=ids --meta_key="meta_key")

Delete posts with specific meta key and meta value.

bashwp post delete $(wp post list --format=ids --meta_key="meta_key" --meta_value="meta_value")

Delete posts where a specific meta key is missing.

bashwp post delete $(wp post list --format=ids --meta_key="meta_key" --meta_compare="NOT EXISTS")

Post revisions

List all revisions.

bashwp post list --post_type=revision

List revisions for a specific post.

bashwp post list --post_parent=1422 --post_type=revision

Get more info on revisions for a specific post.

bashfor id in $(wp post list --post_parent=1422 --post_type=revision --fields=ID)
    wp post get $id

Site Options

Change the site URL.

bashwp option update home ''
wp option update siteurl ''


List active plugins.

bashwp plugin list --status=active

Activate/deactivate plugins.

bashwp plugin activate plugin-1 plugin-2 plugin-3
wp plugin deactivate plugin-1 plugin-2 plugin-3


Update user password.

wp user update USER_ID --user_pass="newpassword"

WP CLI cheatsheet

check database size

Returns sizes of all database tables in a human friendly format.


wp db size --human-readable --tables


check db status

Run health check on the database set in the wp-config.php file. It reports status of each database table separately in the output.


wp db check


check for updates

Checks if WP-CLI is due for an update.

wp cli check-update


check version

Return WP CLI version.

wp cli version


configure wordpress

Creates config.php file. Requires mysql cli to be installed.

wp config create --dbname=yourdbname --dbuser=root --prompt=dbpassword


count all posts

This command searches for all posts in the database and returns the count number.


wp post list --format=count 


download wordpress

Download latest version of WordPress core files to current directory.

wp core download


edit config

Opens wp-config.php file in the default text editor.

wp config edit



Exports WXR file containing XML formatted data about your site including posts, comments and information about images and other attachments. Site option settings are excluded.


wp export


export single page

By combining the following flags you can export a single page from WordPress. First set the post type you want to export (page) then set the ID of the post, and finally limit the command to only fetch a single post. Skipping comments is optional.


wp export --skip_comments --post_type=page --post__in=4995 --max_num_posts=1


generate salts

This command will generate authentication unique keys and salts in your wp-config.php file.


wp config shuffle-salts


get media image sizes

List all defined image sizes, their width, height and the crop details.


wp media image-size



Imports WXR files.


wp import yoursiteexample.wordpress.2021-09-22.000.xml


import to sub-site

You can import WXR data files to specific site in the multi-site installation. The –url flag identifies the site you want to migrate data to. Skipping authors is optional.


wp import yoursiteexample.wordpress.2021-10-15.000.xml --authors=skip --url=


install plugin

Install a plugin in your WordPress site. By passing –activate flag you can enable your new plugin in one command.

wp plugin install [pluginhandle] --activate


list all pages

This command is based on the “wp post list” used to return all posts but the “–post_type=page” flag changes the search scope to return only pages. By default the output if formatted as a table and includes page ID, title, slug, creation date, and the status.


wp post list --post_type=page


list all post meta

Use post ID to return all related meta data. By default it returns data as a table but other formats are available, for example you can use this flag –format=json to get data as json.


wp post meta list <ID>


list custom post type

Returns a table of custom posts with a type specified using the –post_type flag.


wp post list --post_type=movie


list database table columns

Lists all columns in a given database table. You will need to pass a table name as the argument. List of the default WordPress tables – wp_commentmeta, wp_comments, wp_links, wp_options, wp_postmeta, wp_posts, wp_term_relationships, wp_term_taxonomy, wp_termmeta, wp_terms, wp_usermeta, wp_users.


wp db columns {tabel name}


list database tables

Lists all tables in the database connected to your site.


wp db tables


list post types

Returns a table of all post types including custom posts.


wp post-type list


list posts

Returns a table of all posts including ID, title, name, date and status.


wp post list


list sites

If you’re running a multi-site WordPress installation you can return a handy table presenting blog ID, URL, and update dates of each site instance.


wp site list


list taxonomies

Returns a table of all registered taxonomies including categories, post tags, navigation menus, themes, custom taxonomies and more.


wp taxonomy list


maintenance-mode activate

Puts your site in a maintenance mode and returns “Briefly unavailable for scheduled maintenance. Check back in a minute.” message with a 503 server response.

wp maintenance-mode activate


maintenance-mode deactivate

Takes your site out of maintenance mode.

wp maintenance-mode deactivate


maintenance-mode status

Returns maintenance mode status of your site.

wp maintenance-mode status

open mysql cli

Connects to the database set in your wp-config.php file using MySQL CLI.


wp db cli

optimize database

Runs MySQL optimizer on the connected database.


wp db optimize

regenerate thumbnails

Regenerate all thumbnail image sizes stored in the media library. The –yes flag confirms your choice.

wp media regenerate --yes


scaffold plugin

This command will generate basic files and structure for a new plugin. Use –skip-tests flag to omit php unit tests in the process.


wp scaffold plugin your-plugin-slug


scaffold theme

Generates un-styled main theme with all the necessary files and views to display content.


wp scaffold _s your-theme-slug --theme_name="Theme Name" --author="Your Name"


search string in DB

You can search for a string in connected WordPress database. The –stats flag will append details about the search like matches found and tables searched.


wp db search <string_to_find> --stats

update all plugins

Updates all installed plugins.

wp plugin update --all

update wp-cli

Update WP-CLI to the latest version.

wp cli update

wp-cli info

Prints information to the console about WP CLI and its environment such as version, OS, PHP, MySQL.

JQ – Cheatsheet

Installing jq

On Mac OS

brew install jq

Useful arguments

When running jq, the following arguments may become handy:

--versionOutput the jq version and exit with zero.
--sort-keysOutput the fields of each object with the keys in sorted order.

Basic concepts

The syntax for jq is pretty coherent:

,Filters separated by a comma will produce multiple independent outputs
?Will ignores error if the type is unexpected
[]Array construction
{}Object construction
+Concatenate or Add
Difference of sets or Substract
lengthSize of selected element
|Pipes are used to chain commands in a similar fashion than bash

Dealing with json objects

Display all keysjq 'keys'
Adds + 1 to all itemsjq 'map_values(.+1)'
Delete a keyjq 'del(.foo)'
Convert an object to arrayto_entries &#124; map([.key, .value])

Dealing with fields

Concatenate two fieldsfieldNew=.field1+' '+.field2

Dealing with json arrays

Slicing and Filtering

Alljq .[]
Firstjq '.[0]'
Rangejq '.[2:4]'
First 3jq '.[:3]'
Last 2jq '.[-2:]'
Before Lastjq '.[-2]'
Select array of int by valuejq 'map(select(. >= 2))'
Select array of objects by value** jq ‘.[] | select(.id == “second”)’**
Select by type** jq ‘.[] | numbers’ ** with type been arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars

Mapping and Transforming

Add + 1 to all itemsjq 'map(.+1)'
Delete 2 itemsjq 'del(.[1, 2])'
Concatenate arraysjq 'add'
Flatten an arrayjq 'flatten'
Create a range of numbersjq '[range(2;4)]'
Display the type of each itemjq 'map(type)'
Sort an array of basic typejq 'sort'
Sort an array of objectsjq 'sort_by(.foo)'
Group by a key – opposite to flattenjq 'group_by(.foo)'
Minimun value of an arrayjq 'min' .See also min, max, min_by(path_exp), max_by(path_exp)
Remove duplicatesjq 'unique' or jq 'unique_by(.foo)' or jq 'unique_by(length)'
Reverse an arrayjq 'reverse'

XAMPP – Setup HTTPS/SSL localhost on macOS

Original Post from here


1. Check XAMPP SSL config

Open /Applications/XAMPP/xamppfiles/etc/httpd.conf and make sure your settings are the same as below:

LoadModule socache_shmcb_module lib/httpd/modules/
LoadModule ssl_module modules/
<IfModule ssl_module>
    <IfDefine SSL>
        Include etc/extra/httpd-ssl.conf

Test SSL config with this command:

sudo /Applications/XAMPP/xamppfiles/xampp enablessl

2. Backup httpd-ssl.conf

  • Go to: /Applications/XAMPP/xamppfiles/etc/extra
  • Copy httpd-ssl.conf & paste as httpd-ssl.conf.bak

3. Edit httpd-ssl.conf

  • Open /Applications/XAMPP/xamppfiles/etc/extra/httpd-ssl.conf
  • Change default port from 8443 to 443
#Listen 8443
Listen 443
  • Find this line and remove everything below it
## SSL Virtual Host Context

Setup HTTPS/SSL localhost

Open Terminal

4. Create SSL folder to store SSL files

mkdir ssl
cd ssl

5. Create SSL CSR & private key

You can use any file name here (just replace localhost)

openssl req -new -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.csr

Enter info as below. Note: change localhost to your localhost domain name (ex:

Country Name (2 letter code) [AU]:VN
State or Province Name (full name) [Some-State]:HCM
Locality Name (eg, city) []:HCM
Organization Name (eg, company) [Internet Widgits Pty Ltd]:VN
Organizational Unit Name (eg, section) []:VN
Common Name (e.g. server FQDN or YOUR name) []:<strong>localhost</strong>
Email Address []

There are 2 more information may be asked:

  • A challenge password
  • An optional company name

Leave this information BLANK (just Enter, no need to input anything)

6. Create .ext file

touch localhost.ext

Copy & paste below content to v3.ext file

Note: change localhost to your localhost domain name

keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

DNS.1 = localhost

7. Create SSL CRT

openssl x509 -req -sha256 -extfile localhost.ext -days 3650 -in localhost.csr -signkey localhost.key -out localhost.crt

8. Add SSL CRT to macOS Keychain

  • Double click on localhost.crt on Finder
  • Select Keychain: System then click Add
XAMPP - Setup HTTPS/SSL localhost on macOS
  • Find & double click on localhost cert in Keychain Access
  • Expand Trust, select When using this certificates: Always Trust
XAMPP - Setup HTTPS/SSL localhost on macOS
  • Close the window and click Update Settings

9. Config SSL in XAMPP virtual host

Open /Applications/XAMPP/xamppfiles/etc/extra/httpd-vhosts.conf

Update your config:


<VirtualHost *:80>
	ServerName localhost
	DocumentRoot "/Applications/XAMPP/xamppfiles/htdocs"


<VirtualHost *:443>
	ServerName localhost
	DocumentRoot "/Applications/XAMPP/xamppfiles/htdocs"

	SSLEngine on
	SSLCertificateFile "/Applications/XAMPP/xamppfiles/etc/ssl/localhost.crt"
	SSLCertificateKeyFile "/Applications/XAMPP/xamppfiles/etc/ssl/localhost.key"

10. Open Chrome and access https://localhost.

WSL: Wrong Date

When checking the date in WSl, it display the wrong date

❯ date
Wed Jul 26 15:28:20 CEST 2023

So setup the correct date, you could run either

❯ sudo hwclock -s

or setup a timesync daemon (described here)

Add these lines to the /etc/wsl.conf (note you will need to run your editor with sudo privileges, e.g: sudo nano /etc/wsl.conf):


And close out of the nano editor using CTRL+O to save and CTRL+X to exit. Now close your WSL distro windows and run wsl.exe --shutdown from PowerShell, then restart your WSL instance. Upon launch you should have systemd running.

Now install systemd-timesyncd:

sudo apt install systemd-timesyncd
sudo systemctl edit systemd-timesyncd

In the second step, when editing, add the two lines beginning with [Unit], as shown below:

Now start it:

sudo systemctl start systemd-timesyncd

Check status with:

timedatectl status
timedatectl timesync-status