WooCommerce Sepet İkonunu Menüye Ekleme

E-ticaret sitenizde kullanıcı deneyimini artırmanın en basit ama en etkili yollarından biri, sepet ikonunu ana menüye eklemektir. Ziyaretçiler siteyi gezerken sepetlerinde kaç ürün olduğunu görmek ister ve bu küçük detay dönüşüm oranlarını ciddi şekilde etkiler. WooCommerce bu özelliği varsayılan olarak sunmaz, ama functions.php dosyasına birkaç satır kod ekleyerek bunu kolayca halledebilirsiniz.

Neden Sepet İkonunu Menüye Ekliyoruz?

Müşteri alışveriş yaparken sepetine ürün ekliyor, başka sayfalara geziyor, sonra sepete dönmek istiyor. Eğer sepet ikonu her zaman görünürde değilse, müşteri sepeti bulmakta zorlanır ve siteyi terk edebilir. Bu yüzden sepet ikonunun her sayfada, her scroll pozisyonunda görünür olması gerekiyor.

WooCommerce’in kendi widget’ları ve shortcode’ları var ama bunlar genellikle sidebar veya belirli alanlara konuluyor. Menüye entegre bir sepet ikonu hem estetik hem de fonksiyonel açıdan çok daha iyi bir deneyim sunuyor. Üstelik wc_get_cart_url(), WC()->cart->get_cart_contents_count() gibi WooCommerce fonksiyonlarını kullanarak dinamik bir sepet sayacı ekleyebiliyoruz.

Temel Yapı: functions.php’ye İlk Dokunuş

Her şeyden önce, functions.php dosyasına dokunmadan önce bir yedek alın. Bu dosyada yapılan hatalar sitenizi tamamen çökertebilir. Child theme kullanıyorsanız zaten güvende sayılırsınız, child theme’in functions.php dosyasını kullanın.

En basit yaklaşım, wp_nav_menu_items filtresini kullanmak. Bu filtre, menü HTML’i oluşturulduktan sonra devreye giriyor ve siz de sonuna sepet linki ekliyorsunuz.

// functions.php - Temel sepet ikonu ekleme
function add_cart_icon_to_menu( $items, $args ) {
    if ( $args->theme_location == 'primary' ) {
        $cart_count = WC()->cart->get_cart_contents_count();
        $cart_url   = wc_get_cart_url();
        
        $items .= '<li class="menu-item cart-menu-item">';
        $items .= '<a href="' . esc_url( $cart_url ) . '">';
        $items .= '<span class="cart-icon">🛒</span>';
        $items .= '<span class="cart-count">' . $cart_count . '</span>';
        $items .= '</a>';
        $items .= '</li>';
    }
    return $items;
}
add_filter( 'wp_nav_menu_items', 'add_cart_icon_to_menu', 10, 2 );

Bu kod çalışıyor ama ham bir yapı. theme_location değerini kendi temanızın menü lokasyonuna göre değiştirmeniz gerekiyor. Bunu öğrenmek için Görünüm > Menüler sayfasına gidin ve hangi konuma atandığını kontrol edin. Popüler temalarda bu değer genellikle primary, main-menu, header-menu veya top-nav şeklinde oluyor.

WooCommerce Aktif Mi Kontrolü

Sitenize WooCommerce eklentisini devre dışı bırakırsanız yukarıdaki kod hata verecektir çünkü WC() fonksiyonu tanımlı olmayacak. Her zaman bir kontrol ekleyin.

// WooCommerce aktiflik kontrolü ile güvenli versiyon
function add_cart_icon_to_menu( $items, $args ) {
    // WooCommerce aktif değilse hiçbir şey yapma
    if ( ! class_exists( 'WooCommerce' ) ) {
        return $items;
    }
    
    // WC()->cart null olabilir, bunu da kontrol et
    if ( is_null( WC()->cart ) ) {
        return $items;
    }
    
    if ( $args->theme_location == 'primary' ) {
        $cart_count = WC()->cart->get_cart_contents_count();
        $cart_url   = wc_get_cart_url();
        $cart_total = WC()->cart->get_cart_total();
        
        $badge_class = $cart_count > 0 ? 'has-items' : 'empty';
        
        $items .= '<li class="menu-item cart-menu-item ' . $badge_class . '">';
        $items .= '<a href="' . esc_url( $cart_url ) . '" title="Sepetim (' . $cart_count . ' ürün)">';
        $items .= '<span class="cart-icon">🛒</span>';
        if ( $cart_count > 0 ) {
            $items .= '<span class="cart-count">' . absint( $cart_count ) . '</span>';
        }
        $items .= '</a>';
        $items .= '</li>';
    }
    return $items;
}
add_filter( 'wp_nav_menu_items', 'add_cart_icon_to_menu', 10, 2 );

Burada absint() kullandık çünkü dışarıdan gelen verileri her zaman sanitize etmek gerekiyor. esc_url() de URL’yi güvenli hale getiriyor.

AJAX ile Dinamik Sepet Sayacı

Yukarıdaki kodlar sayfa yenilenmeden çalışmaz. Müşteri ürün eklediğinde sepet sayısı güncellenmez. Bunun için WooCommerce’in kendi AJAX event’lerini kullanmamız gerekiyor.

WooCommerce, sepet güncellendiğinde wc_fragment_refresh ve added_to_cart gibi jQuery olayları tetikler. Bu olayları yakalayarak sayacı güncelleyebilirsiniz.

// functions.php - AJAX fragment desteği için
function cart_menu_fragment( $fragments ) {
    if ( ! class_exists( 'WooCommerce' ) || is_null( WC()->cart ) ) {
        return $fragments;
    }
    
    $cart_count = WC()->cart->get_cart_contents_count();
    $badge_class = $cart_count > 0 ? 'has-items' : 'empty';
    
    ob_start();
    ?>
    <a class="cart-menu-link <?php echo esc_attr( $badge_class ); ?>" 
       href="<?php echo esc_url( wc_get_cart_url() ); ?>"
       title="Sepetim">
        <span class="cart-icon">🛒</span>
        <span class="cart-count"><?php echo absint( $cart_count ); ?></span>
    </a>
    <?php
    $fragments['.cart-menu-link'] = ob_get_clean();
    
    return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'cart_menu_fragment' );

Bu fragment sistemi WooCommerce’in kendi AJAX mekanizmasını kullanıyor. Sepete ürün eklendiğinde WooCommerce otomatik olarak bu fragment’leri güncelliyor. CSS seçicisi olan .cart-menu-link sayfadaki elementi bulmak için kullanılıyor, bu yüzden menüdeki linkin de aynı class’a sahip olması gerekiyor.

Birden Fazla Menü Lokasyonu için Destek

Bazı temalar birden fazla menü lokasyonuna sahip, header’da bir menü, mobil için ayrı bir menü. Bu durumda her iki menüye de sepet eklemek isteyebilirsiniz.

// Birden fazla menü lokasyonu desteği
function add_cart_icon_to_multiple_menus( $items, $args ) {
    if ( ! class_exists( 'WooCommerce' ) || is_null( WC()->cart ) ) {
        return $items;
    }
    
    // Sepet eklenecek menü lokasyonları
    $allowed_locations = array( 'primary', 'mobile-menu', 'header-right' );
    
    if ( ! in_array( $args->theme_location, $allowed_locations ) ) {
        return $items;
    }
    
    $cart_count = WC()->cart->get_cart_contents_count();
    $cart_url   = wc_get_cart_url();
    
    // Mobil menü için farklı stil
    if ( $args->theme_location == 'mobile-menu' ) {
        $label = 'Sepetim (' . absint( $cart_count ) . ')';
        $items .= '<li class="menu-item cart-menu-item mobile-cart">';
        $items .= '<a href="' . esc_url( $cart_url ) . '">' . esc_html( $label ) . '</a>';
        $items .= '</li>';
    } else {
        $items .= '<li class="menu-item cart-menu-item">';
        $items .= '<a class="cart-menu-link" href="' . esc_url( $cart_url ) . '">';
        $items .= '<span class="cart-icon">🛒</span>';
        $items .= '<span class="cart-count">' . absint( $cart_count ) . '</span>';
        $items .= '</a>';
        $items .= '</li>';
    }
    
    return $items;
}
add_filter( 'wp_nav_menu_items', 'add_cart_icon_to_multiple_menus', 10, 2 );

CSS ile Sepet İkonunu Güzelleştirme

Kod çalışıyor ama görsel olarak ham halde. functions.php içinden CSS enqueue ederek stillerinizi ekleyebilirsiniz.

// CSS ve JS dosyalarını enqueue etme
function cart_menu_scripts_styles() {
    if ( ! class_exists( 'WooCommerce' ) ) {
        return;
    }
    
    // Inline CSS - küçük projeler için uygun
    $custom_css = '
        .cart-menu-item {
            position: relative;
            display: flex;
            align-items: center;
        }
        
        .cart-menu-link {
            position: relative;
            display: inline-flex;
            align-items: center;
            padding: 8px 12px;
            text-decoration: none;
            color: inherit;
        }
        
        .cart-icon {
            font-size: 20px;
            line-height: 1;
        }
        
        .cart-count {
            position: absolute;
            top: -4px;
            right: -4px;
            background: #e74c3c;
            color: #ffffff;
            font-size: 11px;
            font-weight: 700;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            line-height: 1;
        }
        
        .cart-menu-item.empty .cart-count {
            background: #95a5a6;
        }
        
        .cart-menu-link:hover {
            opacity: 0.8;
        }
    ';
    
    wp_add_inline_style( 'your-theme-style', $custom_css );
}
add_action( 'wp_enqueue_scripts', 'cart_menu_scripts_styles' );

Buradaki your-theme-style kısmını temanızın ana style handle’ı ile değiştirin. Bunu bulmak için temanızın functions.php dosyasında wp_enqueue_style çağrısına bakın. Genellikle twentytwentyfour-style, hello-elementor-style gibi isimler oluyor.

Font Awesome ile İkon Kullanımı

Emoji yerine Font Awesome ikonu kullanmak daha profesyonel görünür. Temanız zaten Font Awesome yüklüyorsa direkt kullanabilirsiniz.

// Font Awesome ile sepet ikonu
function add_cart_icon_fontawesome( $items, $args ) {
    if ( ! class_exists( 'WooCommerce' ) || is_null( WC()->cart ) ) {
        return $items;
    }
    
    if ( $args->theme_location !== 'primary' ) {
        return $items;
    }
    
    $cart_count = WC()->cart->get_cart_contents_count();
    $cart_url   = wc_get_cart_url();
    
    // Font Awesome shopping-cart ikonu
    $icon = '<i class="fa fa-shopping-cart" aria-hidden="true"></i>';
    
    // Screen reader için gizli metin ekle (erişilebilirlik)
    $sr_text = '<span class="screen-reader-text">Sepet, ' . absint( $cart_count ) . ' ürün</span>';
    
    $items .= '<li class="menu-item cart-menu-item" role="none">';
    $items .= '<a class="cart-menu-link" href="' . esc_url( $cart_url ) . '" role="menuitem" aria-label="Alışveriş Sepeti">';
    $items .= $icon;
    $items .= $sr_text;
    if ( $cart_count > 0 ) {
        $items .= '<span class="cart-count" aria-hidden="true">' . absint( $cart_count ) . '</span>';
    }
    $items .= '</a>';
    $items .= '</li>';
    
    return $items;
}
add_filter( 'wp_nav_menu_items', 'add_cart_icon_fontawesome', 10, 2 );

Erişilebilirlik açısından screen-reader-text class’ı çok önemli. Ekran okuyucu kullanan ziyaretçiler için sepet sayısını sesli olarak okutuyoruz. aria-hidden="true" ile görsel ikonu ekran okuyuculardan gizliyoruz.

Gerçek Dünya Senaryosu: Checkout Sayfasında Gizleme

Bazı e-ticaret stratejistleri checkout sayfasında dikkat dağıtıcı elementlerin kaldırılmasını öneriyor. Sepet ikonunun checkout sayfasında görünmemesini isteyebilirsiniz.

// Checkout ve sipariş tamamlama sayfasında sepeti gizle
function add_cart_icon_smart( $items, $args ) {
    if ( ! class_exists( 'WooCommerce' ) || is_null( WC()->cart ) ) {
        return $items;
    }
    
    if ( $args->theme_location !== 'primary' ) {
        return $items;
    }
    
    // Checkout ve order-received sayfasında ekleme
    if ( is_checkout() || is_order_received_page() ) {
        return $items;
    }
    
    $cart_count = WC()->cart->get_cart_contents_count();
    $cart_url   = wc_get_cart_url();
    
    // Sepet sayfasındayken farklı stil uygula
    $active_class = is_cart() ? ' current-menu-item' : '';
    
    $items .= '<li class="menu-item cart-menu-item' . esc_attr( $active_class ) . '">';
    $items .= '<a class="cart-menu-link" href="' . esc_url( $cart_url ) . '" ';
    
    if ( is_cart() ) {
        $items .= 'aria-current="page" ';
    }
    
    $items .= 'title="Alışveriş Sepeti">';
    $items .= '<span class="cart-icon">🛒</span>';
    $items .= '<span class="cart-count">' . absint( $cart_count ) . '</span>';
    $items .= '</a>';
    $items .= '</li>';
    
    return $items;
}
add_filter( 'wp_nav_menu_items', 'add_cart_icon_smart', 10, 2 );

is_checkout(), is_cart(), is_order_received_page() WooCommerce’in conditional tag’leri. Bunları kullanarak hangi sayfada olduğunuzu anlayabilirsiniz.

Hepsini Bir Araya Getiren Tam Kod

Tüm bu parçaları birleştirerek production’a hazır bir çözüm oluşturalım.

/**
 * WooCommerce Menü Sepet İkonu - Tam Çözüm
 * Child theme functions.php dosyasına ekleyin
 */

// 1. Menüye sepet ikonu ekle
function wc_cart_menu_icon( $items, $args ) {
    // Güvenlik kontrolleri
    if ( ! class_exists( 'WooCommerce' ) ) {
        return $items;
    }
    
    if ( is_null( WC()->cart ) ) {
        return $items;
    }
    
    // Sadece belirli menü lokasyonlarına ekle
    $target_locations = apply_filters( 
        'wc_cart_menu_locations', 
        array( 'primary', 'main-navigation' ) 
    );
    
    if ( ! in_array( $args->theme_location, $target_locations, true ) ) {
        return $items;
    }
    
    // Checkout sayfasında gösterme
    if ( function_exists( 'is_checkout' ) && is_checkout() ) {
        return $items;
    }
    
    $cart_count  = WC()->cart->get_cart_contents_count();
    $cart_url    = wc_get_cart_url();
    $has_items   = $cart_count > 0;
    $item_class  = 'menu-item cart-menu-item';
    $item_class .= $has_items ? ' has-items' : ' empty-cart';
    $item_class .= ( function_exists( 'is_cart' ) && is_cart() ) ? ' current-menu-item' : '';
    
    ob_start();
    ?>
    <li class="<?php echo esc_attr( $item_class ); ?>">
        <a class="cart-menu-link" 
           href="<?php echo esc_url( $cart_url ); ?>"
           aria-label="Alışveriş Sepeti, <?php echo absint( $cart_count ); ?> ürün">
            <span class="cart-icon" aria-hidden="true">🛒</span>
            <span class="cart-count" 
                  data-count="<?php echo absint( $cart_count ); ?>"
                  aria-hidden="true">
                <?php echo absint( $cart_count ); ?>
            </span>
        </a>
    </li>
    <?php
    $items .= ob_get_clean();
    
    return $items;
}
add_filter( 'wp_nav_menu_items', 'wc_cart_menu_icon', 10, 2 );

// 2. AJAX fragment güncellemesi
function wc_cart_menu_fragment( $fragments ) {
    if ( ! class_exists( 'WooCommerce' ) || is_null( WC()->cart ) ) {
        return $fragments;
    }
    
    $cart_count = WC()->cart->get_cart_contents_count();
    $has_items  = $cart_count > 0;
    
    ob_start();
    ?>
    <a class="cart-menu-link" 
       href="<?php echo esc_url( wc_get_cart_url() ); ?>"
       aria-label="Alışveriş Sepeti, <?php echo absint( $cart_count ); ?> ürün">
        <span class="cart-icon" aria-hidden="true">🛒</span>
        <span class="cart-count" 
              data-count="<?php echo absint( $cart_count ); ?>"
              aria-hidden="true">
            <?php echo absint( $cart_count ); ?>
        </span>
    </a>
    <?php
    $fragments['.cart-menu-link'] = ob_get_clean();
    
    return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'wc_cart_menu_fragment' );

// 3. Stilleri enqueue et
function wc_cart_menu_styles() {
    if ( ! class_exists( 'WooCommerce' ) ) {
        return;
    }
    
    $css = '
        .cart-menu-item { position: relative; }
        .cart-menu-link { 
            position: relative; 
            display: inline-flex; 
            align-items: center;
            padding: 0 10px;
        }
        .cart-icon { font-size: 22px; }
        .cart-count {
            position: absolute;
            top: -8px; right: 0;
            background: #e74c3c;
            color: #fff;
            font-size: 10px;
            font-weight: bold;
            min-width: 18px;
            height: 18px;
            border-radius: 9px;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0 4px;
            box-sizing: border-box;
        }
        .empty-cart .cart-count { background: #bdc3c7; }
    ';
    
    wp_add_inline_style( 'woocommerce-general', $css );
}
add_action( 'wp_enqueue_scripts', 'wc_cart_menu_styles' );

Sık Karşılaşılan Sorunlar ve Çözümleri

Sepet sayısı güncellenmiyor: WooCommerce AJAX’ının aktif olduğundan emin olun. WooCommerce > Ayarlar > Gelişmiş kısmında AJAX ile sepet yönetimi seçeneğini kontrol edin.

Menü lokasyonu bulunamıyor: functions.php‘de register_nav_menus() fonksiyonuna bakın ve hangi handle’ların tanımlı olduğunu görün. Yanlış lokasyon adı en sık yapılan hata.

CSS uygulanmıyor: Temanız woocommerce-general style handle’ını kullanmıyorsa wp_add_inline_style çalışmaz. O zaman wp_enqueue_style ile kendi CSS dosyanızı ekleyin veya temanızın ana style handle’ını kullanın.

Fatal error WC() çağrısında: woocommerce_loaded veya init hook’undan sonra çağırdığınızdan emin olun. wp_nav_menu_items filtresi template_redirect‘ten sonra çalıştığı için normalde sorun olmamalı ama bazen cache eklentileri bunu tetikleyebilir.

Sayı badge’i pozisyonu bozuk: Tema menü öğeleri için overflow: hidden kullanıyorsa badge dışarı taşamaz. .cart-menu-item‘a overflow: visible !important ekleyin.

Sonuç

WooCommerce sepet ikonunu menüye eklemek birkaç satır kodla halledilebilecek ama doğru yapılmadığında çok sorun çıkarabilen bir işlem. Güvenlik kontrolleri, AJAX güncelleme desteği ve erişilebilirlik dikkat etmeniz gereken üç temel nokta.

En önemli tavsiyem şu: Her zaman child theme kullanın ve değişiklikleri önce staging ortamında test edin. Cache eklentiniz varsa kodu ekledikten sonra cache’i temizlemeyi unutmayın, aksi takdirde sepet sayısı güncel gelmeyebilir.

apply_filters( 'wc_cart_menu_locations', array(...) ) kullanımı sayesinde kodunuzu başka geliştiricilere extensible bıraktınız. Bu küçük detay, özellikle müşteri projelerinde çok işinize yarayacak. Kodun tamamını child theme’e koyun, gerekirse küçük ayarlamalar yapın ve siteniz için mükemmel sepet deneyimini oluşturun.

Bir yanıt yazın

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