Hiding Posts in WordPress with a Custom Post Status

Are you looking for a way to hide WordPress posts from both the frontend and the backend?

By default, WordPress displays all post statuses on the backend post list admin screen.  To specifically tell it to exclude a post status, you’ll want to register the post status with the following arguments:

function themeprefix_register_inactive_post_status() {
         'label' => 'Inactive',
         'public' => false,
         'internal' => true,
         'protected' => true,
         'private' => false,
         'exclude_from_search' => true,
         'publicly_queryable' => false,
         'show_in_admin_all_list' => false,

add_action( 'init', 'themeprefix_register_inactive_post_status' );

I recommend prefixing the post status to avoid potential conflicts — just incase WordPress or a plugin decides to register an inactive post status themselves.

One unintuitive thing is that “private” actually needs to be set to “false” as shown above.

So why would you do this?

In most cases, I’d recommend differentiating types of posts by using a different post type instead of a different post status.

However, in my case, I wanted a way to “soft delete” posts without moving them to the trash.  See, the trash auto-empties after 30 days, and if you move all of the posts to the trash at once, then in 30 days, all of them will be deleted at once, and this could cause some performance issues if you’re dealing with thousands of posts.

So instead I made an inactive post status, and wrote a WP CLI script to set this post status on the content I planned on deleting.  This way I could restore the content if needed, so it’s truly a “soft delete”.  Then, when I want to permanently delete it, I’ll write another custom WP CLI script that permanently deletes them.  This script will sleep at set intervals and also will take other measures to make sure that we don’t cause performance issues!


Setting up PhpStorm, Xdebug to work with WordPress PHPUnit Testing

I’m a huge fan of using Xdebug and recently I ran into some issues with writing PHPUnit tests for my WordPress theme.  It took me longer to debug than usual because I couldn’t get PhpStorm to stop at my debug breakpoint.  Actually, I couldn’t get Xdebug to work at all — if I had Xdebug enabled, PHPUnit wouldn’t even run — it would just hang.

I tracked the issue down to this line in tests/bootstrap.php

system( WP_PHP_BINARY . ' ' . escapeshellarg( dirname( __FILE__ ) . '/install.php' ) . ' ' . escapeshellarg( $config_file_path ) . ' ' . $multisite );

A Google search brought me to this closed WP Core trac ticket.

That ticket has a helpful suggestion, which I hope to immortalize here, as it is the solution to this problem.

Max. Simultaneous Connections Setting

The solution is to change the Max. simultaneous connections setting, which can be found in Default preferences -> Languages and Frameworks -> PHP -> Debug.

Increase the phpStorm max connections setting to get xdebug to work.

“Configure Php Include Paths”

The default setting is 1, change it to 3 or more!


If that doesn’t solve your problem instantly, then I shall ask, did you Configure php include paths so that the phpunit files are included?  Also, depending on your development environment, you may need to set up path mappings so that PhpStorm knows how the server files are mapped to your local ones.

Happy testing!

Debugging WordPress with PhpStorm’s Console Window and xDebug

As a backend WordPress developer, I use PhpStorm to help me develop and debug.  If you’re not familiar with it, PhpStorm is an IDE, so it combines all of the things that I need to do as a programmer into one interface — think code editor plus a debugging interface, git integration, terminal window, etc.

I have fond memories of discovering PhpStorm.   I developed many of my basic programming skills while working in Java.  I used the Eclipse IDE for Java and when I switched to Php, I searched for something equally helpful.  I found PhpStorm.

It turned what I saw as a confusing mess of php files into something I could explore, understand, and build upon.

And yet, the amount of tools available in PhpStorm can be intimidating.  So, unfortunately, I’ve spent the last few years completely ignoring the Console window.  My mistake!

First, this assumes that you’ve got xdebug enabled and configured within PhpStorm properly.  I’ll admit that it can take several hours to get xdebug set up, especially if you’re unfamiliar with how it all works and don’t have a coworker to walk you through it.  But those several hours of persistence will pay off handsomely.

When tackling an issue, I often set a debug point before the code I’m about to examine or change, and then a debug point afterwards.

This way I can step through my code, inspect the variables, and double-check that it’s doing exactly what I want it to be doing.  I find that’s a good way to really understand the code, which is critical to changing the code correctly and not creating new bugs.  Writing unit tests is even a better idea than just inspecting variable values, but not all situations lend themselves to that.

So I usually double-check my work by inspecting variable values.

In PhpStorm, if you have the debug window open, you should see a “Console” tab at the top of that.  If you switch to that, you’ll see a command prompt, at which we can run code within the context of our program.  So when the program stops at the breakpoint, you can switch to the console window and start typing commands.  Let’s try a few.

How did we get here?  Use wp_debug_backtrace_summary()

wp_debug_backtrace_summary will print a comma-separated list of the functions that have been called to get the the current code point.

Here’s a screenshot of me debugging a filter called by Jetpack.  If you’ve ever wondered about the context of when a filter or action is being called, this is a helpful function.  As you can see in my screenshot, wp_debug_backtrace_summary reveals that wp_head was called, so I’m in code that’s running within the head of the website.

This is also helpful when debugging and you’ve realized that you’ve set your breakpoint too late in the execution.  You can look at the list of functions already called and set your breakpoint in one of those.

What are we working with? Use get_post() or get_term()

Is your code trying to manipulate a post object?  Are you trying to change something on a save_post hook?  There’s lots of scenarios where you may be wondering why some code isn’t working.  A common issue is that we’re trying to do something at the wrong time in WordPress execution.  An example would be trying to use some post meta before it’s been saved.

If you’re working with a term object, you can use get_term() to inspect the term object as well.

In the above screenshot, the code execution has stopped at my breakpoint (line that ends in 27 above).  PhpStorm has highlighted the line that I’m on.  I blurred out the function name for privacy, but that’s where I am.  It’s about to call that function and it will pass it the $id, which is 36459.  I know that’s a post ID, and it would be super helpful to know what kind of post it is here, so I ran a get_post() command, which returns the WP_Post object. In this case it’s a guest-author post.

So, an awesome debugging process is to get the data from the database and display it, to make sure it’s what we expect.

Did you write a new function?  Try it out with different parameters.

After writing a new function, we have to check if it works correctly.  The best way to check this would be unit testing, and the most time consuming way would be to reload the web page or multiple pages to check that it gives the expected result. Reloading pages is super time consuming and can be an inaccurate way to measure one function’s correctness.

A quick way is to manually run the function with different inputs, and check the output in the console window.  Here’s an example of me doing that — as you can see, the function here can return a DateTime object or a Unix timestamp, depending on the input.  This is good demo of using this console in an interactive way.


What else is awesome to try in the console?

Do you use the console and have any helpful tips?

It’s also a handy place to just evaluate code to check its correctness.  Next time you’re doing code review and aren’t sure if a WordPress function is being called correctly, pop it into the console.


How to Solve Software Bugs with Wrappers

I’ve taken an interest in improving legacy software.  I use the term legacy broadly here, to refer to software that does something in an outdated way.

It is possible to spend many hours and days trying to figure out WHY a bug occurs.  Lately, I’ve decided that the fine detail of why the bug occurs doesn’t matter in some cases.  That’s right, it doesn’t matter.

All you need is a deep understanding of the problem.

If the problem is that the data going into a function is good but the data coming out of that function is bad, then you can simply replace that function with your own function.

You just have to make sure that you perform all of the necessary actions of that function, so that you don’t mess up any other aspects of the program by accident.  THAT is the tricky part!

Or, your wrapper can just do the really important buggy part of that function and then you might call the original function afterwards, so that your bug fix only adds something extra.  Performing careful code changes in a complex system can be similar to surgery.  You don’t want to excise too much, as that could cause other, new bugs.

When should you use a wrapper?

  1. When you can’t change the buggy code because it’s outside of code that you control.  For example, the bug may be in the framework, NPM package, WordPress core or third-party plugin, other library or dependency, or, operating system, browser, etc.
  2. When it would take too much development time to rewrite the code in question.  Everyone loves a quick fix.

I love elegant software design, but at the same time I’m happy to have a fix that works any day of the week.

If you’re interested in learning more about software design, you may enjoy Head First Design Patterns.

Happy coding!

Firefox Reader View Showing Wrong Author [Bug Fix]

Screenshot of Firefox Reader View Button

Firefox Reader View is a really neat way to consume content on the web — on compatible websites, it extracts the title, author, and main content from the site, and only displays that — leaving out those annoying ads and just about everything else.

Unfortunately, Firefox Reader View doesn’t have good (any?) developer docs, so finding answers to common issues just wasn’t happening for me.  Usually Stack Overflow has the answer — and I did find this helpful answer that explains how Firefox Reader View works, but it didn’t really fix my issue.

The Problem: Incorrect Authors

The Solution: Include an Author Meta tag on your page that looks like this:

<meta name="author" content="John Doe">

For example ^

If you’re using WordPress, you can generate this dynamically as part of your theme code.  It might look something like this:

if ( is_single() ) : ?>
     <meta name="author" content="<?php the_author(); ?>">
<?php endif;

If you’re using the popular CoAuthors Plus plugin for managing multiple authors, you can use the coauthors template function for outputting the author names.

Hope this helps!  This optimization may also help with SEO.  By the way, it looks like when there is no author meta tag, the Firefox Reader View javascript parses the content and looks for an html element with an ‘authors’ class — which in my case, was the direct cause of the incorrect authors showing.

Got any comments on Firefox Reader View or the Author meta tag?  Chime in below.

Use Twilio to Programmatically Text Yourself!

Twilio SMS Text Alerts
Screenshot from my Android phone of the SMS Text Messages I sent myself from Twilio (full URLs are redacted)

built a little program that checks book prices and alerts me if the price is low enough.  Recently, I integrated Twilio with it, so that I receive an SMS alert when my program finds a match.  This was surprisingly easy to do.

I’m a PHP wizard, so I wrote it in PHP, and here’s the code to do it.  That’s a github gist, and I had to alter it a bit as not to reveal any top secret code, so you’ll have to finish it a bit to meet your goals, but it should give you a good idea.  It’s fun to implement, because all you have to do is something like this:

$twilio_gateway = new Twilio_Gateway();
$twilio_gateway->text_me( 'This is an alert!' );

I love when code reads like that. So easy to understand what’s going on!

If you’ve never heard of Twilio, you should check them out.  They have APIs for incorporating text messaging, video and voice into your app.  Their developer docs are super easy to follow and they offer a free trial account!  I’m still unsure of how many text messages you get to use with a free trial account, but it’s way more than a handful.

If you’re on their trial account, text messages will include a notice that they were sent from a trial account.  You also can only send messages to phone numbers that you have verified.  That said, if you want to send alerts to yourself for free, Twilio makes that possible.  And if you decide to upgrade to a paid account, it seems that the cost is still going to be pretty cheap for personal use.  I first heard of Twilio while listening to a Software Engineering Daily podcast, and the ad said it was something like a penny a message.  You do have to buy a phone number to send the messages from, but that’s also super cheap.

SMS is a great option for sending alerts, because modern smartphones allow you to designate different notification sounds for each number, so I have a unique sound for when it’s an alert from my program.  The trick is to make sure that the alert only comes in when it’s actually important, as when alerts happen too often, the human brain tends to tune them out.  So the next step is optimizing my program to get better at figuring out when something really is a deal!

Debugging PhpStorm with xDebug on Ubuntu – Solving Common Set-up Problems

Do you love programming in PHP?  If you don’t, could it be your editor/IDE?

As a programmer, the tools you use, and how well you use them, can have a huge impact on your productivity.

How much time have you wasted writing var_dump statements and printing log messages?

What if you could just inspect the contents of a variable whenever you wanted?

That’s what debugging allows you to do, and that’s what I do every day.

Not sure what the array keys are?  Inspect the variable.  Not sure of the object’s properties?  Inspect the variable.  Not sure if a function is running?  Stick a breakpoint on its first line, and see if your program stops execution at that point.

Debugging saves time… But setting up debugging can also take some time, as it requires the installation of xdebug and the correct configuration set-up.  Plus, if you’re using a virtual machine like a vagrant box, you’ll need to set up path mappings.

PhpStorm Has Built-in Debugging for xdebug

See that screenshot?  If you’re trying to get xdebug to work with phpstorm, and you’ve already installed xdebug, then you should go to: Run –> Web Server Debug Validation (For PhpStorm version 2016.3.2, it’s the last option in that Run dropdown menu.)

When that validation box first opens, you’ll probably see an error message.  Click on “validate” and it might work right out of the box. If not, check that the path is set to a location that the web server can serve up. If you already have a project, this can just be the directory to the project.  (By default, Apache only serves up files from within a specific directory, and as programmers we usually put our web apps inside that directory, because then we can view them with a web browser.)

Settings for Ubuntu 16.04 with Apache and PHP 7

If you’re running Ubuntu with Apache and PHP locally, make sure that “Local Web Server or Shared Folder” is selected, and enter the following:

Path to create validation script: /var/www/html/

URL to validation script:

Click Validate….. and PhpStorm will tell you what’s wrong!!

In this case, it was easy.  I just had to add xdebug.remote_enable=1 to my php.ini file

And then I just had to restart Apache:

systemctl restart apache2

Hope that was helpful!


Goodbye Windows, Hello Ubuntu

Quite some time ago, I installed Ubuntu on my computer alongside my Windows 7 installation.  I had an extra solid state hard drive (they’re cheap these days) and followed the instructions for setting up dual-boot.  I played with Ubuntu a bit, was disappointed that I couldn’t do some things on it, and soon resumed booting into Windows.

More recently, I started using a MacBook Pro for work, and as you may know, it has a bash kernel, and so the commands are similar to the ones you’d write on any linux based machine.  I also started using Ubuntu on a vagrant box (virtual machine).  So linux began popping up all throughout my programming work.  I still had a Windows computer, and often returned to it after work, but I always found myself getting annoyed at it.  And also typing ls instead of dir

Little annoyances pile up.  The last straw was that Windows updates began to fail and Windows started filling up my hard drive with temp files.

Windows became no longer worth it to me.  So I booted into Ubuntu, upgraded to Ubuntu 16.04 LTS, and got everything working… well, almost everything… I’ve still got some things that appear to be incompatible with Ubuntu out-of-the-box, but I thought I’d share here my successes:

Audiophile Sound Equipment Works — Yay!

One of the things I like to do on my computer is listen to music.   It is surprising the number of times that I’ve made a software or hardware upgrade only to have my sound equipment not work.  So often, something I change introduces faint beeping noise, static noise, electrical interference sounds, buffering issues, etc… So many things can go wrong and all I want to do is listen to lossless music files with 20 tabs of chrome open!

I’ve used various sound cards in the past, but my current set up is USB out of the computer and into my Teac UDH01 DAC.  I did some googling but was unable to find out for certain whether this was compatible with Ubuntu, since on Windows it requires specific drivers.  (The Teac also had optical and coaxial inputs, which are good alternatives if you have any issues with the USB driver, but not all motherboards have those outputs.)

It did take me a couple of hours to figure out how to get the computer to output 192 kHz.  The Teac UDH01 displays the sampling rate on the front of it.  There is a huge difference in how a 48 kHz sampling rate sounds versus 192 kHz.  At the lower rate, lots of data is omitted, and this makes the music sound flat because you’re missing the small sounds that help give you room acoustics.

How to get the Teac UDH01 to work with Ubuntu 16.04

  1. Hook it up.
  2. Install Audacious Media Player.  You can do this at the command line with:
    apt-get install audacious
  3. Open up Audacious and go to File –> Settings –> Audio and set the output plugin to PluseAudio Output and set the bit depth to 32. (See below screenshot.)
  4. Edit the configuration file for pulseaudio server according to these instructions.  Basically, you’ll want to edit the file at /etc/pulse/daemon.conf by uncommenting and changing the default-sample-format and default-sample-rate.
  5. Restart pulseaudio with pulseaudio -k (or just restart your computer)

Audacious Settings on Ubuntu for Teac UD-H01

Got my Touchpad Working (Sort of)

Ubuntu is definitely getting better at supporting more things out of the box.  I have a Logitech T650 Touchpad and it does work out of the box with Ubuntu, although it’s a little glitchy, unfortunately.   I find that I sometimes accidentally initiate “drag and drop” or right click when I’m trying to scroll.  I’m not sure what’s the cause of this bugginess… Hopefully some smart programmer will figure that out!

I’ve found that efficient use of computers involves a lot of muscle memory, so I try to have both of my computers set up as similarly as possible.  Having to switch between the command key and the ctrl key is super annoying.  One thing I have been able to set up exactly the same on all of my computers is the direction that you move your fingers for scrolling down a page.  If you don’t like the direction, check out the settings.  I was able to get all of my touchpads to scroll in the same direction by turning off “natural scrolling.”

Got My PHP Programming Environment Set up!

One of the geeky things I do on Ubuntu is run my own personal server for developing web apps.  It was relatively simple to install Apache, Php 7, & MySQL.  Also, installing PhpStorm, my favorite IDE, was a breeze, but getting the debugging to work correctly was a little challenging.  If you run into problems, check out my blog post about how to debug xdebug configuration with PhpStorm.

On Windows 7, I was using WAMP and then later XAMP to run the alternative to the LAMP stack.  It worked, but running it all on Ubuntu works way better.  On Windows, it took a long time after starting Apache before it actually worked — some stupid bugginess.  On Ubuntu, it just all works, instantly.  And this is all on the same hardware. So my initial impression is that Ubuntu is faster than Windows, and not only for this kind of devy stuff.  Switching between music albums on Ubuntu is also near instantaneous.  While Windows is busy doing what Windows wants to do, Ubuntu is busy doing what I want it to.  And that’s why I’m happy to say good-bye to Windows…

Got my Brother HL-5340D Laser Black & White Printer Working with Ubuntu

You most likely don’t care, because my Brother printer is probably an older model than yours, but I just wanted to give props to the developers at Brother for writing a script and precise installation instructions that literally got my printer working on Ubuntu in under 5 minutes!  It even printed a neat test page at the end of the set up.  Woohoo!  I’ll continue to recommend Brother… The toner is cheaper than most competitors too (& Costco sells it).


I’m not actually anti-Windows.  I recommend Windows to my parents, since it’s more affordable than Mac, and widely compatible with all kinds of software.  I also can’t understand why Mac would introduce a touch bar instead of a touch screen for their MacBook Pros, because touching the screen is becoming the norm.  It’s the natural choice for human-computer interaction.  I’d even say that it’s a better choice than voice in most cases, but that’s something I’m interested in seeing what the future brings.  Interesting times we live in…

WordPress get_the_terms by term order [bug fix]

WordPress 4.7 introduced a change to the default term order for get_the_terms()

In earlier versions of WordPress, get_the_terms( $post_id, $taxonomy_name) returned the terms in the same order in which the terms were added to the post.  But, starting with WordPress 4.7, the terms are being returned in alphabetical order by term slug.  (Note:  This is for non-hierarchical terms.  I’m not sure if this is true for hierarchical  terms.)

As you may know, get_the_terms is a convenient function for getting the terms for a specific post ID.  It is used by many plugins, and can be used for built in taxonomies like categories and post_tag or for custom taxonomies.

get_the_terms is a cached function, meaning that WordPress caches the results, so that if it’s called repeatedly, it doesn’t have to do a database query each time.  So it’s a good function to use for performance reasons.  It’s unlikely to slow your site down.  However, it doesn’t accept an orderby argument to specify how to order the results.

So, there are 3 ways to fix this problem.

Option #1: get_terms_orderby Filter

You can add a filter on get_terms_orderby

This filter allows you to alter the $orderby part of the SQL query that WordPress uses to get the terms from the database.

Assuming that author is the name of your custom taxonomy, you can use this function:

function wpcf_author_filter_terms_order( $orderby, $query_vars, $taxonomies ) {
    if ( ! empty( $query_vars['object_ids'] )
        && ! empty( $taxonomies[0] )
        && ( 1 === count( $taxonomies ) )
        && 'author' === $taxonomies[0] )
            $orderby = 'tr.term_order';
    return $orderby;

add_filter( 'get_terms_orderby', 'wpcf_author_filter_terms_order', 10, 3 );

By the way, the above code will fix this Co-Authors Plus plugin ordering issue. The Co-Authors Plus plugin creates a taxonomy named author and uses get_the_terms. This is actually where I first saw this bug, but since it is a result of a WordPress core change, I’m sure that there are many other WordPress themes and plugins in the wild with this same issue.

Keep reading if you’re curious, as this is a solution, but not the only solution.

Option #2: use wp_get_post_terms()

Alternatively, you can simply not use get_the_terms() but instead use wp_get_post_terms() which accepts a list of overrides, which means that you can specify the orderby in the third parameter.

For example,

Instead of this:

$terms = get_the_terms( $post_id, $taxonomy );

Write this:

$terms = wp_get_post_terms( $post_id, $taxonomy, array( 'orderby' => 'term_order' ) );

The reason I prefer option #1, even though it’s more complicated, is that wp_get_post_terms is an uncached function.  On a low traffic site that’s using full page caching, it may make no difference.  But if you have a site with a lot of logged in users where caching isn’t happening, I’d recommend using a more performant method.

Option #3: use wp_get_object_terms

Similar to option #2, with the same warning about it being an uncached function.

I’m running out of steam to elaborate, and I think that the codex entry on wp_get_object_terms does a pretty good just of explaining how to use this function.

Just remember my warning about no caching.  If you’d like to see how to implement some DIY caching, here’s an example I wrote.  Adding your own caching is something you can do anywhere you want in theme and plugin development.  It’s not really hard to do once you figure out the pattern.  The tricky part is to remember to delete the transients when needed — for this case, you’ll want to delete them on save_post and delete_post, which you can see how to do in my example.  If you don’t want to worry about when to delete them, you could just create short transients — like one minute or fifteen minute ones.  Having the query run every minute is way better than having it run for every page load, which could be many times per second.   For more info, check out the WordPress Transients API.  It goes into quite some detail about how to use them for caching data.

WordPress has_post_thumbnail() not working – How to fix the phantom featured image issue

I’ve spent another week working on programming custom WordPress themes, and I’d like to share a fix for the “phantom image bug.”  I just made that up.  It’s not a real WordPress core bug. But it is a real life programming problem that you might encounter, especially if you’re working with migrated content, or for some reason your database has weirdness.  (Funky database, eh?)

The typical way to check for whether a WordPress post has a featured image is to use the function has_post_thumbnail()  This function calls get_post_thumbnail_id(), which queries the database for the post meta field _thumbnail_id

If the field _thumbnail_id is not empty, has_post_thumbnail() will return true.

has_post_thumbnail() does not actually check to see whether _thumbnail_id is an actual ID of an object that exists in your database.  So, on the rare occasion, has_post_thumbnail() will return true when the post thumbnail does not actually exist.

Assuming that you’re in The Loop, you can fix this problem, by replacing:

if ( has_post_thumbnail() ) {

     // do a bunch of stuff



$featured_image_url = wp_get_attachment_url( get_post_thumbnail_id( get_the_ID() ) );

if  ( ! empty( $featured_image_url ) ) {

     // do a bunch of stuff


This checks to see if the actual image URL exists. In my particular case, this solved the problem.  There’s still the chance that the URL points to a file that doesn’t exist.  If that’s the issue, then this fix won’t work, and you have bigger problems.  But in that case, you’re probably seeing a broken image icon, rather than just a blank spot.

Fortunate for me, this fixed the issue with has_post_thumbnail coming back erroneously true.  Since it was returning true, an empty HTML <DIV></DIV> was being output, which was causing issues with the website’s layout.  Actually, in my case, there was also a caption appearing because there was logic written into the template that said to display a custom caption.  So it was extra ugly.

Hopefully, I’ve helped someone out here.  Probably my future self will enjoy finding this code snippet someday…