WooCommerce Sepet Tablosunun Üzerine İçerik Ekleme

WooCommerce mağazanızda sepet sayfası, müşterilerin satın alma kararını verdiği kritik noktalardan biridir. Buraya doğru zamanda doğru mesajı yerleştirmek, hem dönüşüm oranlarını artırır hem de müşteri deneyimini iyileştirir. Bu yazıda, WooCommerce sepet tablosunun üzerine ve altına nasıl içerik ekleyebileceğinizi, bunu functions.php üzerinden hook’larla nasıl yönetebileceğinizi gerçek dünya senaryolarıyla birlikte ele alacağız.

WooCommerce Sepet Hook Sistemi Nasıl Çalışır?

WooCommerce, sepet sayfasını render ederken bir dizi action hook ateşler. Bu hook’lar sayesinde PHP kodunuzu sayfanın belirli noktalarına enjekte edebilirsiniz. functions.php dosyanıza yazdığınız fonksiyonları bu hook’lara bağladığınızda, ne bir şablonu kopyalamanız ne de bir eklenti kurmanız gerekir.

Sepet tablosunun üzerinde çalışan temel hook şudur: woocommerce_before_cart_table. Bu hook, ürünlerin listelendiği

etiketinden hemen önce tetiklenir. Yani buraya eklediğiniz içerik, müşterinin ürün listesini görmeden önce gözüne çarpar.

Bir de bunun tam tersi olan woocommerce_after_cart_table hook’u vardır; tablo bittikten sonra devreye girer. Bu ikisinin yanı sıra woocommerce_before_cart ve woocommerce_after_cart gibi daha geniş kapsamlı hook’lar da mevcuttur. Ama biz bu yazıda özellikle tablo üzerine içerik eklemeye odaklanacağız.

Temel Kullanım: İlk Hook Bağlantısı

En sade haliyle bir duyuru mesajı eklemek için şu kodu functions.php‘ye yapıştırmanız yeterlidir:

add_action( 'woocommerce_before_cart_table', 'ozel_sepet_duyurusu' );

function ozel_sepet_duyurusu() {
    echo '<div class="sepet-duyuru" style="background:#fff3cd; padding:12px 16px; margin-bottom:16px; border-left:4px solid #ffc107; border-radius:4px;">';
    echo '<strong>Dikkat!</strong> Bugün verilen siparişler yarın kargoya verilecektir.';
    echo '</div>';
}

Bu kadar basit. Sayfayı yenilediğinizde sepet tablosunun hemen üzerinde sarı bir bilgi kutusu belirecektir. Ama tabii bu sadece başlangıç.

Senaryo 1: Ücretsiz Kargo Hedef Göstergesi

En yaygın kullanım senaryolarından biri, müşteriye “Şu kadar daha harca, ücretsiz kargoya ulaş” mesajı göstermektir. Bu hem sepeti terk etme oranını düşürür hem de ortalama sipariş değerini artırır.

add_action( 'woocommerce_before_cart_table', 'ucretsiz_kargo_ilerleme_cubugu' );

function ucretsiz_kargo_ilerleme_cubugu() {
    $ucretsiz_kargo_limiti = 500; // TL cinsinden limit
    $sepet_toplami = WC()->cart->get_cart_contents_total();
    $kalan = $ucretsiz_kargo_limiti - $sepet_toplami;

    if ( $kalan <= 0 ) {
        echo '<div class="kargo-mesaj basarili" style="background:#d4edda; padding:12px 16px; margin-bottom:16px; border-left:4px solid #28a745; border-radius:4px;">';
        echo '<strong>Tebrikler!</strong> Ücretsiz kargo kazandınız.';
        echo '</div>';
    } else {
        $yuzde = ( $sepet_toplami / $ucretsiz_kargo_limiti ) * 100;
        $yuzde = min( $yuzde, 100 );
        $kalan_formatted = wc_price( $kalan );

        echo '<div class="kargo-mesaj" style="background:#e8f4fd; padding:12px 16px; margin-bottom:16px; border-left:4px solid #007bff; border-radius:4px;">';
        echo '<p style="margin:0 0 8px 0;">Ücretsiz kargo için <strong>' . $kalan_formatted . '</strong> daha alışveriş yapın!</p>';
        echo '<div style="background:#c8e6f7; border-radius:4px; height:10px;">';
        echo '<div style="background:#007bff; width:' . esc_attr( $yuzde ) . '%; height:10px; border-radius:4px; transition:width 0.3s;"></div>';
        echo '</div>';
        echo '</div>';
    }
}

Bu fonksiyon WC()->cart->get_cart_contents_total() metoduyla anlık sepet toplamını çeker. Limit aşıldıysa yeşil kutuda tebrik mesajı, aşılmadıysa mavi kutuda eksik tutarı ve ilerleme çubuğunu gösterir. Gerçek projelerde bu limiti sabit yazmak yerine WooCommerce ayarlarından dinamik olarak çekmek daha temiz olur.

Senaryo 2: Belirli Ürünler Sepette Varsa Uyarı Göster

Diyelim ki bazı ürünleriniz kombine kullanılamaz ya da belirli bir ürün sepete girdiğinde özel bir mesaj göstermek istiyorsunuz. Örneğin “Bu ürün soğuk zincir gerektirir, aynı gün teslimat geçerlidir” gibi bir uyarı:

add_action( 'woocommerce_before_cart_table', 'soguk_zincir_uyarisi' );

function soguk_zincir_uyarisi() {
    $soguk_zincir_kategori = 'soguk-urunler'; // Kategori slug
    $uyari_goster = false;

    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $urun_id = $cart_item['product_id'];
        if ( has_term( $soguk_zincir_kategori, 'product_cat', $urun_id ) ) {
            $uyari_goster = true;
            break;
        }
    }

    if ( $uyari_goster ) {
        echo '<div class="soguk-zincir-uyari" style="background:#fff0f0; padding:14px 16px; margin-bottom:16px; border-left:4px solid #dc3545; border-radius:4px;">';
        echo '<strong>Soğuk Zincir Ürünü Mevcut</strong><br>';
        echo 'Sepetinizde soğuk zincir gerektiren ürün bulunmaktadır. Bu ürünler yalnızca aynı gün teslimat seçeneğiyle gönderilebilir.';
        echo '</div>';
    }
}

Bu örnekte WC()->cart->get_cart() ile tüm sepet öğeleri döngüye alınır ve her birinin belirtilen kategoride olup olmadığı kontrol edilir. has_term() fonksiyonu WordPress’in standart taxonomy kontrolü yaptığı için güvenilir çalışır.

Senaryo 3: Oturum Açmamış Kullanıcılara Giriş Teşviki

Misafir kullanıcılar genellikle kayıt avantajlarından habersiz olur. Sepet sayfasına küçük bir hatırlatma eklemek kayıt dönüşümlerini ciddi ölçüde artırabilir:

add_action( 'woocommerce_before_cart_table', 'misafir_kullanici_giris_mesaji' );

function misafir_kullanici_giris_mesaji() {
    if ( is_user_logged_in() ) {
        return; // Giriş yapmışsa hiçbir şey gösterme
    }

    $giris_url   = wc_get_page_permalink( 'myaccount' );
    $kayit_url   = wc_get_page_permalink( 'myaccount' ) . '?action=register';

    echo '<div class="misafir-mesaj" style="background:#f8f0ff; padding:14px 16px; margin-bottom:16px; border-left:4px solid #6f42c1; border-radius:4px; display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:10px;">';
    echo '<span><strong>Üye misiniz?</strong> Giriş yaparak özel indirimlerden ve hızlı ödeme avantajından yararlanın.</span>';
    echo '<span>';
    echo '<a href="' . esc_url( $giris_url ) . '" style="background:#6f42c1; color:#fff; padding:6px 14px; border-radius:4px; text-decoration:none; margin-right:6px;">Giriş Yap</a>';
    echo '<a href="' . esc_url( $kayit_url ) . '" style="background:#fff; color:#6f42c1; padding:6px 14px; border-radius:4px; text-decoration:none; border:1px solid #6f42c1;">Üye Ol</a>';
    echo '</span>';
    echo '</div>';
}

is_user_logged_in() kontrolü sayesinde bu mesaj sadece misafir kullanıcılara gösterilir. wc_get_page_permalink() ile WooCommerce sayfalarının URL’lerini dinamik olarak alıyoruz; böylece sayfa slug’ı değişse de bağlantılar bozulmuyor.

Senaryo 4: Kupon Hatırlatması ve Aktif Kupon Bilgisi

Kullanıcı kupon uygulamışsa bunu vurgulayabilir, uygulamadıysa hatırlatabilirsiniz:

add_action( 'woocommerce_before_cart_table', 'kupon_durum_bildirimi' );

function kupon_durum_bildirimi() {
    $uygulanan_kuponlar = WC()->cart->get_applied_coupons();

    if ( ! empty( $uygulanan_kuponlar ) ) {
        $kupon_listesi = implode( ', ', array_map( 'strtoupper', $uygulanan_kuponlar ) );
        $toplam_indirim = WC()->cart->get_discount_total();

        echo '<div class="kupon-aktif" style="background:#d4edda; padding:12px 16px; margin-bottom:16px; border-left:4px solid #28a745; border-radius:4px;">';
        echo '<strong>Kupon Uygulandı:</strong> ' . esc_html( $kupon_listesi );
        echo ' &nbsp;|&nbsp; <strong>İndirim:</strong> ' . wc_price( $toplam_indirim );
        echo '</div>';
    } else {
        echo '<div class="kupon-hatirlatma" style="background:#fff8e1; padding:12px 16px; margin-bottom:16px; border-left:4px solid #ff9800; border-radius:4px;">';
        echo 'Bir <strong>indirim kodunuz</strong> var mı? Sayfanın altındaki kupon alanını kullanmayı unutmayın!';
        echo '</div>';
    }
}

Bu örnek hem pozitif geri bildirim (kupon uygulandı, şu kadar kazandın) hem de teşvik edici hatırlatma işlevi görüyor. get_applied_coupons() boş array döndürürse hatırlatma kutusunu, dolu döndürürse aktif kupon bilgisini gösteriyoruz.

Senaryo 5: Zaman Bazlı Flaş Satış Sayacı

Belirli saatler arasında indirim uyguluyorsanız ya da sepetin fiyatlarını belirli bir süreyle kilitlediniz, bunu bir geri sayım sayacıyla vurgulayabilirsiniz:

add_action( 'woocommerce_before_cart_table', 'flash_satis_sayaci' );

function flash_satis_sayaci() {
    // Flaş satışın bitiş tarihi (Unix timestamp)
    $bitis_tarihi = strtotime( 'today 23:59:59' );
    $simdi        = time();

    if ( $simdi >= $bitis_tarihi ) {
        return; // Süre bitmişse gösterme
    }

    $kalan_saniye = $bitis_tarihi - $simdi;
    $saat         = floor( $kalan_saniye / 3600 );
    $dakika       = floor( ( $kalan_saniye % 3600 ) / 60 );
    $saniye       = $kalan_saniye % 60;

    echo '<div class="flash-satis" style="background:#1a1a2e; color:#fff; padding:14px 16px; margin-bottom:16px; border-radius:4px; text-align:center;">';
    echo '<strong style="color:#ffd700;">BUGÜNKÜ FİYATLAR SADECE BU GECE GEÇERLİ!</strong>';
    echo '<div style="font-size:1.4em; margin-top:6px; letter-spacing:2px; font-family:monospace;">';
    printf( '%02d:%02d:%02d', $saat, $dakika, $saniye );
    echo '</div>';
    echo '<small style="opacity:0.8;">Fırsatı kaçırmayın, sepetinizdeki ürünlerin fiyatları gece yarısı değişebilir.</small>';
    echo '</div>';
}

Burada dikkat edilmesi gereken nokta: PHP tarafında hesaplanan bu süre statik bir görüntü üretir. Sayacın gerçek zamanlı azalması için sayfada JavaScript ile setInterval kullanmanız gerekir. Bu kodu basit tutmak adına yalnızca PHP kısmını yazdım, ancak üretim ortamında sayacı JS ile canlandırmanızı öneririm.

Priority Parametresiyle Sıralama Kontrolü

Birden fazla fonksiyon aynı hook’a bağlandığında hangisinin önce çalışacağını priority parametresiyle belirlersiniz. Düşük sayı önce çalışır, varsayılan değer 10’dur:

// Bu önce çalışır (priority: 5)
add_action( 'woocommerce_before_cart_table', 'kargo_bilgisi_goster', 5 );

// Bu sonra çalışır (priority: 15)
add_action( 'woocommerce_before_cart_table', 'kupon_hatirlatma_goster', 15 );

function kargo_bilgisi_goster() {
    echo '<div class="bilgi-kutu" style="background:#e8f5e9; padding:12px 16px; margin-bottom:10px; border-radius:4px;">';
    echo 'Siparişiniz <strong>en hızlı 1-3 iş günü</strong> içinde teslim edilir.';
    echo '</div>';
}

function kupon_hatirlatma_goster() {
    if ( empty( WC()->cart->get_applied_coupons() ) ) {
        echo '<div class="bilgi-kutu" style="background:#e3f2fd; padding:12px 16px; margin-bottom:16px; border-radius:4px;">';
        echo 'İndirim kodunuzu aşağıdaki alana girerek tasarruf edin!';
        echo '</div>';
    }
}

Bu örnekte kargo bilgisi her zaman kupon hatırlatmasının üstünde görünür.

Güvenlik ve Performans Notları

Sepet sayfasına içerik eklerken göz ardı edilmemesi gereken birkaç kritik nokta var.

Çıktıyı her zaman escape edin: Veritabanından ya da kullanıcı girdisinden gelen herhangi bir değeri ekrana basmadan önce esc_html(), esc_url() veya wp_kses() fonksiyonlarından geçirin. Aksi halde XSS açığı yaratırsınız.

WC()->cart kontrolü yapın: is_cart() ile sepet sayfasında olduğunuzu doğrulamak, hook zaten sepet sayfasına özgü olsa bile gereksiz nesne çağrısını önler.

Nesne önbelleği kullanın: WC()->cart->get_cart_contents_total() gibi metodları tek bir değişkene atayın ve aynı fonksiyon içinde birden fazla kez çağırmaktan kaçının.

Koşullu yükleme yapmayı düşünün:

add_action( 'woocommerce_before_cart_table', 'guvenli_sepet_mesaji' );

function guvenli_sepet_mesaji() {
    // Sepet sayfası değilse çık
    if ( ! is_cart() ) {
        return;
    }

    // Sepet boşsa gösterme
    if ( WC()->cart->is_empty() ) {
        return;
    }

    $toplam = floatval( WC()->cart->get_cart_contents_total() );

    echo '<div class="guvenli-odeme" style="background:#f0f4ff; padding:12px 16px; margin-bottom:16px; border-radius:4px;">';
    echo '<strong>Güvenli Alışveriş:</strong> Tüm ödemeler SSL ile şifrelenmektedir.';
    echo '</div>';
}

CSS ile Daha Profesyonel Görünüm

Inline style yazmak hızlı prototipleme için iyidir ama uzun vadede CSS dosyanıza ya da temanın style.css‘ine taşımanız gerekir. wp_enqueue_scripts hook’unu kullanarak sadece sepet sayfasında CSS yükleyebilirsiniz:

add_action( 'wp_enqueue_scripts', 'sepet_ozel_css_yukle' );

function sepet_ozel_css_yukle() {
    if ( ! is_cart() ) {
        return;
    }

    $ozel_css = "
        .sepet-bilgi-kutu {
            padding: 12px 16px;
            margin-bottom: 16px;
            border-radius: 6px;
            font-size: 0.95em;
            line-height: 1.5;
        }
        .sepet-bilgi-kutu.mavi { background: #e8f4fd; border-left: 4px solid #007bff; }
        .sepet-bilgi-kutu.yesil { background: #d4edda; border-left: 4px solid #28a745; }
        .sepet-bilgi-kutu.sari { background: #fff3cd; border-left: 4px solid #ffc107; }
        .sepet-bilgi-kutu.kirmizi { background: #fff0f0; border-left: 4px solid #dc3545; }
        .kargo-progress-bar { background: #dee2e6; border-radius: 4px; height: 10px; margin-top: 8px; }
        .kargo-progress-bar-dolgu { background: #007bff; height: 10px; border-radius: 4px; transition: width 0.4s ease; }
    ";

    wp_add_inline_style( 'woocommerce-general', $ozel_css );
}

Böylece bu CSS sınıflarını HTML çıktılarınızda kullanabilirsiniz. wp_add_inline_style(), belirtilen handle’ın CSS dosyasının hemen ardından bu stilleri sayfaya ekler; ayrı bir etiketi açmanıza gerek kalmaz.

Child Theme’de Kullanım

Tüm bu kodları doğrudan ana temanın functions.php‘sine yazmak tehlikelidir çünkü tema güncellendiğinde her şey silinir. Mutlaka bir child theme oluşturun ya da mu-plugins dizininde ayrı bir dosya kullanın.

Child theme functions.php yapısı şu şekilde olmalıdır:

<?php
/**
 * Child Theme Functions
 * WooCommerce Sepet Özelleştirmeleri
 */

// Parent theme fonksiyonlarını yükle
add_action( 'wp_enqueue_scripts', 'child_theme_styles' );
function child_theme_styles() {
    wp_enqueue_style(
        'parent-style',
        get_template_directory_uri() . '/style.css'
    );
}

// Sepet özelleştirmeleri burada başlıyor
require_once get_stylesheet_directory() . '/inc/sepet-ozellikler.php';

Sepet kodlarını inc/sepet-ozellikler.php gibi ayrı bir dosyaya taşıyarak functions.php‘yi şişirmekten kaçınabilirsiniz. Bu hem bakımı kolaylaştırır hem de ekip içinde kodun nerede olduğunu bulmayı hızlandırır.

Debugging ve Test

Kodunuzu yayına almadan önce birkaç senaryoyu test edin:

  • Boş sepet: Mesajlar boş sepette de görünüyor mu?
  • Sadece ücretsiz ürünler: Toplam sıfırken ilerleme çubuğu nasıl davranıyor?
  • Çok sayıda ürün: Onlarca ürünle sepet döngüsü yavaşlıyor mu?
  • Giriş/çıkış durumu: Oturum kontrolleri doğru çalışıyor mu?

Hata ayıklama için wp-config.php‘de geçici olarak şunları açabilirsiniz:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

Loglar wp-content/debug.log dosyasına yazılır. Canlı sitede WP_DEBUG_DISPLAY mutlaka false olmalıdır.

Sonuç

woocommerce_before_cart_table hook’u, sepet sayfasının en stratejik noktalarından birini özelleştirmenize kapı aralar. Ücretsiz kargo teşvikinden kupon hatırlatmasına, kategori bazlı uyarılardan kullanıcı oturumu mesajlarına kadar pek çok senaryo için küçük ve temiz kod parçalarıyla büyük etkiler yaratabilirsiniz.

Bu yazıda ele aldığımız yaklaşımların ortak noktası şu: Plugin kurmak yerine hook sistemiyle çalışmak, sitenizi daha hafif ve bakımı kolay tutar. Her bir fonksiyonu bağımsız tuttuğunuzda test etmek, devre dışı bırakmak ya da güncellemek de çok daha basit hale gelir. Inline CSS’i zamanla sınıf tabanlı bir yapıya taşıdığınızda ve kodlarınızı child theme’in ayrı bir dosyasında düzenlediğinizde, sepet sayfası özelleştirmelerinizi gerçek anlamda sürdürülebilir bir hale getirmiş olursunuz.

Bir yanıt yazın

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