Category Archives: WordPress Bits

Notes: Renaming and relocating directories in WordPress

This is not a guide (yet?). These are just notes for personal reference which may be expanded upon later.

Site owners/developers/administrators may find useful hints below, but please do not get mad at me if you break your site.

Methods were initially tested on a multisite-with-subdirectories installation, but are generally applicable to single and subdomain installations as well.

standard installation

familiar structure, e.g.

├── wp-config.php
└── wp-content/
    └── plugins/

nginx (subdirectory multisite)

if (!-e $request_filename) {
    rewrite ^(/[^/]+)?(/wp-.*)   $2                   last;
    rewrite ^(/[^/]+)?(/.*\.php) $2                   last;


WP CLI: --skip-plugins

A few notes on skipping plugins with wp-cli.

Suppose you want to skip all except one, DONTSKIP:

wp user list --skip-plugins=$(wp plugin list --field=name | grep -v ^DONTSKIP$ | tr  '\n' ',')

If this will be repeated, you’d benefit from saving the ‘skip-list’ to a text file instead of running the nested command each time. This also allows you to update the skip-list relatively easily, if you don’t mind tighly squeezed comma-separated lists.

wp plugin list --field=name | grep -v ^DONTSKIP$ | tr  '\n' ',' > skipplugins.txt
wp user list --skip-plugins=`cat skipplugins.txt`

If it’s a permanent skip-list, save the keystrokes and processes by putting it in a config file (different options depending on how global you want that change:

 - skip-me
 - skip-me-too

isset() Assumptions

register_setting() can be really handy, but take note! The first time your option gets saved, it’ll pass through the santize callback twice. With most input, it won’t matter; and if you’re explicit, it won’t matter either. But under the right conditions, it will.

Suppose your register_setting() looks like this:

register_setting( $option_group, 'checkbox', 'sanitize' );

And you have a pair of checkboxes like this:

<input type="checkbox" name="checkbox[one]" value="1" />
<input type="checkbox" name="checkbox[two]" value="1" />

And finally, your sanitize callback looks like this

function sanitize( $input ) {
	$input['one'] = isset( $input[ 'one' ] ) ? true : false;
	$input['two'] = isset( $input[ 'two' ] ) ? true : false;
	return $input;

See the problem?

On the very first save, both $input['one'] and $input['two'] will be true, no matter what. Say checkbox one is unchecked, when it fist passes through, $input['one'] is set to false – as expected. But when the input is passed through sanitize the second time, $input['one'] is set (to false) and thus the $input['one'] is changed to true.


So the moral of the story is: be more explicit, don’t make assumptions.

Fun with WP-CLI

A random collection of things you perhaps didn’t know you could do with WP-CLI.

Maybe you’ve imported an image before, but did you know you can import a whole directory just as easily? For example, if the directory is named ‘images’:

wp media import images/*

Sometimes you need to run a command based on a result set from another command. In many cases, you can do that by nesting the one in the other. For example, if you want to change the password for all users with the ‘author’ role.

wp user update $(wp user list --role=author --field=ID) --user_pass=password

Or go crazy and regenerate media for the featured image of all sticky posts.

wp media regenerate $(wp eval 'foreach( wp_parse_id_list( get_option("sticky_posts") ) as $id ) { echo get_post_thumbnail_id($id). " "; }')

Trying to run a command for each site in a multisite doesn’t have to be a chore. A little bash script can speed things along.


for url in $(wp site list --field=url)
	wp theme activate twentyfourteen --url=$url

Save that to a file, and run with bash: bash filename

You can do that in a one-liner as well, but that can make it harder to see what you’re doing, especially with more comprehensive commands.

for url in $(wp site list --field=url); do wp theme activate twentyfourteen --url=$url; done

Function: wp_list_pluck()

Suppose you want to get some information about some posts in this format: an array of post titles, keyed by the post ID. How would you do it? Spoiler alert: Skip the first 2 options

Let’s assume you’re fetching some posts via get_posts(). For simplicity I won’t be passing an arguments to that function, but go ahead if you want to 🙂

$posts = get_posts();

Option 1

$post_titles = array();

foreach( $posts as $p ) {
	$post_titles[ $p->ID] = $p->post_title;

Not bad, but surely there’s a WordPress-y way to do that.

Option 2

You might have come across the function wp_list_pluck() which is really neat for pulling a particular value by key from an array of arrays or objects.

$post_titles = wp_list_pluck( $posts, 'post_title' );

This works for getting the titles, but leaves us without the IDs as keys. You might extrapolate that to this

$post_titles = array_combine( wp_list_pluck( $posts, 'ID' ), wp_list_pluck( $posts, 'post_title' ) );

Now we have what we want, but that seems clunky.

Option 3 (the best!)

Since WordPress 4.0, wp_list_pluck() takes a third argument that makes it behave more like the native PHP function (since 5.5) array_column(). This third argument allows you to specify a key whose value should be used as the key of the returned array.

$post_titles = wp_list_pluck( $posts, 'post_title', 'ID' );

How to Become A Better Developer

I was on a panel at WordCamp Seattle this last weekend on becoming a better developer. One point I repeated a few times was “read core” and a related point of “don’t rely on tutorials.”

These ideas have been circling in my head since then, so I wanted to write them down.

Are Tutorials a Problem?

Tutorials can be great for providing context for code, but they often leave the reader without the tools to work out of that context. They may come away with working code, and even be able to reuse it over and over, but often without knowing what it is they’re doing. This happened to me.

It seems to me that a lot of tutorials fall into one of three categories:

  1. Installers: This is probably what irks me most. There will be a headline that looks like “How to foo bar” and the first step is “Download the Foo Bar plugin” and proceed to explain how to set up a plugin. These tutorials may be perfectly fine for helping a user solve a problem, but the title is very misleading.
  2. Copy-Pasta: These often just describe a problem and offer a snippet as a solution but with little-to-no explanation.
  3. Over-Simplified: These are tricky. The tutorial is often really trying to teach and does so understandably by simplifying the code to the bare-bones. But they are incomplete because they skip the ‘shoulds’ (like sanitization, and security) because they’re not ‘have tos’ so that users will end up with code that technically works but with no idea that there should be more.

I’m not sure there’s hope for the Installers. Those authors should just be more careful about picking titles. Or I should be better about detecting linkbait.

As for the other two, I won’t pretend I’ve never done those. I’m also not suggesting that they have no use, but I think there’s room for improvement.

Copy-Pasta is a great way to end up with conflicting function names, a bloated functions.php file, and/or unintended side-effects.

To me, the over-simplified ones are the most dangerous because the user doesn’t know what they’re missing. It’s like teaching someone to build a car, but never getting around to the seatbelts and windshield – they’ll get in and drive on the highway and be fine till they’re not.

Go To the Source (Code)

If you want to learn how a function really works, you’ll have to look at the source. Tutorials can provide examples of how to use a function or hook, but you’re often on your own to learn how/if you can repurpose or reuse it in a different context.

I’ve faced this personally more than once, and wrote about it.

WordPress core is neither magic nor mystery (though it can feel like it at times!). It’s full of awesome gems that you may never learn about unless you dig in.

Where do you start? Try the Code Reference and look up functions that you see in tutorials. Personally, I spend a lot of time in my xref or just straight up opening core files in my text editor.

Turn That Snippet Into A Plugin

This post is sort of a recap of a talk I gave a couple years ago.

Whenever you get a WordPress code snippet, where do you put it? It’s not uncommon all those bits of code to end up cluttering up the functions.php file of your theme, whether out of habit or suggested by tutorials.

But wouldn’t it be better if all those non-theme snippets were plugins instead? Yes!

As plugins, you can switch/upgrade themes without losing that functionality and toggle the funtionality without editing the theme.

And great news! It’s really easy to turn a snippet into a plugin.

Nginx, robots.txt, and Copy-Pasta

Did you know that if you don’t have an actual robots.txt file, WordPress will create a virtual one for you? For example, I have not created a robots file for, yet you can see one at

So either you have created your own file, or you’re relying on the virtual one. Unless you’ve explicitly disabled WordPress virtual robots.txt file, you’ll have something at

However, if you (1) use nginx, and if you (2) followed certain popular guidelines* for configuring your site, and if you (2) are relying on the virtual file, you might discover that you get a 404 if you try to view your robots file.