# Post Views Counter With Admin Column

> Counts views of posts and pages, shows the totals in a sortable "Views" column in the admin, and adds a [wpide_views] shortcode to display the count.

- Type: PHP
- Runs: Run everywhere
- Category: [Analytics & Tracking](https://wpide.com/library/category/analytics/)
- Tags: views, counter, statistics, popular-posts
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/analytics-post-views-counter/

## Code

```php
add_action( 'wp_footer', function () {
    if ( ! is_singular() || current_user_can( 'edit_posts' ) || is_preview() ) {
        return;
    }
    ?>
<script>
(function () {
    var id = <?php echo (int) get_queried_object_id(); ?>, key = 'wpide_viewed_' + id;
    try { if (sessionStorage.getItem(key)) { return; } sessionStorage.setItem(key, '1'); } catch (e) {}
    if (/bot|crawl|spider|slurp|lighthouse/i.test(navigator.userAgent)) { return; }
    var data = new FormData();
    data.append('action', 'wpide_count_view');
    data.append('post_id', id);
    if (navigator.sendBeacon) { navigator.sendBeacon(<?php echo wp_json_encode( admin_url( 'admin-ajax.php' ) ); ?>, data); }
})();
</script>
    <?php
} );

$wpide_count_view = function () {
    $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification -- public, cache-safe counter.

    if ( $post_id && 'publish' === get_post_status( $post_id ) && is_post_type_viewable( get_post_type( $post_id ) ) ) {
        update_post_meta( $post_id, '_wpide_views', (int) get_post_meta( $post_id, '_wpide_views', true ) + 1 );
    }

    wp_die( '', '', array( 'response' => 204 ) );
};

add_action( 'wp_ajax_nopriv_wpide_count_view', $wpide_count_view );
add_action( 'wp_ajax_wpide_count_view', $wpide_count_view );

add_shortcode( 'wpide_views', function ( $atts ) {
    $atts = shortcode_atts( array( 'id' => get_the_ID() ), $atts, 'wpide_views' );

    return esc_html( number_format_i18n( (int) get_post_meta( absint( $atts['id'] ), '_wpide_views', true ) ) );
} );

foreach ( array( 'post', 'page' ) as $wpide_type ) {
    add_filter( "manage_{$wpide_type}_posts_columns", function ( $columns ) {
        $columns['wpide_views'] = 'Views';

        return $columns;
    } );

    add_action( "manage_{$wpide_type}_posts_custom_column", function ( $column, $post_id ) {
        if ( 'wpide_views' === $column ) {
            echo esc_html( number_format_i18n( (int) get_post_meta( $post_id, '_wpide_views', true ) ) );
        }
    }, 10, 2 );

    add_filter( "manage_edit-{$wpide_type}_sortable_columns", function ( $columns ) {
        $columns['wpide_views'] = 'wpide_views';

        return $columns;
    } );
}

add_action( 'pre_get_posts', function ( $query ) {
    if ( is_admin() && $query->is_main_query() && 'wpide_views' === $query->get( 'orderby' ) ) {
        $query->set( 'meta_key', '_wpide_views' );
        $query->set( 'orderby', 'meta_value_num' );
    }
} );
```

## Notes

Counting happens with a small request after the page loads, so it works with page caching; editors and repeat views in the same session are not counted.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Post Views Counter With Admin Column" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
