Quoting: Men at Arms (Discworld, #15; City Watch #2)

“The reason that the rich were so rich, Vimes reasoned, was because they managed to spend less money.

Take boots, for example. He earned thirty-eight dollars a month plus allowances. A really good pair of leather boots cost fifty dollars. But an affordable pair of boots, which were sort of OK for a season or two and then leaked like hell when the cardboard gave out, cost about ten dollars. Those were the kind of boots Vimes always bought, and wore until the soles were so thin that he could tell where he was in Ankh-Morpork on a foggy night by the feel of the cobbles.

But the thing was that good boots lasted for years and years. A man who could afford fifty dollars had a pair of boots thatā€™d still be keeping his feet dry in ten yearsā€™ time, while the poor man who could only afford cheap boots would have spent a hundred dollars on boots in the same time and would still have wet feet.

This was the Captain Samuel Vimes ā€˜Bootsā€™ theory of socioeconomic unfairness.”

I had the need to change the status on several hundred wordpress posts by a particular author, from “publish” to “pending” (more on this in a future post). This would have taken me hours to do through the frontend, so I figured I’d make my first serious use of WP-CLI, and script the job.

You can list posts using WP-CLI, and specify which columns to display, and even pass in basic filters, like so wp post list --<column>=value --fields=ID,post_title,post_status,post_author. You can also update posts. By combining these with some shell scripting, big jobs can be done fairly easily.

Easily. Oh, the hubris. The problem I ran into was:

  • The display column names are the names of the columns in the database, so to list the post author, you would refer to it as post_author.
  • The filter column names are as they are referred to in WP_Query, not how they are named in the database.

I didn’t catch on to this distinction at first, and the number of rows I was returning was large enough it couldn’t display all of them in the terminal. Yes, I should have used less to check. I should have done a lot of things, like take a backup first (wp db export ~/export.sql), but that wouldn’t be as good a cautionary tale.

Long story short, I ran wp post list --post_author=3 --fields=ID,post_title,post_status,post_author, saw only the results I expected because some rows were cut-off. When I fed this into a loop which would update the post_status, I ended up setting every post as pending.

wp post list --post_author=3 --format=ids \
| xargs -d ' ' -I % wp post update % --post_status=pending

The correct command should have been

wp post list --author=3 --format=ids \
| xargs -d ' ' -I % wp post update % --post_status=pending

Thankfully, having realised my mistake, I could make use of WP-CLI to fix it:

wp post list --author=2 --format=ids \
| xargs -d ' ' -I % wp post update % --post_status=publish

For everyone following along at home, my mistakes so-far were:

  • Not reading the documentation fully
  • Not taking a backup before altering a live site
  • Not double-checking my test results before running the command “for real”

I’ve returned all of the wrongly-pended posts to “publish” status. I do still have an issue with Post-Kinds data being missing on most of these posts; I think this is due to some wierd interaction between WP-CLI and the plugin, but I can’t be sure. These posts (~60) I’m going to have to fix by hand — I consider it a reprimand for my earlier flippant approach!

Cross-posted to /en/wordpress.

I’ve been chipping away at K as time allows over the last week. It’s still a long way from where I’d like it to be, but it’s getting there…

  • All theme files should be compliant with the WordPress Coding Standards, apart from a few instances where I’m planning to rewrite what’s there.
  • I’ve made little tweaks here and there to the markup output by the theme, and plan to revisit this continually. I made a test post to indieweb.xyz, but it didn’t quite parse correctly last time. This post should also be submitted – fingers crossed it goes better this time! I’m also curious if IndieNews posting will be more successful.
  • Files have been refactored (albeit not yet fully reorganised), with a goal of splitting up what was a growing, monolithic functions.php into smaller logical chunks.
  • I’m wrestling with how to handle all of the different kinds of posts the theme will support, from a markup and display point of view. My biggest headache at the moment is the treatment of post titles. I might write another post on this topic.
  • I’ve been working on making plug-in support more optional than I had it at the outset. I make heavy use of Post Kinds and other IndieWeb plug-ins, but don’t want the theme to necessarily rely on them.
  • Oh, and the source code is now available on GitHub, in the spirit of “selfdogfooding“. I came to the realisation there wasn’t anything to be gained by holding the code back, and I even ran the risk of never releasing anything if I waited until it was “ready.”

I’m learning quite a bit through this exercise, which is great. It’s reinvigorated some of my love of code tinkering; I’m finding that some evenings I’m more keen to sit down at a keyboard than I am to sit at my hobby station, which is something that’s not happened in a long time!

Update 09:26 – IndieNews submission is still failing, unfortunately. Indieweb.xyz seems to be working, but I had to force a Webmention.

Just had one of the back garden fence panels implode under the high winds, and several others looking like they might go too. Just the thing I needed first thing in the New Year.