Technote

Development workflow Intro

Series WP-CLI automation recipes Part 2 of 8

Posts and terms from the command line: list before you change

Bulk-edit accidents almost always come from selecting the wrong set. Split selection and action into two commands and you get to see what will change before it changes.

Moving 300 posts to a different category, publishing every draft matching a condition, or cleaning up a tag takes an afternoon in the admin. On the command line it is two lines. Why it has to be two lines is the point of this part.

List before you change

wp post list accepts nearly all of WP_Query‘s arguments as flags, so most filters you can express in the admin list table work here too.

wp post list --post_type=post --post_status=draft --fields=ID,post_title,post_name
wp post list --post_type=post --category_name=seo --format=csv
wp post list --post_type=post --posts_per_page=-1 --format=ids

--fields picks the columns, --format chooses between a table, CSV, JSON or a bare list of IDs. That last one, --format=ids, is the raw material for the next step.

The rule is simple. Keep the command that selects and the command that changes separate, and run the selecting one on its own first. Only once the printed list matches the list you intended do you wrap it in something that writes.

Creating — –porcelain makes it composable

Add --porcelain when creating and you get just the new ID instead of a friendly success message, which means it feeds straight into the next command.

ID=$(wp post create --post_type=page --post_title='Pricing' --post_name=pricing --post_status=draft --porcelain)
wp post meta update $ID _wper_layout wide
wp post term set $ID category performance

For anything longer than a sentence, do not cram the body into a flag — read it from a file. wp post create ./body.html --post_title='Pricing' takes the first positional argument as the content file, which is the easiest escape from shell quoting purgatory.

Terms and meta

Terms follow the same shape: see what exists, then attach.

wp term list category --fields=term_id,slug,name,count
wp term create wper_role developer --slug=developer
wp post term add 123 wper_level practical
wp post meta list 123

term set and term add are not interchangeable. set replaces every existing term in that taxonomy; add appends. Use set where the rule is one term per post, and add where terms accumulate. Swap them by accident and your taxonomy quietly flattens.

If a meta value needs to be an array or an object, use --format=json. Never hand-write a serialised string — the next part is about exactly that serialisation coming apart.

Bulk edits without casualties

Once the selection is confirmed, the write is short. Put the list command inside it verbatim.

wp post update $(wp post list --post_type=post --post_status=draft --category_name=seo --format=ids) --post_status=publish

A few habits keep this safe.

Before a bulk edit — the top four rule out almost every irreversible accident

wp post delete moves items to the trash by default and deletes permanently with --force. Permanent is permanent. Getting into the habit of running wp db export before any mass deletion costs seconds, and there is no substitute for it on the day you need it.

How to structure content so this kind of work stays easy is covered in the development workflow archive, and if you would rather hand the restructuring and upgrade over as one job, see our optimization program.

Next part

Next up: changing a domain. It looks like a one-line SQL job, and that is precisely where settings quietly disappear. The reason is serialisation.

More on this topic

All technotes

Development workflow Practical

Turning taste arguments into rule checks

"It feels a bit cramped" can be neither argued with nor fixed. Spacing off the scale, colour off the palette, contrast below threshold, missing states — four rules…

Designers 9 min read

Development workflow Practical

Do not swap everything at once

A full swap makes every problem appear at the same moment — which means none of them can be attributed. So you switch one template at a time.

Designers 6 min read

Development workflow Practical

Adding an SCSS build, and whether to commit the output

WordPress themes are expected to deploy without a build step, which leads to the opposite conclusion from ordinary application code — and to its own costs.

Developers 7 min read

₩270,000 · Join the program