1

I'd like to add that nice little notification bubble beside a nav item in the admin. But I don't want to slow down the whole admin by triggering a post query every time just to display the value in the little bubble. Hoping to load this one integer value into transient cache to use for display in the menu.

Developing a custom plugin which registers a custom post type. This automatically creates the nav item in the admin, which I'd like to add the bubble to. The value within the bubble will be pulled from a simple query of how many posts (of this CPT) have been assigned to a custom taxonomy. For example if post has been assigned to custom term "pending review" then add to bubble count.

This function here works a charm, although I have no idea how to transition to using transient cache to store and retrieve the data.... any suggestions would be greatly appreciated. Thanks!

add_action( 'admin_menu', 'add_cpt_menu_bubble' );
function add_cpt_menu_bubble() {
    global $menu;
    $count_posts = 0;

    // count the number of posts to show in bubble
    $args = array(
        'order'    => 'DESC',
        'posts_per_page' => '-1',
        'post_type' => 'custom_post_type_name',
        'custom_tax_name' => 'pending-review'
    );
    // The Query
    query_posts( $args );
    if (have_posts()) : 
        while ( have_posts() ) : the_post(); 
            $count_posts++;
        endwhile; 
        else: 
    endif; 
    wp_reset_query();

    // only display the number of pending posts over a certain amount
    if ( $count_posts > 5 ) {
        foreach ( $menu as $key => $value ) {
            if ( $menu[$key][2] == 'edit.php?post_type=custom_post_type_name' ) {
                $menu[$key][0] .= ' <span class="update-plugins count-2"><span class="update-count">' . $count_posts . '</span></span>';
                return;
            }
        }
    }

} // EOF
2
  • 1
    To clarify, you want to cache the result of your count query in a transient instead of querying each time?
    – jdm2112
    Commented Feb 22, 2018 at 20:40
  • exactly right @jdm2112
    – Simon
    Commented Feb 23, 2018 at 0:16

2 Answers 2

2

Thanks again for the help @jdm2112. Updated a few syntax errors and used the same structure you suggested, works great!

// Add notification bubble to custom post type menu nav 
add_action( 'admin_menu', 'add_cpt_menu_bubble' );
function add_cpt_menu_bubble() {
    global $menu;
    $count_posts = tms_count_pending_posts();
    if ( $count_posts > 3 ) {
        foreach ( $menu as $key => $value ) {
            if ( $menu[$key][2] == 'edit.php?post_type=custom_post_type_name' ) {
                $menu[$key][0] .= ' <span class="update-plugins count-2"><span class="update-count">' . $count_posts . '</span></span>';
                return;
            }
        }
    }
}
function tms_count_pending_posts() {
    if ( false === ( $num_posts = get_transient( 'tms_pending_posts_key' ) ) ) {
        $args = array(
            'order'    => 'DESC',
            'posts_per_page' => '-1',
            'post_type' => 'custom_post_type_name',
            'custom_tax' => 'pending-review'
        );
        $posttype_query = new WP_Query( $args );
        ($posttype_query->post_count) ? $num_posts = $posttype_query->post_count : $num_posts = 0;
        set_transient( 'tms_pending_posts_key', $num_posts, 30 ); 
    } 
    return $num_posts;
}
1

Using your original code, I pulled the query/count/cache code to a separate function. I have not had a chance to test any of this yet so my apologies if you hit any errors. Post here if you do and I'll update when I can test it.

Briefly, the idea is to first check for a valid transient based on its key (name) which is unique for each value and if no value exists, create it anew and store it. Either way, calling the function should return the count of posttype posts, up to 4 hours old.

I randomly selected 4 hours but that is an easy parameter to edit. Simply come up with something to use in place of "your-transient-key" and you should be good to go.

add_action( 'admin_menu', 'add_cpt_menu_bubble' );
function add_cpt_menu_bubble() {
    global $menu;

    // Retrieve cached value or count current number of posttype posts.
$count_posts = wpse_count_of_posttype_posts

    // only display the number of pending posts over a certain amount
    if ( $count_posts > 5 ) {
        foreach ( $menu as $key => $value ) {
            if ( $menu[$key][2] == 'edit.php?post_type=custom_post_type_name' ) {
                $menu[$key][0] .= ' <span class="update-plugins count-2"><span class="update-count">' . $count_posts . '</span></span>';
                return;
            }
        }
    }

}

function wpse_count_of_postype_posts() {

    // First try to get a cached value
    if ( false === ( $num_posts = get_transient( 'your-transient-key' ) ) ) {
        // this code runs when there is no valid transient set

        // Your original query args
        $args = array(
            'order'    => 'DESC',
            'posts_per_page' => '-1',
            'post_type' => 'custom_post_type_name',
            'custom_tax_name' => 'pending-review'
        );

        // Instantiate WP_Query instead
        $posttype_query = new WP_Query( $args );

        // One of the properties of the class is a count of the posts. No need to loop and increment a counter
        // https://codex.wordpress.org/Class_Reference/WP_Query#Properties
        $num_posts = $posttype_query->post_count;

        // Store the count in your transient; build it now for the future https://www.youtube.com/watch?v=XjYLvpwDNOY
        set_transient( 'your-transient-key', $num_posts, 4 * HOUR_IN_SECONDS );

        return $num_posts;
    }
}
1
  • Thanks for the response! let me check that out, test and repost.
    – Simon
    Commented Feb 26, 2018 at 16:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.