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: Bir de bunun tam tersi olan En sade haliyle bir duyuru mesajı eklemek için şu kodu Bu kadar basit. Sayfayı yenilediğinizde sepet tablosunun hemen üzerinde sarı bir bilgi kutusu belirecektir. Ama tabii bu sadece başlangıç. 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. Bu fonksiyon 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ı: Bu örnekte 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: Kullanıcı kupon uygulamışsa bunu vurgulayabilir, uygulamadıysa hatırlatabilirsiniz: Bu örnek hem pozitif geri bildirim (kupon uygulandı, şu kadar kazandın) hem de teşvik edici hatırlatma işlevi görüyor. 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: 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 Birden fazla fonksiyon aynı hook’a bağlandığında hangisinin önce çalışacağını Bu örnekte kargo bilgisi her zaman kupon hatırlatmasının üstünde görünür. 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 WC()->cart kontrolü yapın: Nesne önbelleği kullanın: Koşullu yükleme yapmayı düşünün: Inline style yazmak hızlı prototipleme için iyidir ama uzun vadede CSS dosyanıza ya da temanın Böylece bu CSS sınıflarını HTML çıktılarınızda kullanabilirsiniz. Tüm bu kodları doğrudan ana temanın Child theme Sepet kodlarını Kodunuzu yayına almadan önce birkaç senaryoyu test edin: Hata ayıklama için Loglar 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.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.
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ı
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>';
}Senaryo 1: Ücretsiz Kargo Hedef Göstergesi
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>';
}
}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
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>';
}
}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
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
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 ' | <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>';
}
}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ı
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>';
}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ü
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>';
}
}Güvenlik ve Performans Notları
esc_html(), esc_url() veya wp_kses() fonksiyonlarından geçirin. Aksi halde XSS açığı yaratırsınız.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.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.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
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 );
}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
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.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';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
wp-config.php‘de geçici olarak şunları açabilirsiniz:define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );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.
