WordPress İçerik Sonrasına Otomatik İçerik Ekleme

WordPress siteni yönetirken er ya da geç şu ihtiyaçla karşılaşırsın: her yazının altına otomatik olarak bir şeyler eklemek istiyorsun. Belki bir yazar biyografisi, belki bir ürün tanıtımı, belki sadece sosyal medya paylaşım butonları. Bunu her yazıya elle eklemek hem zaman kaybı hem de bakımı imkansız bir kabus. İşte the_content filtresi tam burada devreye giriyor ve functions.php dosyandan birkaç satır kodla bu işi tamamen otomatikleştirebiliyorsun.

the_content Filtresi Nedir ve Nasıl Çalışır?

WordPress içerik sistemi, veritabanından çekilen ham içeriği ekrana basmadan önce bir dizi filtreden geçirir. Bu filtre zincirinin en önemli halkalarından biri the_content filtresidir. add_filter() fonksiyonu ile bu zincire kendi fonksiyonunu ekleyebilir, içeriği almadan önce ya da sonra istediğin şeyi yapıştırabilirsin.

Temel mantık şu şekilde işliyor:

add_filter( 'the_content', 'benim_fonksiyonum' );

function benim_fonksiyonum( $content ) {
    // $content mevcut yazı içeriği
    // İçeriğin sonuna bir şeyler ekle
    $ek = '<p>Bu ek içeriktir.</p>';
    return $content . $ek;
}

$content değişkeni tüm işlenmiş HTML içeriğini taşıyor. Bunu alıp sonuna, başına ya da ortasına istediğini ekleyebilirsin. Filtreye verdiğin fonksiyon mutlaka değiştirilmiş $content‘i geri döndürmelidir, yoksa sayfa boş gelir.

Dikkat Edilmesi Gereken Temel Noktalar

Koda geçmeden önce bazı kritik detayları konuşmamız lazım. Bu noktaları atlarsanız içerik hem ana sayfada hem kategori sayfalarında hem de RSS beslemelerinde görünür, bu da genellikle istemediğiniz bir durumdur.

is_single() kontrolü: Eklediğin içeriğin sadece tekil yazı sayfalarında görünmesini istiyorsan bu kontrolü mutlaka yapmalısın.

is_main_query() kontrolü: WordPress bazen aynı sayfada birden fazla sorgu çalıştırır. Ana sorgu olmayan döngülerde de filtrenin tetiklenmesini engellemek için bu kontrol önemlidir.

in_the_loop() kontrolü: Filtrenin sadece döngü içindeyken çalışmasını sağlar. Widget’lar veya kısa kodlarla çağrılan içeriklerde istenmeyen sonuçları önler.

Post type kontrolü: Belki sadece yazılara eklemek istiyorsun, sayfalara değil. get_post_type() ile bunu kontrol edebilirsin.

Temel Kullanım Örnekleri

1. Her Yazının Altına Sabit Metin Ekleme

En basit senaryo: tüm yazıların altına aynı metni eklemek.

add_filter( 'the_content', 'yazinin_altina_metin_ekle' );

function yazinin_altina_metin_ekle( $content ) {
    if ( is_single() && is_main_query() && in_the_loop() ) {
        $ek = '<div class="yazi-alt-notu">';
        $ek .= '<p><strong>Not:</strong> Bu yazıdaki bilgiler düzenli olarak güncellenmektedir. ';
        $ek .= 'En güncel bilgi için bültene abone olmayı unutma.</p>';
        $ek .= '</div>';
        
        $content = $content . $ek;
    }
    
    return $content;
}

2. Yazar Biyografisi Kutusu Ekleme

Çok yazarlı bir blog yönetiyorsan bu kod her yazının altına o yazıya ait yazar bilgilerini otomatik olarak ekler.

add_filter( 'the_content', 'yazar_biyografisi_ekle' );

function yazar_biyografisi_ekle( $content ) {
    if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) {
        return $content;
    }
    
    $yazar_id     = get_the_author_meta( 'ID' );
    $yazar_adi    = get_the_author_meta( 'display_name' );
    $yazar_bio    = get_the_author_meta( 'description' );
    $yazar_url    = get_author_posts_url( $yazar_id );
    $avatar       = get_avatar( $yazar_id, 80 );
    
    if ( empty( $yazar_bio ) ) {
        return $content;
    }
    
    $kutu  = '<div class="yazar-kutusu" style="border:1px solid #ddd; padding:20px; margin-top:30px; border-radius:8px;">';
    $kutu .= '<div style="display:flex; align-items:center; gap:15px;">';
    $kutu .= $avatar;
    $kutu .= '<div>';
    $kutu .= '<h4 style="margin:0 0 8px;">' . esc_html( $yazar_adi ) . '</h4>';
    $kutu .= '<p style="margin:0 0 10px;">' . esc_html( $yazar_bio ) . '</p>';
    $kutu .= '<a href="' . esc_url( $yazar_url ) . '">Tüm yazıları gör &rarr;</a>';
    $kutu .= '</div></div></div>';
    
    return $content . $kutu;
}

3. Belirli Kategorilere Göre İçerik Ekleme

Diyelim ki sadece “teknoloji” kategorisindeki yazıların altına “ilgili ürünler” bölümü eklemek istiyorsun. Bu senaryo e-ticaret sitelerinde çok işe yarar.

add_filter( 'the_content', 'kategori_bazli_icerik_ekle' );

function kategori_bazli_icerik_ekle( $content ) {
    if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) {
        return $content;
    }
    
    // Yazının belirli kategoride olup olmadığını kontrol et
    $hedef_kategoriler = array( 'teknoloji', 'yazilim', 'donanim' );
    
    if ( in_category( $hedef_kategoriler ) ) {
        $ek  = '<div class="ilgili-urunler-banner">';
        $ek .= '<h3>Bu Konuyla İlgili Ürünlerimiz</h3>';
        $ek .= '<p>Teknoloji alanında ihtiyaç duyduğun her şey mağazamızda seni bekliyor.</p>';
        $ek .= '<a href="/magaza" class="buton">Mağazaya Git</a>';
        $ek .= '</div>';
        
        $content .= $ek;
    }
    
    return $content;
}

4. Yazı Başına ve Sonuna Aynı Anda Ekleme

Bazen içeriğin hem başına hem sonuna bir şeyler eklemen gerekir. Örneğin üstte bir uyarı kutusu, altta ise paylaşım butonları.

add_filter( 'the_content', 'icerik_ust_alt_ekle' );

function icerik_ust_alt_ekle( $content ) {
    if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) {
        return $content;
    }
    
    // Üste eklenecek uyarı kutusu
    $ust_ek  = '<div class="icerik-uyari" style="background:#fff3cd; border:1px solid #ffc107; ';
    $ust_ek .= 'padding:12px; border-radius:4px; margin-bottom:20px;">';
    $ust_ek .= '<strong>Okuma süresi:</strong> ' . okuma_suresi_hesapla( $content ) . ' dakika';
    $ust_ek .= '</div>';
    
    // Alta eklenecek paylaşım bölümü
    $paylasim_url   = urlencode( get_permalink() );
    $paylasim_baslik = urlencode( get_the_title() );
    
    $alt_ek  = '<div class="paylasim-butonlari" style="margin-top:30px; padding-top:20px; border-top:1px solid #eee;">';
    $alt_ek .= '<p><strong>Bu yazıyı paylaş:</strong></p>';
    $alt_ek .= '<a href="https://twitter.com/intent/tweet?url=' . $paylasim_url . '&text=' . $paylasim_baslik . '" ';
    $alt_ek .= 'target="_blank" rel="noopener" style="margin-right:10px;">Twitter</a>';
    $alt_ek .= '<a href="https://www.linkedin.com/sharing/share-offsite/?url=' . $paylasim_url . '" ';
    $alt_ek .= 'target="_blank" rel="noopener">LinkedIn</a>';
    $alt_ek .= '</div>';
    
    return $ust_ek . $content . $alt_ek;
}

// Yardımcı fonksiyon: okuma süresi hesapla
function okuma_suresi_hesapla( $content ) {
    $kelime_sayisi = str_word_count( strip_tags( $content ) );
    $dakika        = ceil( $kelime_sayisi / 200 );
    return $dakika;
}

5. Post Type’a Göre Özelleştirilmiş İçerik

Eğer WooCommerce veya özel post type’larla çalışıyorsan, filtreni çok daha spesifik hale getirmen gerekir.

add_filter( 'the_content', 'post_type_bazli_icerik_ekle' );

function post_type_bazli_icerik_ekle( $content ) {
    if ( ! in_the_loop() || ! is_main_query() ) {
        return $content;
    }
    
    $post_type = get_post_type();
    
    // Sadece normal blog yazılarına ekle
    if ( 'post' === $post_type && is_single() ) {
        $etiketler = get_the_tags();
        
        if ( $etiketler ) {
            $etiket_listesi = '<div class="yazi-etiketleri" style="margin-top:25px;">';
            $etiket_listesi .= '<strong>Etiketler: </strong>';
            
            foreach ( $etiketler as $etiket ) {
                $etiket_listesi .= '<a href="' . esc_url( get_tag_link( $etiket->term_id ) ) . '" ';
                $etiket_listesi .= 'style="display:inline-block; background:#f0f0f0; padding:3px 10px; ';
                $etiket_listesi .= 'margin:3px; border-radius:3px; text-decoration:none;">';
                $etiket_listesi .= esc_html( $etiket->name );
                $etiket_listesi .= '</a>';
            }
            
            $etiket_listesi .= '</div>';
            $content .= $etiket_listesi;
        }
    }
    
    // Portfolyo yazılarına farklı bir şey ekle
    if ( 'portfolio' === $post_type ) {
        $iletisim_kutusu  = '<div class="portfolyo-iletisim" style="background:#f8f9fa; padding:25px; margin-top:30px; text-align:center;">';
        $iletisim_kutusu .= '<h3>Bu proje hakkında konuşalım</h3>';
        $iletisim_kutusu .= '<p>Benzer bir proje için iletişime geçmekten çekinme.</p>';
        $iletisim_kutusu .= '<a href="/iletisim" class="buton">İletişim Formu</a>';
        $iletisim_kutusu .= '</div>';
        $content         .= $iletisim_kutusu;
    }
    
    return $content;
}

6. Dinamik İçerik: İlgili Yazıları Listeleme

Bu biraz daha gelişmiş bir senaryo. Her yazının altına aynı kategoriden ilgili yazıları otomatik olarak çeken bir kod bloğu.

add_filter( 'the_content', 'ilgili_yazilari_ekle' );

function ilgili_yazilari_ekle( $content ) {
    if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) {
        return $content;
    }
    
    global $post;
    
    $kategoriler = wp_get_post_categories( $post->ID );
    
    if ( empty( $kategoriler ) ) {
        return $content;
    }
    
    $ilgili_query = new WP_Query( array(
        'category__in'   => $kategoriler,
        'posts_per_page' => 3,
        'post__not_in'   => array( $post->ID ),
        'orderby'        => 'rand',
        'no_found_rows'  => true, // performans için
    ) );
    
    if ( ! $ilgili_query->have_posts() ) {
        return $content;
    }
    
    $ilgili_html  = '<div class="ilgili-yazilar" style="margin-top:40px; padding:25px; background:#f9f9f9; border-radius:8px;">';
    $ilgili_html .= '<h3 style="margin-top:0;">İlgili Yazılar</h3>';
    $ilgili_html .= '<ul style="list-style:none; padding:0; margin:0;">';
    
    while ( $ilgili_query->have_posts() ) {
        $ilgili_query->the_post();
        $ilgili_html .= '<li style="padding:10px 0; border-bottom:1px solid #eee;">';
        $ilgili_html .= '<a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a>';
        $ilgili_html .= '<span style="color:#999; font-size:0.85em; margin-left:10px;">';
        $ilgili_html .= get_the_date();
        $ilgili_html .= '</span>';
        $ilgili_html .= '</li>';
    }
    
    $ilgili_html .= '</ul></div>';
    
    wp_reset_postdata();
    
    return $content . $ilgili_html;
}

7. Kullanıcı Rolüne Göre İçerik Ekleme

Abonelik sistemi ya da üyelik tabanlı bir site yönetiyorsan bu pattern çok işe yarar. Giriş yapmamış kullanıcılara farklı, giriş yapmışlara farklı içerik gösterebilirsin.

add_filter( 'the_content', 'kullanici_rolune_gore_ek_icerik' );

function kullanici_rolune_gore_ek_icerik( $content ) {
    if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) {
        return $content;
    }
    
    // Giriş yapmamış kullanıcılar için
    if ( ! is_user_logged_in() ) {
        $giris_kutusu  = '<div class="abone-cagri" style="background:linear-gradient(135deg, #667eea, #764ba2); ';
        $giris_kutusu .= 'color:white; padding:30px; margin-top:30px; border-radius:10px; text-align:center;">';
        $giris_kutusu .= '<h3 style="color:white; margin-top:0;">Daha Fazlası İçin Üye Ol</h3>';
        $giris_kutusu .= '<p>Tüm içeriklere erişmek için ücretsiz üye olabilirsin.</p>';
        $giris_kutusu .= '<a href="' . esc_url( wp_registration_url() ) . '" ';
        $giris_kutusu .= 'style="background:white; color:#764ba2; padding:10px 25px; ';
        $giris_kutusu .= 'border-radius:5px; text-decoration:none; font-weight:bold;">Ücretsiz Üye Ol</a>';
        $giris_kutusu .= '</div>';
        
        return $content . $giris_kutusu;
    }
    
    // Giriş yapmış ama subscriber rolündeki kullanıcılar için
    $kullanici        = wp_get_current_user();
    $kullanici_roller = $kullanici->roles;
    
    if ( in_array( 'subscriber', $kullanici_roller ) ) {
        $upgrade_notu  = '<div class="premium-cagri" style="border:2px solid #f39c12; padding:20px; margin-top:25px; border-radius:8px;">';
        $upgrade_notu .= '<p><strong>Premium üyelere özel içeriklerimizi keşfetmek ister misin?</strong></p>';
        $upgrade_notu .= '<a href="/premium">Premium Üye Ol</a>';
        $upgrade_notu .= '</div>';
        
        return $content . $upgrade_notu;
    }
    
    return $content;
}

Performans İpuçları

Bu filtreyi kullanırken performansı da göz önünde bulundurman lazım. Özellikle veritabanı sorgusu yapan fonksiyonlar her sayfa yüklemesinde çalışacak.

Geçici önbellekleme kullanmak: get_transient() ve set_transient() ile sorgu sonuçlarını önbelleğe alabilirsin.

no_found_rows parametresi: WP_Query kullanırken bu parametreyi true yap. WordPress’in toplam sayfa sayısını hesaplamamasını sağlar ve gereksiz bir SQL sorgusu engellenir.

Erken çıkış yapmak: Koşulları fonksiyonun en başında kontrol et ve şart sağlanmıyorsa hemen return $content yap. Bu sayede gereksiz işlemlerden kaçınırsın.

Inline style yerine CSS kullanmak: Örneklerde inline style kullandım ki direkt çalışsın, ama production ortamında stilleri ayrı bir CSS dosyasına taşıman hem performans hem de bakım açısından daha iyidir.

Yaygın Hatalar ve Çözümleri

İçerik iki kez görünüyor: Bu durumun en sık nedeni is_main_query() veya in_the_loop() kontrollerinin yapılmamasıdır. Widget’lar veya kısa kodlar da the_content filtresini tetikleyebilir.

Ana sayfada da görünüyor: is_single() veya is_singular('post') kontrolü eksiktir. Ana sayfa döngüsü de the_content filtresini kullanır.

RSS beslemesinde bozuk görünüyor: RSS’te HTML görselliği desteklenmez. is_feed() ile RSS kontrolü yaparak RSS’te farklı veya hiç ek gösterme.

WooCommerce ürün sayfalarında çakışma: Ürün açıklamaları da the_content filtresinden geçer. get_post_type() !== 'product' kontrolü ile bunu engelleyebilirsin.

add_filter( 'the_content', 'guvenli_icerik_ekleme' );

function guvenli_icerik_ekleme( $content ) {
    // Tüm kontrolleri bir arada yap
    if ( 
        ! is_single() ||
        ! in_the_loop() ||
        ! is_main_query() ||
        is_feed() ||
        'product' === get_post_type()
    ) {
        return $content;
    }
    
    $ek = '<p class="yazi-sonu-notu">İçeriğimizi beğendiysen bültene abone ol!</p>';
    
    return $content . $ek;
}

Child Theme’de Kullanım

Bu kodların tamamını child theme’inin functions.php dosyasına eklemelisin. Neden child theme? Çünkü ana tema güncellendiğinde yaptığın değişiklikler silinir. Child theme kullanmıyorsan, en azından bir eklenti oluşturmayı ya da Code Snippets gibi bir eklenti kullanmayı düşünebilirsin.

functions.php dosyasını düzenlerken dikkat etmen gereken bir nokak daha var: PHP syntax hatası tüm siteyi çökertebilir. Bu yüzden değişiklikleri yapmadan önce bir yedeğini al ve mümkünse önce geliştirme ortamında test et.

Gelişmiş senaryolarda birden fazla add_filter() çağrısı yapman gerekebilir. Bu durumda öncelik sırasını add_filter() fonksiyonunun dördüncü parametresiyle ayarlayabilirsin. Varsayılan değer 10’dur; daha düşük değer daha önce, daha yüksek değer daha sonra çalışır anlamına gelir.

// Bu fonksiyon önce çalışır (öncelik: 5)
add_filter( 'the_content', 'once_calisacak_fonksiyon', 5 );

// Bu sonra çalışır (öncelik: 20)
add_filter( 'the_content', 'sonra_calisacak_fonksiyon', 20 );

Sonuç

the_content filtresi, WordPress’in en güçlü ve esnek araçlarından biri. Yazar biyografilerinden ilgili yazı listelerine, kullanıcı rolü bazlı içeriklerden kategori özelleştirmelerine kadar akla gelebilecek her türlü dinamik içerik eklemeyi bu tek filtre üzerinden halledebilirsin. Eklenti kurmak yerine functions.php’ye birkaç satır kod ekleyerek hem sitenin ağırlığını azaltmış hem de tam istediğin şekilde çalışan bir sisteme kavuşmuş olursun.

En önemli nokta her zaman üç güvenlik kontrolünü yapmak: is_single(), is_main_query() ve in_the_loop(). Bu üçü yerindeyse beklenmedik yerlerде içerik belirmesi sorunuyla karşılaşmazsın. Performans için sorgu yapan fonksiyonlarda transient cache kullan ve WP_Query‘de no_found_rows parametresini unutma.

Kod yazmaya başlamadan önce tam olarak ne istediğini belirle, post type’ını tanımla, hangi sayfalarda görünmeli görünmemeli karar ver ve ona göre koşullarını yaz. Geri kalanı zaten bu örneklerde mevcut.

Bir yanıt yazın

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