How do i display the number of images on the “post screen”

The code below suggests one approach to handling the display of a post image count on the Post Edit List screen (edit.php). The function names provide an outline of what the code is doing. References to WordPress Documentation are below for details about the action and filter hooks used. Add the code to your plugin or child theme.

Images are counted with a simple regular expression matching the opening of an image tag (<img).

An image_count post meta data field is used to store the image count for a post. Using meta data allows for searching, filtering and sorting with WP Query.

The code assumes that images are counted for core WordPress Post types only. Different hooks are needed for custom post types.

/**
 * Register an image_count post meta key if you want
 * it to be available via WordPress REST API.
 */
function register_image_count_post_meta() {
    register_meta(
        'post',
        'image_count',
        array(
            'object_subtype'    => 'post',
            'description'       => 'Count of images in post.',
            'show_in_rest'      => true,
            'single'            => true,
            'type'              => 'integer',
            'default'           => 0,
            'sanitize_callback' => function( $value ) { return $value; }, // Replace with proper sanitization.
            'auth_callback'     => function() { return '__return_true'; } // Replace with proper authorization check.
        )
    );
}
add_action( 'rest_api_init', 'register_image_count_post_meta', 10, 1 );


function add_post_screen_custom_headings( $columns ) {
    $columns['image_count'] = __( 'Images', 'translation_domain' );

    return $columns;
}
add_filter( 'manage_posts_columns', 'add_post_screen_custom_headings', 10, 1 );


/**
 * Render content for the custom column.
 * A switch statement is commonly used when rendering several custom
 * columns.
 */
function add_post_screen_custom_content( $column, $post_id ) {
    switch ( $column ) {
        case 'image_count' :
            $single_value = true; // Single value. Not an array.

            $image_count = get_post_meta( $post_id , 'image_count', $single_value );
            echo $image_count;
            break;
    }
}
add_action( 'manage_posts_custom_column', 'add_post_screen_custom_content', 10, 2 );


/**
 * This filter is needed to make the custom column
 * sortable on the post screen.
 */
function register_post_screen_images_column_as_sortable( $columns ) {
    $columns['image_count'] = 'image_count';

    return $columns;
}
add_filter( 'manage_edit-post_sortable_columns', 'register_post_screen_images_column_as_sortable' );


/**
 * If the user clicks the custom column header to sort the page
 * this function is called to update the WP Query.
 */
function update_post_screen_images_column_orderby( $query_vars ) {
    if ( isset( $query_vars['orderby'] ) && 'image_count' == $query_vars['orderby'] ) {
        $query_vars = array_merge( $query_vars, array(
            'orderby'   => 'meta_value',
            'meta_key'  => 'image_count',
            'meta_type' => 'NUMERIC'
        ) );
    }

    return $query_vars;
}
add_filter( 'request', 'update_post_screen_images_column_orderby' );


/**
 * This function is optional.
 * It suggests that you might want to initialize the image_count
 * meta data value for all posts that currently do not yet
 * have an image_count post meta key.
 */
function initialize_image_count() {
    $posts = get_posts( array(
        'post_type' => 'post',
        'post_status' => 'publish',
        'numberposts' => -1,
        'meta_query' => array(
            array(
                'key' => 'image_count',
                'compare' => 'NOT EXISTS'
            )
        )
    ) );

    foreach ( $posts as $post ) {
        $count = preg_match_all( "/<img\s+/i", $post->post_content );

        if ( is_bool( $count ) ) {
            $image_count = 0;
        } else {
            $image_count = $count;
        }

        update_post_meta( $post->ID, 'image_count', $image_count );
    }
}
add_action( 'init', 'initialize_image_count', 10, 1 );


/**
 * Whenever a post is updated, this function is called to update
 * the image_count.
 */
function dynamically_update_post_image_count( $post_id, $post, $update ) {

    $count = preg_match_all( "/<img\s+/i", $post->post_content );

    if ( is_bool( $count ) ) {
        $image_count = 0;
    } else {
        $image_count = $count;
    }

    if ( empty( $completion_date ) ) {
        remove_action( 'save_post', 'dynamically_update_post_image_count' );
        update_metadata( 'post', $post_id, 'image_count', $image_count );
        add_action( 'save_post', 'dynamically_update_post_image_count', 10, 3 );
    }
}
add_action( 'save_post', 'dynamically_update_post_image_count', 10, 3 );

Further Reading / Useful Links

rest_api_init

  • Fires when preparing to serve a REST API request.

manage_posts_columns

  • Filters the columns displayed in the Posts list table.

manage_posts_custom_column

  • Fires in each custom column in the Posts list table.

manage_{$this->screen->id}_sortable_columns

  • Filters the list table sortable columns for a specific screen.

request

  • Filters the array of parsed query variables.

init

  • Fires after WordPress has finished loading but before any headers are sent.

save_post

  • Fires once a post has been saved.

preg_match_all

  • Counts regular expression matches in a string.