WP Code Tip: get array of post IDs

A number of times over my years developing in WordPress I’ve needed to extract the post IDs of the posts in an array. And every time I need to do this I use the wp_list_pluck() function, from WP_List_Util, the WordPress list utility class. And every time I use this really handy helper I mean to write a simple blog post to help promote it. So here it is.

To help demonstrate its purpose, and why it’s used, rather than PHP’s array_column() function, let’s look at the following scenario.

Scenario – exclude post IDs from a WP Query

Objective: Show the trending posts and the latest posts, on the homepage, excluding trending posts from latest posts.

In this scenario the objective is to record the post IDs from an array of trending post objects, so they can be excluded from the array of latest post objects, resulting in two unique lists of posts.

NB: This is for demonstration purposes only

If I were solving this particular problem I’d only return an array of IDs (rather than post objects) and exclude them using post__not_in, but for the purposes of a simple way to demonstrate how to use wp_list_pluck() I’ll ignore that option.

Why use wp_list_pluck instead of array_column?

As stated by WordPress, these list helpers do almost the same thing; that is, they grab a field from each item in a list, in our case the ID for each post in the query. The reason we’re using wp_list_pluck() is simply because it works on objects, too, which is perfect, as our query will return an array of post objects, containing (among others) the post IDs.

Query for Trending Posts

/**
 * Filter posts 'WHERE' comments are greater than 0
 * 
 * appends an additional clause to the SQL query to return only posts with comments.
 *
 * @return $where string
 */
function itd_has_comments_filter($where) {
    $where .= ' AND comment_count > 0 ';
    return $where;
}

// Hang the comments filter onto the 'posts_where' hook
add_filter('posts_where', 'itd_has_comments_filter');

/**
 * Get a list of trending posts
 * 
 * This is based on the number of comments the post has received over the last month (if any).
 */
// Set up the args to order by comments, then modified date and limit to 6 posts that have been modified in the last month.
$args = [
    'post_type' => 'post',
    'posts_per_page' => 6,
    'date_query' => [
        'column' => 'modified',
        'after'  => '1 month ago',
    ],
    'orderby' => [
        'comment_count' => 'DESC',
        'post_modified' => 'DESC'
    ],
];

// store the query results
$trending_posts = new WP_Query($args);

// restore the posts query
remove_filter('posts_where', 'itd_has_comments_filter');
wp_reset_postdata();

// get the array of post IDs 
$trending_post_ids = wp_list_pluck($trending_posts->posts, 'ID');

Query for Latest Posts

/**
 * Get a list of latest posts, excluding trending posts
 */
// Set up the args to order by latest posts (default) and limit to 6 posts, excluding the $trending_post_ids.
$args = [
    'post_type' => 'post',
    'posts_per_page' => 6,
    'post__not_in' => $trending_post_ids,
];

// store the query results
$latest_posts = new WP_Query($args);

// restore the posts query
wp_reset_postdata();

Conclusion

So there you have it, wp_list_pluck is a simple helper that circumnavigates the need to write a loop to get the column data from an array/object. Also in the above examples you’ll see the use of the posts_where filter, that’s modifying the posts query to include an additional WHERE parameter to the SQL database query, and semi-complex query arguments, for querying by date parameters and multi-field ordering – feel free to get in touch if you want to know about how to use these, or if you would like a helping hand with any development challenges.