Самый простой способ вывести количество просмотров записей, это установить плагин Post Views Counter


Чтобы вывести на страницу записи, добавьте шорткод [ post-views ]

Количество просмотров записей без плагина

Или Вы можете сделать без плагина, добавьте сниппет код:
/* Defaults / configuration */
if ( ! defined( 'AVS_PV_COOKIE_TTL' ) ) define( 'AVS_PV_COOKIE_TTL', 12 * HOUR_IN_SECONDS );
if ( ! defined( 'AVS_PV_BUFFER_TTL' ) ) define( 'AVS_PV_BUFFER_TTL', HOUR_IN_SECONDS );
if ( ! defined( 'AVS_PV_BUFFER_THRESHOLD' ) ) define( 'AVS_PV_BUFFER_THRESHOLD', 10 );
if ( ! defined( 'AVS_PV_VISITOR_TTL' ) ) define( 'AVS_PV_VISITOR_TTL', AVS_PV_COOKIE_TTL );
if ( ! defined( 'AVS_PV_TABLE' ) ) define( 'AVS_PV_TABLE', 'avs_post_views' );
if ( ! defined( 'AVS_PV_DIRTY_KEY' ) ) define( 'AVS_PV_DIRTY_KEY', 'avs_pv_dirty_posts' );
if ( ! defined( 'AVS_PV_CRON_HOOK' ) ) define( 'AVS_PV_CRON_HOOK', 'avs_pv_flush_buffers_cron' );
function avs_pv_get_client_ip() {
$keys = array( 'HTTP_CF_CONNECTING_IP', 'HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR' );
foreach ( $keys as $key ) {
if ( empty( $_SERVER[ $key ] ) ) continue;
$value = (string) $_SERVER[ $key ];
if ( 'HTTP_X_FORWARDED_FOR' === $key ) {
$parts = array_map( 'trim', explode( ',', $value ) );
$value = $parts[0] ?? $value;
}
if ( filter_var( trim( $value ), FILTER_VALIDATE_IP ) ) {
return trim( $value );
}
}
return '0.0.0.0';
}
function avs_pv_is_prefetch_request() {
$headers = array(
'HTTP_X_MOZ',
'HTTP_PURPOSE',
'HTTP_X_PURPOSE',
'HTTP_SEC_PURPOSE',
'HTTP_X_MIDDLETON_PREFETCH',
);
foreach ( $headers as $h ) {
if ( empty( $_SERVER[ $h ] ) ) continue;
$val = strtolower( trim( (string) $_SERVER[ $h ] ) );
if ( strpos( $val, 'prefetch' ) !== false || strpos( $val, 'prerender' ) !== false ) {
return true;
}
}
if ( ! empty( $_SERVER['HTTP_SEC_FETCH_MODE'] ) ) {
$mode = strtolower( trim( (string) $_SERVER['HTTP_SEC_FETCH_MODE'] ) );
if ( in_array( $mode, array( 'prefetch', 'prerender' ), true ) ) {
return true;
}
}
return false;
}
function avs_pv_should_skip_current_user() {
if ( ! is_user_logged_in() ) return false;
$user = wp_get_current_user();
if ( ! $user || empty( $user->roles ) ) return false;
$excluded_roles = apply_filters( 'avs_pv_excluded_roles', array( 'administrator', 'editor', 'author', 'shop_manager' ) );
if ( ! is_array( $excluded_roles ) ) $excluded_roles = array();
return (bool) array_intersect( (array) $user->roles, $excluded_roles );
}
function avs_pv_cookie_name( $post_id ) {
return 'avs_pv_' . (int) $post_id;
}
function avs_pv_visitor_lock_key( $post_id ) {
$post_id = (int) $post_id;
$user_id = get_current_user_id();
if ( $user_id > 0 ) {
return 'avs_pv_v_' . $post_id . '_u_' . $user_id;
}
$ip = avs_pv_get_client_ip();
$ua = ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? strtolower( trim( (string) wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) ) : '';
return 'avs_pv_v_' . $post_id . '_g_' . md5( $ip . '|' . $ua );
}
function avs_pv_has_recent_visitor_hit( $post_id ) {
$post_id = (int) $post_id;
if ( $post_id <= 0 ) return false;
$cookie = avs_pv_cookie_name( $post_id );
if ( ! empty( $_COOKIE[ $cookie ] ) ) {
return true;
}
$lock_key = avs_pv_visitor_lock_key( $post_id );
return (bool) get_transient( $lock_key );
}
function avs_pv_mark_visitor_hit( $post_id ) {
$post_id = (int) $post_id;
if ( $post_id <= 0 ) return;
$ttl = (int) apply_filters( 'avs_pv_visitor_ttl', AVS_PV_VISITOR_TTL );
if ( $ttl <= 0 ) $ttl = AVS_PV_VISITOR_TTL;
$cookie = avs_pv_cookie_name( $post_id );
$path = defined( 'COOKIEPATH' ) ? COOKIEPATH : '/';
$domain = defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : '';
@setcookie( $cookie, '1', time() + $ttl, $path ?: '/', $domain ?: '', is_ssl(), true );
$_COOKIE[ $cookie ] = '1';
set_transient( avs_pv_visitor_lock_key( $post_id ), 1, $ttl );
}
/* Create DB table if missing */
add_action( 'init', 'avs_pv_maybe_create_table', 5 );
function avs_pv_maybe_create_table() {
global $wpdb;
$tbl = $wpdb->prefix . AVS_PV_TABLE;
$exists = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $tbl ) );
if ( $exists === $tbl ) return;
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE {$tbl} (
post_id bigint unsigned NOT NULL,
views bigint unsigned NOT NULL DEFAULT 0,
last_updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (post_id)
) {$charset_collate};";
dbDelta( $sql );
}
/* Server-side counting for uncached requests (single posts) */
add_action( 'template_redirect', 'avs_pv_maybe_count' );
function avs_pv_maybe_count() {
if ( is_admin() ) return;
if ( ! is_singular() ) return;
if ( ! is_main_query() ) return;
if ( 'GET' !== ( $_SERVER['REQUEST_METHOD'] ?? '' ) ) return;
global $post;
if ( empty( $post ) || empty( $post->ID ) ) return;
$post_id = (int) $post->ID;
if ( get_post_type( $post_id ) !== 'post' ) return;
if ( is_preview() || wp_is_post_revision( $post_id ) ) return;
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) return;
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) return;
if ( avs_pv_should_skip_current_user() ) return;
if ( avs_pv_is_prefetch_request() ) return;
if ( avs_pv_is_bot() ) return;
if ( avs_pv_has_recent_visitor_hit( $post_id ) ) return;
avs_pv_buffer_increment( $post_id );
avs_pv_mark_visitor_hit( $post_id );
}
/* REST API: hit and views */
add_action( 'rest_api_init', function() {
register_rest_route( 'avs/v1', '/post/(?P<id>\d+)/hit', array(
'methods' => 'POST',
'callback' => 'avs_pv_rest_hit_callback',
'permission_callback' => '__return_true',
) );
register_rest_route( 'avs/v1', '/post/(?P<id>\d+)/views', array(
'methods' => 'GET',
'callback' => function( $request ) {
$id = (int) $request['id'];
if ( $id <= 0 ) return new WP_Error( 'invalid_id', 'Invalid post ID', array( 'status' => 400 ) );
return rest_ensure_response( array( 'views' => avs_pv_get_views( $id ) ) );
},
'permission_callback' => '__return_true',
) );
} );
function avs_pv_rest_hit_callback( $request ) {
$id = (int) $request['id'];
if ( $id <= 0 ) return new WP_Error( 'invalid_id', 'Invalid post ID', array( 'status' => 400 ) );
if ( get_post_type( $id ) !== 'post' ) return new WP_Error( 'wrong_type', 'Not a standard post', array( 'status' => 400 ) );
$site_host = parse_url( home_url(), PHP_URL_HOST );
$allowed = false;
if ( ! empty( $_SERVER['HTTP_ORIGIN'] ) ) {
$origin_host = parse_url( wp_unslash( $_SERVER['HTTP_ORIGIN'] ), PHP_URL_HOST );
if ( $origin_host === $site_host ) $allowed = true;
}
if ( ! $allowed && ! empty( $_SERVER['HTTP_REFERER'] ) ) {
$ref_host = parse_url( wp_unslash( $_SERVER['HTTP_REFERER'] ), PHP_URL_HOST );
if ( $ref_host === $site_host ) $allowed = true;
}
if ( ! $allowed ) {
return new WP_Error( 'forbidden_origin', 'Forbidden', array( 'status' => 403 ) );
}
if ( avs_pv_should_skip_current_user() || avs_pv_is_prefetch_request() ) {
return rest_ensure_response( array( 'ok' => false, 'skipped' => true ) );
}
if ( avs_pv_is_bot() ) {
return rest_ensure_response( array( 'ok' => false, 'bot' => true ) );
}
if ( avs_pv_has_recent_visitor_hit( $id ) ) {
return rest_ensure_response( array( 'ok' => true, 'message' => 'already' ) );
}
avs_pv_buffer_increment( $id );
avs_pv_mark_visitor_hit( $id );
return rest_ensure_response( array( 'ok' => true ) );
}
/* Simple bot detection (filterable) */
function avs_pv_is_bot() {
$forced = apply_filters( 'avs_pv_is_bot', null );
if ( $forced !== null ) return (bool) $forced;
$ua = ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? strtolower( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';
if ( $ua === '' ) return true;
$bots = apply_filters( 'avs_pv_bot_useragents', array(
'bot','crawl','slurp','googlebot','bingbot','yandex','facebookexternalhit','facebot',
'ahrefs','semrush','curl','wget','python-requests','php','libwww-perl'
) );
foreach ( $bots as $b ) {
$b = trim( strtolower( $b ) );
if ( $b === '' ) continue;
if ( strpos( $ua, $b ) !== false ) return true;
}
if ( ! empty( $_SERVER['HTTP_ACCEPT'] ) ) {
$accept = strtolower( $_SERVER['HTTP_ACCEPT'] );
if ( strpos( $accept, 'text/html' ) === false && strpos( $accept, '*/*' ) === false ) return true;
}
return false;
}
/* Buffer increment (object cache preferred) + dirty tracking */
function avs_pv_buffer_increment( $post_id ) {
$post_id = (int) $post_id;
if ( $post_id <= 0 ) return false;
$key = "avs_pv_buffer_{$post_id}";
$use_cache = wp_using_ext_object_cache();
$ttl = (int) apply_filters( 'avs_pv_buffer_ttl', AVS_PV_BUFFER_TTL );
$threshold = (int) apply_filters( 'avs_pv_buffer_threshold', AVS_PV_BUFFER_THRESHOLD );
if ( $use_cache ) {
$buf = (int) wp_cache_get( $key, 'avs_pv' );
$buf++;
wp_cache_set( $key, $buf, 'avs_pv', $ttl );
} else {
$buf = (int) get_transient( $key );
$buf++;
set_transient( $key, $buf, $ttl );
}
$dirty_key = AVS_PV_DIRTY_KEY;
$dirty = get_transient( $dirty_key );
if ( ! is_array( $dirty ) ) $dirty = array();
if ( ! in_array( $post_id, $dirty, true ) ) {
$dirty[] = $post_id;
set_transient( $dirty_key, $dirty, DAY_IN_SECONDS );
}
if ( $buf >= $threshold ) {
if ( function_exists( 'as_enqueue_async_action' ) ) {
as_enqueue_async_action( 'avs_pv_flush_single_action', array( 'post_id' => $post_id ), 'avs-pv' );
} elseif ( function_exists( 'as_schedule_single_action' ) ) {
as_schedule_single_action( time() + 1, 'avs_pv_flush_single_action', array( 'post_id' => $post_id ), 'avs-pv' );
} else {
avs_pv_flush_post_buffer( $post_id );
}
}
return true;
}
/* Action Scheduler handler */
add_action( 'avs_pv_flush_single_action', 'avs_pv_as_single_flush_handler', 10, 1 );
function avs_pv_as_single_flush_handler( $args ) {
if ( empty( $args['post_id'] ) ) return;
avs_pv_flush_post_buffer( (int) $args['post_id'] );
}
/* Flush buffer to DB */
function avs_pv_flush_post_buffer( $post_id ) {
global $wpdb;
$post_id = (int) $post_id;
if ( $post_id <= 0 ) return false;
$key = "avs_pv_buffer_{$post_id}";
$use_cache = wp_using_ext_object_cache();
$buffer = $use_cache ? (int) wp_cache_get( $key, 'avs_pv' ) : (int) get_transient( $key );
if ( $buffer <= 0 ) {
avs_pv_remove_dirty( $post_id );
return false;
}
$table = $wpdb->prefix . AVS_PV_TABLE;
$now = current_time( 'mysql', 1 );
$sql = $wpdb->prepare(
"INSERT INTO {$table} (post_id, views, last_updated) VALUES (%d, %d, %s)
ON DUPLICATE KEY UPDATE views = views + %d, last_updated = %s",
$post_id, $buffer, $now, $buffer, $now
);
$wpdb->query( $sql );
if ( $use_cache ) wp_cache_delete( $key, 'avs_pv' );
else delete_transient( $key );
avs_pv_remove_dirty( $post_id );
return true;
}
function avs_pv_remove_dirty( $post_id ) {
$dirty_key = AVS_PV_DIRTY_KEY;
$dirty = get_transient( $dirty_key );
if ( ! is_array( $dirty ) ) return;
$idx = array_search( $post_id, $dirty, true );
if ( $idx !== false ) {
array_splice( $dirty, $idx, 1 );
set_transient( $dirty_key, $dirty, DAY_IN_SECONDS );
}
}
/* Periodic flush runner: Action Scheduler preferred, WP-Cron fallback (5 minutes) */
add_action( 'wp_loaded', 'avs_pv_schedule_flush_runner' );
function avs_pv_schedule_flush_runner() {
$hook = AVS_PV_CRON_HOOK;
if ( function_exists( 'as_schedule_recurring_action' ) && function_exists( 'as_next_scheduled_action' ) ) {
if ( ! as_next_scheduled_action( 'avs_pv_as_cron' ) ) {
as_schedule_recurring_action( time() + 60, 5 * MINUTE_IN_SECONDS, 'avs_pv_as_cron', array(), 'avs-pv' );
}
add_action( 'avs_pv_as_cron', 'avs_pv_cron_flush' );
return;
}
if ( ! wp_next_scheduled( $hook ) ) {
wp_schedule_event( time() + 60, 'avs_pv_5min', $hook );
}
add_action( $hook, 'avs_pv_cron_flush' );
}
add_filter( 'cron_schedules', function( $schedules ) {
if ( empty( $schedules['avs_pv_5min'] ) ) {
$schedules['avs_pv_5min'] = array(
'interval' => 5 * MINUTE_IN_SECONDS,
'display' => 'AVS every 5 minutes'
);
}
return $schedules;
} );
function avs_pv_cron_flush() {
$dirty_key = AVS_PV_DIRTY_KEY;
$dirty = get_transient( $dirty_key );
if ( ! is_array( $dirty ) || empty( $dirty ) ) return;
set_transient( $dirty_key, array(), DAY_IN_SECONDS );
foreach ( $dirty as $post_id ) {
avs_pv_flush_post_buffer( (int) $post_id );
}
}
/* Read helper: DB + buffered */
function avs_pv_get_views( $post_id = 0 ) {
global $wpdb;
$post_id = (int) $post_id;
if ( $post_id <= 0 ) $post_id = get_the_ID();
if ( $post_id <= 0 ) return 0;
if ( get_post_type( $post_id ) !== 'post' ) return 0;
$table = $wpdb->prefix . AVS_PV_TABLE;
$row = $wpdb->get_row( $wpdb->prepare( "SELECT views FROM {$table} WHERE post_id = %d LIMIT 1", $post_id ), ARRAY_A );
$db_views = ( $row && isset( $row['views'] ) ) ? (int) $row['views'] : 0;
$key = "avs_pv_buffer_{$post_id}";
$use_cache = wp_using_ext_object_cache();
$buffer = $use_cache ? (int) wp_cache_get( $key, 'avs_pv' ) : (int) get_transient( $key );
return $db_views + max(0, $buffer);
}
/* Cached read helper */
function avs_pv_get_views_cached( $post_id = 0, $ttl = 60 ) {
$post_id = (int) $post_id;
if ( $post_id <= 0 ) $post_id = get_the_ID();
if ( $post_id <= 0 ) return 0;
if ( get_post_type( $post_id ) !== 'post' ) return 0;
$cache_key = "avs_pv_views_{$post_id}";
$cached = wp_cache_get( $cache_key, 'avs_pv' );
if ( $cached !== false ) {
return (int) $cached;
}
$views = avs_pv_get_views( $post_id );
wp_cache_set( $cache_key, (int) $views, 'avs_pv', $ttl );
return (int) $views;
}
/* Shortcode: server-side rendering to avoid flicker */
add_shortcode( 'avs_post_views_container', function( $atts ) {
$atts = shortcode_atts( array( 'id' => 0, 'cache_ttl' => 60 ), $atts, 'avs_post_views_container' );
$post_id = (int) $atts['id'];
if ( $post_id <= 0 ) $post_id = get_the_ID();
if ( ! $post_id ) return '<span class="avs-post-views" data-post-id="">0</span>';
$ttl = (int) $atts['cache_ttl'];
if ( $ttl < 0 ) $ttl = 0;
$views = $ttl > 0 ? avs_pv_get_views_cached( $post_id, $ttl ) : avs_pv_get_views( $post_id );
return '<span class="avs-post-views" data-post-id="' . esc_attr( $post_id ) . '">' . intval( $views ) . '</span>';
} );
/* Admin: add "Просмотры" column (appended last) and make it sortable */
add_filter( 'manage_edit-post_columns', 'avs_admin_add_views_column' );
function avs_admin_add_views_column( $columns ) {
$columns['avs_views'] = __( 'Просмотры', 'avs' );
return $columns;
}
add_action( 'manage_post_posts_custom_column', 'avs_admin_render_views_column', 10, 2 );
function avs_admin_render_views_column( $column, $post_id ) {
if ( 'avs_views' !== $column ) return;
if ( function_exists( 'avs_pv_get_views_cached' ) ) {
$views = avs_pv_get_views_cached( $post_id, 30 );
} else {
$views = function_exists( 'avs_pv_get_views' ) ? avs_pv_get_views( $post_id ) : 0;
}
echo '<span class="avs-views-count">' . intval( $views ) . '</span>';
}
add_filter( 'manage_edit-post_sortable_columns', 'avs_admin_make_views_sortable' );
function avs_admin_make_views_sortable( $sortable ) {
$sortable['avs_views'] = 'avs_views';
return $sortable;
}
add_filter( 'posts_join', 'avs_admin_posts_join_for_views', 10, 2 );
function avs_admin_posts_join_for_views( $join, $query ) {
if ( ! is_admin() || ! $query->is_main_query() ) return $join;
$orderby = $query->get( 'orderby' );
$post_type = $query->get( 'post_type' );
if ( 'avs_views' === $orderby && ( ! $post_type || 'post' === $post_type ) ) {
global $wpdb;
$tbl = $wpdb->prefix . ( defined( 'AVS_PV_TABLE' ) ? AVS_PV_TABLE : 'avs_post_views' );
$join .= " LEFT JOIN {$tbl} AS avs_views_table ON avs_views_table.post_id = {$wpdb->posts}.ID ";
}
return $join;
}
add_filter( 'posts_orderby', 'avs_admin_posts_orderby_for_views', 10, 2 );
function avs_admin_posts_orderby_for_views( $orderby_sql, $query ) {
if ( ! is_admin() || ! $query->is_main_query() ) return $orderby_sql;
$orderby = $query->get( 'orderby' );
$post_type = $query->get( 'post_type' );
if ( 'avs_views' === $orderby && ( ! $post_type || 'post' === $post_type ) ) {
$order = strtoupper( $query->get( 'order' ) ) === 'ASC' ? 'ASC' : 'DESC';
$orderby_sql = " COALESCE(avs_views_table.views,0) {$order} ";
}
return $orderby_sql;
}
/* Optional admin CSS */
add_action( 'admin_head-edit.php', 'avs_admin_column_css' );
function avs_admin_column_css() {
?>
<style>
.wp-list-table .column-avs_views { width: 8%; text-align: left; }
.avs-views-count { display: inline-block; min-width: 30px; text-align: left; }
</style>
<?php
}
/**
* Шорткод [avs_post_views] — число просмотров из основного AVS-счетчика
*/
add_shortcode( 'avs_post_views', function( $atts ) {
$atts = shortcode_atts( array( 'id' => 0, 'cache_ttl' => 60 ), $atts, 'avs_post_views' );
$post_id = (int) $atts['id'];
if ( $post_id <= 0 ) {
$post_id = get_the_ID();
}
if ( $post_id <= 0 ) {
return '0';
}
$ttl = max( 0, (int) $atts['cache_ttl'] );
$views = $ttl > 0 ? avs_pv_get_views_cached( $post_id, $ttl ) : avs_pv_get_views( $post_id );
return (string) number_format_i18n( (int) $views );
} );Вывести количество просмотров шоркодом [ avs_post_views ]
Админке также появится сортируемый столбец с количеством просмотров.
Количество просмотров считается только для стандартных записей WordPress, чтобы вывести кол-во просмотров для CCT и CPT, то необходимо изменить php.