WooCommerce Mini Sepete Özel İçerik Ekleme
E-ticaret sitelerinde mini sepet, kullanıcı deneyiminin en kritik parçalarından biri. Müşteri bir ürün eklediğinde sağ üstte açılan o küçük dropdown ya da sidebar panel, aslında dönüşüm oranını doğrudan etkiliyor. WooCommerce’in varsayılan mini sepet şablonu işlevsel ama çoğu zaman yetersiz kalıyor. Belki ücretsiz kargo eşiğini göstermek istiyorsun, belki sepete özel bir indirim mesajı eklemek ya da güven rozeti koymak istiyorsun. İşte tam bu noktada functions.php devreye giriyor.
Bu yazıda WooCommerce mini sepetine nasıl özel içerik ekleyeceğini, hangi hook’ları kullanacağını ve gerçek dünyadan senaryolara nasıl çözümler üretebileceğini adım adım göstereceğim.
Mini Sepet Nasıl Çalışır?
WooCommerce mini sepet, temanın header bölgesinde genellikle woocommerce_header_add_to_cart_fragment ya da doğrudan tema şablonlarıyla entegre edilmiş bir bileşen. İçerik AJAX ile güncelleniyor ve sepete ürün eklendiğinde sayfa yenilenmeden dinamik olarak değişiyor.
Mini sepetin içine içerik eklemek için kullanabileceğin birkaç farklı yol var:
woocommerce_before_mini_cart: Mini sepetin en üstüne, ürün listesinin öncesine içerik eklerwoocommerce_after_mini_cart: Ürün listesinin altına, toplam tutarın üstüne içerik eklerwoocommerce_mini_cart_contents: Mini sepet içerik alanına eklerwoocommerce_widget_shopping_cart_before_buttons: Butonların hemen üstüne eklerwoocommerce_widget_shopping_cart_after_buttons: Butonların hemen altına eklerwoocommerce_widget_shopping_cart_total: Toplam tutarın üstüne ekler
Bu hook’lar wp-content/plugins/woocommerce/templates/cart/mini-cart.php şablonu içinde tanımlı. Hangi hook’u nerede kullanacağını seçmek için şablona göz atmak her zaman iyi bir fikir.
Temel İçerik Ekleme
En basit kullanım senaryosuyla başlayalım. Mini sepetin üstüne bir bildirim mesajı eklemek istiyorsun diyelim:
// functions.php
add_action( 'woocommerce_before_mini_cart', 'custom_mini_cart_top_message' );
function custom_mini_cart_top_message() {
if ( WC()->cart->is_empty() ) {
return;
}
echo '<div class="mini-cart-top-message" style="background:#f0f7ff; padding:10px; margin-bottom:10px; border-radius:4px; font-size:13px;">';
echo '<strong>🎁 Bugün verilen siparişler aynı gün kargoda!</strong>';
echo '</div>';
}
Bu kadar basit. Sepet boşsa mesajı göstermiyoruz çünkü boş sepette bu mesajın işi yok. WC()->cart->is_empty() kontrolü bu işi yapıyor.
Ücretsiz Kargo İlerleme Çubuğu
Şimdi daha kullanışlı ve dönüşüme etkisi kanıtlanmış bir özelliğe geçelim: Ücretsiz kargo ilerleme çubuğu. Örneğin 250 TL ve üzeri alışverişlerde ücretsiz kargo veriyorsun. Müşteriye ne kadar kaldığını göstermek onları daha fazla harcamaya teşvik ediyor.
// functions.php
add_action( 'woocommerce_widget_shopping_cart_before_buttons', 'custom_free_shipping_progress_bar' );
function custom_free_shipping_progress_bar() {
$free_shipping_threshold = 250; // TL cinsinden eşik değer
$cart_total = WC()->cart->get_subtotal();
$remaining = $free_shipping_threshold - $cart_total;
echo '<div class="free-shipping-progress" style="padding:10px 0; border-top:1px solid #eee;">';
if ( $cart_total >= $free_shipping_threshold ) {
echo '<p style="color:#2ecc71; font-weight:bold; font-size:13px; margin:0 0 8px;">✅ Ücretsiz kargo kazandınız!</p>';
$percentage = 100;
} else {
$formatted_remaining = wc_price( $remaining );
echo '<p style="font-size:12px; margin:0 0 8px;">Ücretsiz kargo için <strong>' . $formatted_remaining . '</strong> daha alışveriş yapın.</p>';
$percentage = ( $cart_total / $free_shipping_threshold ) * 100;
}
echo '<div style="background:#e0e0e0; border-radius:10px; height:6px; overflow:hidden;">';
echo '<div style="background:#2ecc71; width:' . esc_attr( $percentage ) . '%; height:100%; border-radius:10px; transition:width 0.3s ease;"></div>';
echo '</div>';
echo '</div>';
}
Bu kod sadece görsel olarak değil, fonksiyonel olarak da doğru çalışıyor. wc_price() fonksiyonu para birimini ve formatı otomatik olarak WooCommerce ayarlarından alıyor, elle TL yazmak zorunda kalmıyorsun.
Güven Rozetleri Ekleme
Ödeme güvenliğine dair endişeler, sepet terkinin en büyük nedenlerinden. Mini sepete güven rozetleri eklemek bu endişeyi azaltır:
// functions.php
add_action( 'woocommerce_widget_shopping_cart_after_buttons', 'custom_mini_cart_trust_badges' );
function custom_mini_cart_trust_badges() {
if ( WC()->cart->is_empty() ) {
return;
}
?>
<div class="mini-cart-trust-badges" style="text-align:center; padding:12px 0; border-top:1px solid #f0f0f0; margin-top:10px;">
<p style="font-size:11px; color:#666; margin-bottom:8px;">Güvenli Alışveriş</p>
<div style="display:flex; justify-content:center; gap:15px; align-items:center; flex-wrap:wrap;">
<span style="font-size:11px; color:#555;">🔒 SSL Korumalı</span>
<span style="font-size:11px; color:#555;">💳 Güvenli Ödeme</span>
<span style="font-size:11px; color:#555;">🔄 Kolay İade</span>
</div>
</div>
<?php
}
Gerçek projekte inline style yerine CSS dosyasına taşımanı öneririm ama prototip için bu yeterli.
Sepet Tutarına Göre Dinamik Mesaj
Sadece sabit mesajlar değil, sepet içeriğine göre dinamik mesajlar da ekleyebilirsin. Bu senaryo biraz daha gerçek dünya:
// functions.php
add_action( 'woocommerce_before_mini_cart', 'custom_cart_dynamic_message' );
function custom_cart_dynamic_message() {
if ( WC()->cart->is_empty() ) {
return;
}
$cart_total = WC()->cart->get_subtotal();
$item_count = WC()->cart->get_cart_contents_count();
$message = '';
$bg_color = '#fff3cd';
$text_color = '#856404';
if ( $cart_total >= 500 ) {
$message = '🏆 VIP müşteri statüsündesiniz! Siparişinizde ek %5 indirim uygulandı.';
$bg_color = '#d4edda';
$text_color = '#155724';
} elseif ( $cart_total >= 250 ) {
$message = '🎉 Harika! Sepetiniz ücretsiz kargo için yeterli.';
$bg_color = '#cce5ff';
$text_color = '#004085';
} elseif ( $item_count >= 3 ) {
$message = '💡 3 ve üzeri üründe ek %3 indirim! İndirim sepete yansıtıldı.';
$bg_color = '#e2d9f3';
$text_color = '#432874';
} else {
$message = '🛒 Sepetinize ürün eklemeye devam edin, fırsatları kaçırmayın!';
}
if ( $message ) {
printf(
'<div style="background:%s; color:%s; padding:10px 12px; margin-bottom:10px; border-radius:4px; font-size:12px; line-height:1.5;">%s</div>',
esc_attr( $bg_color ),
esc_attr( $text_color ),
wp_kses_post( $message )
);
}
}
Bu örnekte get_subtotal() KDV hariç tutarı döndürüyor. KDV dahil tutarla çalışmak istersen get_cart_contents_total() veya get_total() kullanabilirsin. Ama genel kural olarak indirim eşiklerini KDV hariç tutara göre ayarlamak daha temiz.
Belirli Kategorideki Ürünler İçin Özel Mesaj
Bazı senaryolarda sepetteki ürünlerin kategorisine göre farklı mesaj göstermek gerekiyor. Örneğin elektronik kategorisinde ürün varsa garanti bilgisi göstermek:
// functions.php
add_action( 'woocommerce_after_mini_cart', 'custom_category_based_mini_cart_message' );
function custom_category_based_mini_cart_message() {
if ( WC()->cart->is_empty() ) {
return;
}
$has_elektronik = false;
$has_giyim = false;
$target_categories = array( 'elektronik', 'elektronik-urunler' ); // slug ile belirt
$giyim_categories = array( 'giyim', 'kadin-giyim', 'erkek-giyim' );
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product_id = $cart_item['product_id'];
if ( has_term( $target_categories, 'product_cat', $product_id ) ) {
$has_elektronik = true;
}
if ( has_term( $giyim_categories, 'product_cat', $product_id ) ) {
$has_giyim = true;
}
}
if ( $has_elektronik ) {
echo '<div style="padding:8px 12px; background:#e8f4fd; border-left:3px solid #3498db; margin-top:10px; font-size:12px;">';
echo '<strong>📦 Elektronik Ürün Garantisi:</strong> 2 yıl resmi garanti ve kapıda servis desteği.';
echo '</div>';
}
if ( $has_giyim ) {
echo '<div style="padding:8px 12px; background:#fef9e7; border-left:3px solid #f1c40f; margin-top:10px; font-size:12px;">';
echo '<strong>👗 Giyim İade Hakkı:</strong> 30 gün içinde ücretsiz iade, bedel değişimi garantisi.';
echo '</div>';
}
}
has_term() fonksiyonu WordPress’in native fonksiyonu, ürünün belirli bir taksonomiye ait olup olmadığını kontrol ediyor. Kategori slug’larını kullanmak ID’ye göre daha güvenilir çünkü veritabanı aktarımlarında ID değişebiliyor.
AJAX Güncellemesine Uyumlu Fragment Sistemi
Şimdiye kadar eklediğimiz kodlar statik hook’larla çalışıyor. Ama WooCommerce mini sepet AJAX ile güncellendiğinde, sepete ürün eklendiğinde ya da çıkarıldığında bu içerikler otomatik olarak yenilenmiyor mu diye sorabilirsin. Aslında hayır, yenileniyor. Çünkü mini sepetin tamamı AJAX fragment olarak yeniden render ediliyor ve hook’larımız her renderda çalışıyor. Ama bunu garanti altına almak için fragment sistemini doğru kullanman gerekiyor:
// functions.php
add_filter( 'woocommerce_add_to_cart_fragments', 'custom_mini_cart_fragment_update' );
function custom_mini_cart_fragment_update( $fragments ) {
ob_start();
// Özel içeriğimizi bir wrapper div içine alıyoruz
echo '<div class="custom-mini-cart-wrapper">';
custom_free_shipping_progress_bar(); // Yukarıda tanımladığımız fonksiyon
echo '</div>';
$fragments['.custom-mini-cart-wrapper'] = ob_get_clean();
return $fragments;
}
Bu yöntemle belirli bir CSS selectorunu hedef alarak sadece o alanı güncelliyorsun. Ama dikkat et, bu yöntemi kullanmak için o elementi sayfa yüklendiğinde de HTML’e yazmış olman gerekiyor. Fragment sistemi mevcut elementi değiştiriyor, sıfırdan oluşturmuyor.
Kupon Formu Ekleme
Mini sepetin içine kupon kodu formu eklemek de sıkça istenilen bir özellik. Ayrı bir sayfaya gitmeden direkt sepet üzerinden kupon uygulayabilmek kullanıcı deneyimini ciddi iyileştiriyor:
// functions.php
add_action( 'woocommerce_widget_shopping_cart_before_buttons', 'custom_mini_cart_coupon_form', 5 );
function custom_mini_cart_coupon_form() {
if ( WC()->cart->is_empty() ) {
return;
}
// Zaten uygulanmış kuponları listele
$applied_coupons = WC()->cart->get_applied_coupons();
if ( ! empty( $applied_coupons ) ) {
echo '<div style="padding:8px 0; font-size:12px;">';
echo '<strong style="color:#2ecc71;">✅ Uygulanan Kuponlar:</strong> ';
echo esc_html( implode( ', ', $applied_coupons ) );
echo '</div>';
return; // Kupon zaten uygulandıysa formu gösterme
}
?>
<div class="mini-cart-coupon" style="padding:10px 0; border-top:1px solid #eee;">
<form method="post" action="<?php echo esc_url( wc_get_cart_url() ); ?>" class="mini-cart-coupon-form">
<div style="display:flex; gap:5px;">
<input
type="text"
name="coupon_code"
placeholder="Kupon kodunuz..."
style="flex:1; padding:7px 10px; border:1px solid #ddd; border-radius:4px; font-size:12px;"
autocomplete="off"
>
<button
type="submit"
name="apply_coupon"
value="Uygula"
style="padding:7px 12px; background:#333; color:#fff; border:none; border-radius:4px; font-size:12px; cursor:pointer;"
>
Uygula
</button>
</div>
<?php wp_nonce_field( 'woocommerce-cart', '_wpnonce' ); ?>
</form>
</div>
<?php
}
Bu form, WooCommerce’in kendi sepet sayfasına POST isteği gönderiyor. Nonce alanı güvenlik için zorunlu. Formu gönderdikten sonra kullanıcı sepet sayfasına yönlendirilecek. Mini sepet içinde AJAX ile kupon uygulamak istersen daha fazla JavaScript yazman gerekiyor, o konu ayrı bir yazı konusu.
Özel CSS Eklemek
Tüm bu inline style’ları temizlemek için gerçek projede şöyle bir yapı kullan:
// functions.php
add_action( 'wp_head', 'custom_mini_cart_styles' );
function custom_mini_cart_styles() {
// Sadece WooCommerce aktifse yükle
if ( ! class_exists( 'WooCommerce' ) ) {
return;
}
?>
<style>
.mini-cart-top-message {
background: #f0f7ff;
padding: 10px 12px;
margin-bottom: 10px;
border-radius: 4px;
font-size: 13px;
line-height: 1.5;
}
.free-shipping-progress {
padding: 10px 0;
border-top: 1px solid #eee;
}
.free-shipping-progress__bar-wrapper {
background: #e0e0e0;
border-radius: 10px;
height: 6px;
overflow: hidden;
}
.free-shipping-progress__bar {
background: #2ecc71;
height: 100%;
border-radius: 10px;
transition: width 0.3s ease;
}
.mini-cart-trust-badges {
text-align: center;
padding: 12px 0;
border-top: 1px solid #f0f0f0;
margin-top: 10px;
}
.mini-cart-coupon input[type="text"]:focus {
outline: none;
border-color: #333;
}
</style>
<?php
}
Daha büyük projelerde bu stilleri ayrı bir CSS dosyasına taşıyıp wp_enqueue_style() ile yüklemek en temiz yöntem. Ama küçük projeler için wp_head ile direkt head’e yazmak da kabul edilebilir.
Hook Önceliği ve Çakışmalar
Birden fazla eklenti veya fonksiyon aynı hook’a ekleme yapıyorsa sıralama önem kazanıyor. WordPress hook sistemi öncelik parametresiyle bunu yönetiyor:
// functions.php
// Öncelik 10 (varsayılan) - normal sırada çalışır
add_action( 'woocommerce_before_mini_cart', 'custom_mini_cart_top_message', 10 );
// Öncelik 5 - daha önce çalışır (üstte görünür)
add_action( 'woocommerce_before_mini_cart', 'custom_urgent_sale_banner', 5 );
// Öncelik 20 - daha sonra çalışır (altta görünür)
add_action( 'woocommerce_before_mini_cart', 'custom_secondary_message', 20 );
function custom_urgent_sale_banner() {
$sale_end = strtotime( '2024-12-31 23:59:59' );
$now = current_time( 'timestamp' );
if ( $now > $sale_end ) {
return; // Kampanya bitti
}
$remaining_hours = floor( ( $sale_end - $now ) / 3600 );
echo '<div style="background:#e74c3c; color:#fff; padding:8px 12px; text-align:center; font-size:12px; border-radius:4px; margin-bottom:10px;">';
printf( '⏰ Yılbaşı kampanyası! Son <strong>%d saat</strong> kaldı.', $remaining_hours );
echo '</div>';
}
Bu örnekte kampanya bitiş tarihi sabit kodlanmış. Gerçek projede bu değeri WordPress seçeneği olarak tutmak daha yönetilebilir bir yaklaşım. get_option('kampanya_bitis_tarihi') gibi.
Performans Notları
Mini sepet çok sık güncelleniyor, dolayısıyla bu hook’lara eklediğin fonksiyonların performanslı olması önemli:
WC()->cart->get_cart()ile tüm sepeti döngüye almak yoğun bir işlem. Bunu mümkünse önbellekle ya da sadece gerektiğinde çalıştır.- Veritabanı sorgusu yapıyorsan (örneğin kullanıcıya özel mesaj için) sorgu sonuçlarını
wp_cache_get()vewp_cache_set()ile önbelleğe al. - Ağır hesaplamalar yapan fonksiyonlara
static $cache = null;ile basit fonksiyon içi önbellekleme ekleyebilirsin.
// functions.php
function custom_get_user_segment() {
static $segment = null;
if ( null !== $segment ) {
return $segment; // Aynı istek içinde tekrar hesaplama
}
$user_id = get_current_user_id();
if ( ! $user_id ) {
$segment = 'guest';
return $segment;
}
$order_count = wc_get_customer_order_count( $user_id );
if ( $order_count >= 10 ) {
$segment = 'vip';
} elseif ( $order_count >= 3 ) {
$segment = 'regular';
} else {
$segment = 'new';
}
return $segment;
}
add_action( 'woocommerce_before_mini_cart', 'custom_user_segment_message' );
function custom_user_segment_message() {
if ( WC()->cart->is_empty() || ! is_user_logged_in() ) {
return;
}
$segment = custom_get_user_segment();
if ( 'vip' === $segment ) {
echo '<div style="background:#fff3e0; padding:8px 12px; border-radius:4px; font-size:12px; margin-bottom:8px;">⭐ VIP müşterimiz, özel fiyatlar sizin için aktif!</div>';
}
}
Hata Ayıklama İpuçları
Mini sepetle çalışırken sık karşılaşılan sorunlar ve çözümleri:
- İçerik görünmüyor: Temanın mini sepet şablonunu override etmiş olabilir.
woocommerce/templates/cart/mini-cart.phpdosyasını kontrol et, hook’ların orada olduğundan emin ol. - AJAX’tan sonra kaybolıyor: Fragment sistemi eksik olabilir. Yukarıdaki
woocommerce_add_to_cart_fragmentsfilter’ını kullan. - Çift görünüyor: Hook aynı anda iki kez tetikleniyordur.
remove_actionile önceki kayıtı temizle ya da$donestatic değişkeni kullan. - PHP hatası:
WC()global nesnesine erişirkenclass_exists('WooCommerce')kontrolü koymak WooCommerce aktif değilken oluşacak fatal error’ları engelliyor.
Sonuç
WooCommerce mini sepeti, çoğu mağazada potansiyelinin çok altında kullanılan bir alan. Sadece ürün listesi ve ödeme butonu göstermek yerine, müşteriyle buluşma noktasına dönüştürebilirsin. Ücretsiz kargo ilerleme çubuğu, kampanya sayacı, güven rozetleri, kategori bazlı bilgiler… Bunların hepsi functions.php üzerinden eklediğin birkaç hook fonksiyonuyla hayata geçiyor.
Önemli olan noktaları özetleyecek olursam:
- Doğru hook seç: İçeriğin nerede görünmesini istediğine göre
before_mini_cart,after_mini_cart,before_buttonsveyaafter_buttonsarasından seçim yap. - Boş sepet kontrolü: Hemen hemen her fonksiyonda
is_empty()kontrolü koy. - AJAX uyumluluğu: Kritik içerikler için
woocommerce_add_to_cart_fragmentsfilter’ını kullan. - Performans: Döngü ve veritabanı işlemlerini minimize et, statik önbellekleme kullan.
- Güvenlik: Kullanıcı girdilerini her zaman
esc_html(),esc_attr()veyawp_kses_post()ile sanitize et.
Mini sepet küçük bir UI elemanı gibi görünse de doğru optimize edildiğinde sepet terk oranını düşürmede ve ortalama sipariş değerini artırmada ciddi bir etki yaratıyor. Yukarıdaki örnekleri kendi projenin ihtiyaçlarına göre uyarlayabilir, birleştirebilir ya da tamamen farklı senaryolar için şablon olarak kullanabilirsin.
