ショートコードで投稿ページごとに閲覧数(カウンター)を表示する方法

この記事では、WordPressの投稿ページごとに閲覧数(カウンター)を表示する方法を解説します。

ポイントは以下です:

  • IP制限付きで投稿記事ごとの閲覧数をカウント
  • ショートコード [post_views] で投稿記事内・テンプレートに表示可能
  • Ajaxで非同期更新も対応可能(※JavaScript を無効にすれば通常のショートコード表示のみ)

functions.php に追加するコード

以下のコードを子テーマの functions.php に貼り付けます。


/**
 * 投稿の閲覧数を取得・更新する関数(IP制限付き)
 */
function get_post_views($postID){
    $count_key = 'post_views_count';
    $count = get_post_meta($postID, $count_key, true);
    if($count==''){
        update_post_meta($postID, $count_key, '0');
        return "0";
    }
    return $count;
}

function set_post_views($postID) {
    $count_key = 'post_views_count';
    $count = get_post_meta($postID, $count_key, true);

    if($count === '') {
        $count = 1; // 初回は1から
        add_post_meta($postID, $count_key, $count);
    } else {
        $count++;
        update_post_meta($postID, $count_key, $count);
    }
}

/**
 * 同一IPで6時間以内のカウントを防止
 */
function set_post_views_with_ip_limit($postID) {
    if (!is_single()) return;

    $ip = $_SERVER['REMOTE_ADDR'];
    $transient_name = 'post_views_' . $postID . '_' . md5($ip);

    if ( false === get_transient($transient_name) ) {
        set_post_views($postID);
        set_transient($transient_name, 1, 21600); // 6時間
    }
}

/**
 * 単一記事ページでカウント
 */
function track_post_views_ip_limit() {
    if (is_single()) {
        global $post;
        set_post_views_with_ip_limit($post->ID);
    }
}
add_action('wp', 'track_post_views_ip_limit'); // wp_head → wp

/**
 * ショートコードで表示(クラス付き)
 */
function post_views_shortcode() {
    $views = get_post_views(get_the_ID());
    return '<span class="post-views">' . esc_html($views) . '</span>';
}
add_shortcode('post_views', 'post_views_shortcode');
/**
 * Ajax用スクリプト読み込み
 */
function enqueue_post_views_script() {
    if (is_single()) {
        wp_enqueue_script(
            'post-views-ajax',
            get_stylesheet_directory_uri() . '/js/post-views.js',
            array('jquery'),
            '1.0',
            true
        );

        global $post;
        wp_localize_script('post-views-ajax', 'postViewsData', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'post_id' => $post->ID
        ));
    }
}
add_action('wp_enqueue_scripts', 'enqueue_post_views_script');

/**
 * Ajaxハンドラー
 */
add_action('wp_ajax_increment_post_views', 'increment_post_views_ajax');
add_action('wp_ajax_nopriv_increment_post_views', 'increment_post_views_ajax');

function increment_post_views_ajax() {
    $post_id = intval($_POST['post_id']);
    if($post_id) {
        // IP制限付きでカウント
        set_post_views_with_ip_limit($post_id);

        wp_send_json_success(array('views' => get_post_views($post_id)));
    } else {
        wp_send_json_error();
    }
}
補足:
例としてLightningで「外観」→「ウィジェット」→「サイドバー(投稿)」にテキストでショートコード[post_views]を挿入してください。「本日までのこのページの閲覧数は[post_views]人」と挿入すると分かりやすいです。

投稿ウィジェット

JavaScript (post-views.js)

Ajaxで非同期に閲覧数を更新する場合に使用します。

ファイル名:post-views.js
保存先:wp-content/themes/child-theme/js/post-views.js


document.addEventListener('DOMContentLoaded', function() {
    if(!postViewsData || !postViewsData.post_id) return;

    fetch(postViewsData.ajax_url, {
        method: 'POST',
        headers: {'Content-Type':'application/x-www-form-urlencoded'},
        body: 'action=increment_post_views&post_id=' + postViewsData.post_id
    })
    .then(response => response.json())
    .then(data => {
        if(data.success){
            const viewsEl = document.querySelector('.post-views');
            if(viewsEl) viewsEl.textContent = data.data.views;
        }
    });
});

子テーマのディレクトリ構造

  • child-theme/
    • style.css
    • functions.php
    • footer.php
    • header.php
    • js/
      • post-views.js
    • images/
      • logo.png

汎用CSS


/*ショートコードで投稿ページごとに閲覧数(カウンター)を表示*/
.post-views {
    display: inline-block;
    padding: 2px 8px;
    font-size: 0.9em;
    color: #333;
}

  

(例)
ショートコードで固定ページ、投稿ページごとに閲覧数(カウンター)を表示する方法

使い方まとめ

  • ウィジェットに [post_views] を挿入すると閲覧数を表示できます。
  • Ajaxで非同期更新したい場合は post-views.js を子テーマの js/ に置きます。