WordPress’te Yazı Görüntülenme Sayacı: functions.php ile View Counter

WordPress sitende bir yazının kaç kez görüntülendiğini bilmek istiyorsun ama eklenti kurmaktan kaçınıyorsun. Haklısın, her şey için eklenti kurmak sitenin performansını ciddi ölçüde etkiliyor. İşte tam bu noktada functions.php devreye giriyor. Birkaç satır kodla kendi görüntülenme sayacını yazabilir, bunu istediğin yerde gösterebilir ve hatta en çok okunan yazıları listeleyebilirsin. Bu yazıda adım adım her şeyi ele alacağız.

Temel Mantık: Nasıl Çalışıyor?

WordPress’te view counter sistemi üç temel adımdan oluşur. Birincisi, kullanıcı bir yazıya girdiğinde sayacı artırmak. İkincisi, bu değeri bir yerde saklamak. Üçüncüsü, istediğinde bu değeri okuyup göstermek.

Değeri saklamak için WordPress’in post meta sistemi kullanılıyor. Yani her yazı için _post_views_count gibi bir meta alanı oluşturuyoruz ve her görüntülemede bu değeri bir artırıyoruz. Bu yaklaşım hem performanslı hem de WordPress’in kendi altyapısına uygun.

Dikkat edilmesi gereken bir nokta var: Admin panelinde yazıya her girdiğinde sayaç artmamalı. Aksi hâlde rakamlar anlamsız hâle gelir. Bunun için admin kullanıcılarını ve bot isteklerini filtreleyeceğiz.

Adım 1: Temel View Counter Fonksiyonu

functions.php dosyanı açıp aşağıdaki kodu ekliyoruz. Bu kod, sayacı artıran ve okuyan iki temel fonksiyonu içeriyor.

// functions.php

// Görüntülenme sayısını artır
function wpb_set_post_views($postID) {
    $count_key = '_post_views_count';
    $count = get_post_meta($postID, $count_key, true);

    if ($count == '') {
        $count = 0;
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, '0');
    } else {
        $count++;
        update_post_meta($postID, $count_key, $count);
    }
}

// Görüntülenme sayısını oku
function wpb_get_post_views($postID) {
    $count_key = '_post_views_count';
    $count = get_post_meta($postID, $count_key, true);

    if ($count == '') {
        delete_post_meta($postID, $count_key);
        add_post_meta($postID, $count_key, '0');
        return "0 görüntülenme";
    }

    return $count . ' görüntülenme';
}

Bu iki fonksiyon temel yapı taşlarımız. Şimdi bunları tetiklememiz gerekiyor.

Adım 2: Sayacı Otomatik Tetikleme

Fonksiyonları yazdık ama henüz çalışmıyorlar. Bir kullanıcı yazıya girdiğinde wpb_set_post_views fonksiyonunu çağırmamız lazım. Bunun için wp_head kancasını kullanacağız.

// functions.php - Sayacı otomatik artır

function wpb_track_post_views($post_id) {
    // Sadece tekil yazılarda çalış
    if (!is_single()) return;

    // Admin kullanıcıları sayma
    if (current_user_can('administrator')) return;

    // REST API isteklerini atla
    if (defined('REST_REQUEST') && REST_REQUEST) return;

    // XML-RPC isteklerini atla
    if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) return;

    if (empty($post_id)) {
        global $post;
        $post_id = $post->ID;
    }

    wpb_set_post_views($post_id);
}

add_action('wp_head', 'wpb_track_post_views');

Bu kodu ekledikten sonra artık her tekil yazı sayfası açıldığında sayaç otomatik olarak bir artacak. Admin kullanıcıları hariç tutulduğu için test ederken sayacın şişmesinden korkmana gerek yok.

Adım 3: Sayacı Tema Şablonunda Gösterme

Sayaç artık çalışıyor ama bunu kullanıcıya göstermiyoruz. single.php dosyana ya da kullanmak istediğin herhangi bir şablon dosyasına şu satırı ekleyebilirsin:

// single.php veya herhangi bir şablon dosyasında kullan

<?php echo wpb_get_post_views(get_the_ID()); ?>

Bunu biraz daha şekillendirmek istersen:

// Daha detaylı çıktı için

function wpb_display_post_views() {
    $post_id = get_the_ID();
    $count_key = '_post_views_count';
    $count = get_post_meta($post_id, $count_key, true);

    if (empty($count)) {
        $count = 0;
    }

    $output = '<span class="post-views">';
    $output .= '<i class="fas fa-eye"></i> ';

    if ($count == 1) {
        $output .= '1 kez görüntülendi';
    } else {
        $output .= number_format($count) . ' kez görüntülendi';
    }

    $output .= '</span>';

    return $output;
}

number_format kullanmak önemli, çünkü 15000 görüntülenmeyi “15.000” olarak göstermek çok daha okunabilir.

Adım 4: Önbellekleme Sorunu ve Çözümü

Eğer sitenizde WP Super Cache, W3 Total Cache veya LiteSpeed Cache gibi bir önbellekleme eklentisi kullanıyorsanız, wp_head ile sayacı artırmak düzgün çalışmayabilir. Çünkü sayfa önbellekten geldiğinde PHP kodu tekrar çalışmıyor.

Bu sorunu çözmek için sayacı JavaScript ile AJAX üzerinden artırmalıyız.

// functions.php - AJAX tabanlı view counter

// AJAX işleyicisini kaydet
function wpb_ajax_track_views() {
    // Güvenlik kontrolü
    if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wpb_views_nonce')) {
        wp_die('Güvenlik hatası');
    }

    $post_id = intval($_POST['post_id']);

    if ($post_id > 0) {
        // Admin değilse say
        if (!current_user_can('administrator')) {
            wpb_set_post_views($post_id);
        }

        $count_key = '_post_views_count';
        $count = get_post_meta($post_id, $count_key, true);
        wp_send_json_success(array('count' => intval($count)));
    }

    wp_send_json_error();
}

add_action('wp_ajax_wpb_track_views', 'wpb_ajax_track_views');
add_action('wp_ajax_nopriv_wpb_track_views', 'wpb_ajax_track_views');

// JavaScript ve değişkenleri sayfaya ekle
function wpb_enqueue_view_tracker() {
    if (!is_single()) return;

    global $post;

    wp_enqueue_script(
        'wpb-view-tracker',
        get_template_directory_uri() . '/js/view-tracker.js',
        array('jquery'),
        '1.0.0',
        true
    );

    wp_localize_script('wpb-view-tracker', 'wpbViews', array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce'   => wp_create_nonce('wpb_views_nonce'),
        'postId'  => $post->ID
    ));
}

add_action('wp_enqueue_scripts', 'wpb_enqueue_view_tracker');

Temanda js/view-tracker.js dosyasını oluşturup şu kodu ekle:

// js/view-tracker.js

jQuery(document).ready(function($) {
    if (typeof wpbViews !== 'undefined') {
        $.ajax({
            url: wpbViews.ajaxUrl,
            type: 'POST',
            data: {
                action: 'wpb_track_views',
                post_id: wpbViews.postId,
                nonce: wpbViews.nonce
            },
            success: function(response) {
                if (response.success) {
                    // İsterseniz sayacı dinamik güncelleyebilirsiniz
                    console.log('Görüntülenme kaydedildi: ' + response.data.count);
                }
            }
        });
    }
});

Bu yaklaşımla sayfa önbellekten gelse bile JavaScript çalışacak ve AJAX isteği gönderilecek. Sayaç doğru şekilde artacak.

Adım 5: En Çok Okunan Yazıları Listeleme

View counter sisteminin en kullanışlı yanı, bu veriyi kullanarak “En Çok Okunanlar” widget’ı oluşturabilmek. Aşağıdaki fonksiyon, belirli bir dönem içinde en çok görüntülenen yazıları çekiyor:

// functions.php - En çok okunan yazılar

function wpb_get_most_viewed_posts($count = 5, $days = 0) {
    $args = array(
        'post_type'      => 'post',
        'post_status'    => 'publish',
        'posts_per_page' => $count,
        'meta_key'       => '_post_views_count',
        'orderby'        => 'meta_value_num',
        'order'          => 'DESC',
        'no_found_rows'  => true,  // Performans için
    );

    // Belirli gün aralığı filtresi
    if ($days > 0) {
        $args['date_query'] = array(
            array(
                'after'     => $days . ' days ago',
                'inclusive' => true,
            ),
        );
    }

    $query = new WP_Query($args);
    return $query;
}

// Shortcode olarak kullan: [most_viewed count="5"]
function wpb_most_viewed_shortcode($atts) {
    $atts = shortcode_atts(array(
        'count' => 5,
        'days'  => 0,
    ), $atts);

    $posts = wpb_get_most_viewed_posts(intval($atts['count']), intval($atts['days']));

    if (!$posts->have_posts()) {
        return '<p>Henüz görüntülenme verisi yok.</p>';
    }

    $output = '<ul class="most-viewed-posts">';

    while ($posts->have_posts()) {
        $posts->the_post();
        $views = get_post_meta(get_the_ID(), '_post_views_count', true);
        $output .= '<li>';
        $output .= '<a href="' . get_permalink() . '">' . get_the_title() . '</a>';
        $output .= ' <span class="view-count">(' . number_format(intval($views)) . ' görüntülenme)</span>';
        $output .= '</li>';
    }

    wp_reset_postdata();
    $output .= '</ul>';

    return $output;
}

add_shortcode('most_viewed', 'wpb_most_viewed_shortcode');

Bu shortcode’u herhangi bir sayfada veya widget alanında [most_viewed count="10"] şeklinde kullanabilirsin. Son 7 günün verilerini görmek için [most_viewed count="5" days="7"] yazman yeterli.

Adım 6: Admin Panelinde Görüntülenme Sütunu

Sayaç verilerini admin panelindeki yazı listesinde görmek büyük kolaylık sağlıyor. Hangi yazının daha fazla ilgi çektiğini tek bakışta anlarsın.

// functions.php - Admin yazı listesine görüntülenme sütunu ekle

// Sütun başlığını ekle
function wpb_add_views_column($columns) {
    $columns['post_views'] = 'Görüntülenme';
    return $columns;
}
add_filter('manage_posts_columns', 'wpb_add_views_column');

// Sütun içeriğini doldur
function wpb_show_views_column_content($column_name, $post_id) {
    if ($column_name === 'post_views') {
        $count = get_post_meta($post_id, '_post_views_count', true);
        echo '<strong>' . number_format(intval($count)) . '</strong>';
    }
}
add_action('manage_posts_custom_column', 'wpb_show_views_column_content', 10, 2);

// Sütuna göre sıralama özelliği ekle
function wpb_views_column_sortable($columns) {
    $columns['post_views'] = 'post_views';
    return $columns;
}
add_filter('manage_edit-posts_sortable_columns', 'wpb_views_column_sortable');

// Sıralama sorgusunu işle
function wpb_views_column_orderby($query) {
    if (!is_admin()) return;

    $orderby = $query->get('orderby');

    if ($orderby === 'post_views') {
        $query->set('meta_key', '_post_views_count');
        $query->set('orderby', 'meta_value_num');
    }
}
add_action('pre_get_posts', 'wpb_views_column_orderby');

Bu kodu ekledikten sonra Yazılar menüsünde yeni bir “Görüntülenme” sütunu göreceksin. Üstüne tıklayarak sıralama da yapabilirsin. Yoğun içerik üretenler için gerçekten hayat kurtarıcı.

Adım 7: Sayaç Verilerini Sıfırlama

Bazen tüm verileri sıfırlamak ya da belirli bir yazının sayacını resetlemek gerekebilir. Bunun için pratik bir fonksiyon:

// functions.php - Sayaç sıfırlama araçları

// Tek bir yazının sayacını sıfırla
function wpb_reset_post_views($post_id) {
    update_post_meta($post_id, '_post_views_count', 0);
}

// Tüm yazıların sayaçlarını sıfırla (dikkatli kullan!)
function wpb_reset_all_views() {
    // Sadece süper admin çalıştırabilsin
    if (!current_user_can('manage_options')) {
        return false;
    }

    $args = array(
        'post_type'      => 'post',
        'post_status'    => 'publish',
        'posts_per_page' => -1,
        'fields'         => 'ids',
        'no_found_rows'  => true,
    );

    $post_ids = get_posts($args);

    foreach ($post_ids as $post_id) {
        update_post_meta($post_id, '_post_views_count', 0);
    }

    return true;
}

// Admin menüsüne sıfırlama linki ekle (opsiyonel)
function wpb_add_reset_link() {
    if (isset($_GET['reset_all_views']) && $_GET['reset_all_views'] == '1') {
        if (current_user_can('manage_options')) {
            wpb_reset_all_views();
            add_action('admin_notices', function() {
                echo '<div class="notice notice-success"><p>Tüm görüntülenme sayaçları sıfırlandı.</p></div>';
            });
        }
    }
}
add_action('admin_init', 'wpb_add_reset_link');

Tüm sayaçları sıfırlamak için admin panelinde URL’ye ?reset_all_views=1 ekleyebilirsin. Ama bunu dikkatli kullan, geri alınamaz bir işlem.

Performans Optimizasyonu

Binlerce yazısı olan bir sitede view counter sorgularının yükünü hissetmeye başlayabilirsin. Birkaç öneri:

  • Transient kullan: En çok okunan yazılar listesini her sayfa yüklemesinde çekmek yerine, sonuçları 1 saat boyunca önbellekle.
  • no_found_rows kullan: WP_Query ile sorgu yaparken bu parametreyi true yap, sayfalama bilgisi gereksiz yere hesaplanmasın.
  • update_post_meta yerine doğrudan SQL: Çok yoğun sitelerde her istek için meta sorgusu yerine $wpdb ile doğrudan UPDATE çalıştırabilirsin. Bu yaklaşım daha hızlı ama daha az WordPress-uyumlu.
  • Bot filtrelemesi: Arama motoru botlarından gelen istekleri saymamak için $_SERVER['HTTP_USER_AGENT'] kontrolü ekleyebilirsin.
// Basit bot filtrelemesi

function wpb_is_bot() {
    $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';

    $bots = array(
        'Googlebot', 'Bingbot', 'Slurp', 'DuckDuckBot',
        'Baiduspider', 'YandexBot', 'facebookexternalhit',
        'Twitterbot', 'curl', 'wget'
    );

    foreach ($bots as $bot) {
        if (stripos($user_agent, $bot) !== false) {
            return true;
        }
    }

    return false;
}

Bu fonksiyonu wpb_set_post_views içinde çağırarak bot isteklerini sayaçtan dışlayabilirsin.

Gerçek Dünya Senaryosu: Haber Sitesi

Diyelim ki Türkçe bir teknoloji haber sitesi yönetiyorsun. Editörler hangi haberlerin viral olduğunu bilmek istiyor. View counter sistemi burada kritik.

Günde 50.000 sayfa görüntülenmesi olan bir sitede wp_head ile senkron sayaç artırmak sorun yaratabilir. Bu yüzden AJAX yöntemini tercih ediyorsun ve önbellekleme sisteminle uyumlu olması için JavaScript üzerinden tetikliyorsun.

Editörler sabah siteye girip “Görüntülenme” sütununa göre sıralıyor ve hangi haberin geceden beri ne kadar okunduğunu görüyor. Bu veriyle hangi konuların okuyucuyla daha çok buluştuğuna dair somut bir veri elde ediyorlar.

Ana sayfanın kenar çubuğunda [most_viewed count="5" days="1"] shortcode’u var, bu son 24 saatin en çok okunan 5 haberini gösteriyor. Okuyucular tıklıyor, site içi süre artıyor.

Güvenlik Notları

Bu sistemi kurarken göz ardı edilmemesi gereken birkaç güvenlik noktası var:

  • Nonce kullan: AJAX isteklerinde mutlaka nonce doğrulaması yapılmalı, yukarıdaki örnekte bunu dahil ettik.
  • intval() kullan: Post ID’yi işlerken her zaman intval() ile tamsayıya çevir.
  • Yetki kontrolü: Sayaç sıfırlama gibi kritik işlemlerde current_user_can() kontrolünü atlama.
  • Rate limiting düşün: Aynı IP’den gelen çok sayıda isteği sınırlandırmak için transient tabanlı basit bir rate limiter eklenebilir.

Sonuç

WordPress’te görüntülenme sayacı kurmak aslında sandığından çok daha basit. Birkaç fonksiyon, birkaç kanca ve işte kendi view counter sistemin hazır. Eklenti kurmak zorunda kalmıyorsun, veritabanında ekstra tablo açmıyorsun, WordPress’in kendi post meta altyapısını kullanıyorsun.

Özellikle önbellekleme kullanan siteler için AJAX yöntemini tercih etmeni kesinlikle öneririm. Hem daha güvenilir hem de önbellekleme sistemleriyle uyumlu çalışıyor.

Admin paneline eklediğin sıralama özelliği ve shortcode sistemi, bu kodu sadece teknik bir araç olmaktan çıkarıp içerik stratejisini destekleyen gerçek bir veri kaynağına dönüştürüyor. Hangi yazıların tuttuğunu, hangi konuların ilgi çektiğini artık sayılarla görebiliyorsun.

Kodu functions.php yerine bir eklenti olarak yapılandırmak da mümkün, bu şekilde tema değişikliğinde veriler kaybolmaz. Ama bu, ayrı bir yazının konusu.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir