WooCommerce Ürün Açıklamasının Üzerine İçerik Ekleme

E-ticaret sitelerinde ürün sayfaları, müşterinin satın alma kararını doğrudan etkileyen en kritik sayfaların başında gelir. WooCommerce kullanıyorsanız ve ürün açıklamalarının üzerine özel içerik eklemek istiyorsanız, bunu yapmak için birkaç farklı yöntem mevcuttur. Bu yazıda functions.php dosyasını kullanarak WooCommerce ürün açıklamasının üzerine nasıl içerik ekleyeceğimizi, farklı senaryolara göre nasıl özelleştireceğimizi detaylıca ele alacağız.

Neden Ürün Açıklamasının Üzerine İçerik Ekleyelim?

Gerçek dünya senaryolarına bakmadan önce, bu ihtiyacın neden ortaya çıktığını anlayalım. Bir sysadmin veya WordPress geliştiricisi olarak müşterilerinizden sık sık şu talepleri alırsınız:

  • Kargo bilgisi uyarısı: “Tüm ürün sayfalarına kargo bilgisini otomatik ekle”
  • Stok uyarısı: “Az stoklu ürünlerde açıklamanın üstüne uyarı çıksın”
  • Kampanya bandı: “Belirli kategorideki ürünlerde indirim mesajı göster”
  • Güven rozetleri: “Her ürün açıklamasının üstüne SSL ve güvenli ödeme ikonları ekle”
  • Yaş/bölge kısıtlaması: “Alkol kategorisindeki ürünlerde yaş uyarısı göster”

Tüm bu ihtiyaçlar için tema dosyalarını düzenlemek yerine functions.php üzerinden hook sistemi kullanmak hem daha temiz hem de tema güncellemelerinden etkilenmeyen bir çözüm sunar.

WooCommerce Hook Sistemi Nedir?

WooCommerce, WordPress’in hook sistemini genişleterek ürün sayfalarının neredeyse her noktasına müdahale etmenizi sağlar. Ürün açıklamasıyla ilgili kullanacağımız ana hook şudur:

  • woocommerce_before_single_product_summary: Ürün görselinin ve özet alanının tamamen üstü
  • woocommerce_single_product_summary: Ürün başlığı, fiyat, açıklama gibi özet alanının içi
  • woocommerce_before_add_to_cart_form: Sepete ekle butonunun hemen üstü
  • woocommerce_product_tabs: Ürün sekmeleri (açıklama sekmesinin içeriği burada)
  • woocommerce_before_tabs: Sekmelerin tamamen üstü
  • the_content: WordPress’in genel içerik filtresi, ürün açıklamasını da kapsar

Ürün açıklaması WooCommerce’de iki farklı yerde görünür: kısa açıklama (özet alanında) ve uzun açıklama (sekmeler bölümünde). Bunları birbirinden ayırt etmek önemlidir.

Temel Kullanım: Ürün Açıklamasının Üstüne Sabit Metin Ekleme

En basit senaryo ile başlayalım. Tüm ürün açıklamalarının üstüne sabit bir bilgi notu eklemek istiyoruz.

// functions.php dosyasına ekleyin
add_action( 'woocommerce_before_tabs', 'onurlabs_urun_aciklama_uyarisi', 5 );

function onurlabs_urun_aciklama_uyarisi() {
    echo '<div class="urun-bilgi-notu" style="background:#fff3cd; border-left:4px solid #ffc107; padding:12px 16px; margin-bottom:20px; border-radius:4px;">';
    echo '<strong>Bilgi:</strong> Tüm ürünlerimiz orijinal ve faturalıdır. Ücretsiz kargo 500 TL ve üzeri siparişlerde geçerlidir.';
    echo '</div>';
}

Bu kod basit ama işe yarıyor. woocommerce_before_tabs hook’u ürün sekmelerinin (açıklama, yorumlar vb.) hemen üstüne içerik ekler. Priority değeri olan 5, bu kodun diğer aynı hook’u kullanan fonksiyonlardan önce çalışmasını sağlar.

Sadece Belirli Kategorilerde İçerik Gösterme

Gerçek projede genellikle “tüm ürünlere ekle” yaklaşımı işe yaramaz. Belirli kategorilerdeki ürünler için farklı mesajlar göstermek daha mantıklıdır.

add_action( 'woocommerce_before_tabs', 'onurlabs_kategori_bazli_uyari', 10 );

function onurlabs_kategori_bazli_uyari() {
    if ( ! is_product() ) {
        return;
    }

    global $product;

    // Ürünün kategorilerini al
    $urun_kategorileri = wp_get_post_terms( $product->get_id(), 'product_cat', array( 'fields' => 'slugs' ) );

    // Elektronik kategorisi için özel uyarı
    if ( in_array( 'elektronik', $urun_kategorileri ) ) {
        echo '<div class="garanti-bilgisi" style="background:#d4edda; border-left:4px solid #28a745; padding:12px 16px; margin-bottom:20px;">';
        echo '<strong>Garanti:</strong> Bu ürün 2 yıl resmi distribütör garantisi kapsamındadır.';
        echo '</div>';
    }

    // Gıda kategorisi için son kullanma tarihi uyarısı
    if ( in_array( 'gida', $urun_kategorileri ) ) {
        echo '<div class="gida-uyari" style="background:#f8d7da; border-left:4px solid #dc3545; padding:12px 16px; margin-bottom:20px;">';
        echo '<strong>Önemli:</strong> Ürünlerin son kullanma tarihleri kargo paketinizde belirtilmiştir.';
        echo '</div>';
    }
}

Burada dikkat edilmesi gereken nokta is_product() kontrolüdür. Hook’lar bazen beklenmedik yerlerde tetiklenebilir, bu kontrol ile sadece ürün sayfalarında çalışmasını garanti ediyoruz.

Ürün Etiketine Göre Dinamik İçerik Ekleme

Etiket bazlı filtreleme, kategori yapısını bozmadan esnek içerik yönetimi sağlar. Örneğin “yeni-sezon” etiketli ürünlere özel banner ekleyelim.

add_action( 'woocommerce_before_tabs', 'onurlabs_etiket_bazli_icerik', 10 );

function onurlabs_etiket_bazli_icerik() {
    if ( ! is_product() ) {
        return;
    }

    global $product;
    $urun_id = $product->get_id();

    // Ürün etiketlerini al
    $etiketler = wp_get_post_terms( $urun_id, 'product_tag', array( 'fields' => 'slugs' ) );

    if ( is_wp_error( $etiketler ) || empty( $etiketler ) ) {
        return;
    }

    $mesajlar = array(
        'yeni-sezon'   => array(
            'mesaj' => '2024 Yeni Sezon ürünü! İlk alanlara özel %10 indirim kodu: YENISEZON10',
            'renk'  => '#cce5ff',
            'kenar' => '#004085',
        ),
        'indirimli'    => array(
            'mesaj' => 'Bu ürün sınırlı stok indirimi kapsamındadır. Fırsatı kaçırmayın!',
            'renk'  => '#fff3cd',
            'kenar' => '#856404',
        ),
        'ithal-urun'   => array(
            'mesaj' => 'İthal ürün: Gümrük vergisi dahil fiyatlandırılmıştır.',
            'renk'  => '#e2e3e5',
            'kenar' => '#383d41',
        ),
    );

    foreach ( $mesajlar as $etiket => $bilgi ) {
        if ( in_array( $etiket, $etiketler ) ) {
            printf(
                '<div style="background:%s; border-left:4px solid %s; padding:12px 16px; margin-bottom:15px; border-radius:4px;"><p style="margin:0;">%s</p></div>',
                esc_attr( $bilgi['renk'] ),
                esc_attr( $bilgi['kenar'] ),
                esc_html( $bilgi['mesaj'] )
            );
        }
    }
}

Bu yaklaşım oldukça ölçeklenebilir. $mesajlar dizisine yeni etiket-mesaj çiftleri ekleyerek sistemi genişletebilirsiniz.

Stok Durumuna Göre Dinamik Uyarı Mesajı

Stok yönetimi aktifse, ürünün stok miktarına göre farklı mesajlar göstermek dönüşüm oranını artırır. “Aciliyet” hissi yaratmak e-ticarette bilinen bir yöntemdir.

add_action( 'woocommerce_before_tabs', 'onurlabs_stok_uyarisi', 15 );

function onurlabs_stok_uyarisi() {
    if ( ! is_product() ) {
        return;
    }

    global $product;

    // Stok yönetimi aktif değilse çık
    if ( ! $product->managing_stock() ) {
        return;
    }

    $stok_miktari = $product->get_stock_quantity();

    if ( null === $stok_miktari ) {
        return;
    }

    // Kritik stok: 1-5 adet
    if ( $stok_miktari > 0 && $stok_miktari <= 5 ) {
        echo '<div class="kritik-stok-uyarisi" style="background:#f8d7da; border:1px solid #f5c6cb; padding:10px 16px; margin-bottom:20px; border-radius:4px;">';
        echo '<span style="color:#721c24;">&#9888; <strong>Son ' . intval( $stok_miktari ) . ' ürün kaldı!</strong> Bu ürün tükenmeden siparişinizi verin.</span>';
        echo '</div>';
    }

    // Orta stok: 6-20 adet
    if ( $stok_miktari > 5 && $stok_miktari <= 20 ) {
        echo '<div class="orta-stok-uyarisi" style="background:#fff3cd; border:1px solid #ffeeba; padding:10px 16px; margin-bottom:20px; border-radius:4px;">';
        echo '<span style="color:#856404;">&#9432; <strong>Stoklar azalıyor:</strong> Yalnızca ' . intval( $stok_miktari ) . ' adet mevcuttur.</span>';
        echo '</div>';
    }
}

intval() kullanımına dikkat edin. Veritabanından gelen değerleri her zaman doğru tipe çevirip çıktıda temizlemek güvenlik açısından zorunludur.

Özel Ürün Meta Alanına Göre İçerik Ekleme

Bazen ürüne özel bilgileri ACF (Advanced Custom Fields) veya WooCommerce’in custom meta alanları aracılığıyla saklarsınız. Bu meta alanlara göre içerik gösterelim.

add_action( 'woocommerce_before_tabs', 'onurlabs_meta_alanina_gore_icerik', 10 );

function onurlabs_meta_alanina_gore_icerik() {
    if ( ! is_product() ) {
        return;
    }

    global $product;
    $urun_id = $product->get_id();

    // Özel meta alanlarını kontrol et
    $uretici_ulke   = get_post_meta( $urun_id, '_uretici_ulke', true );
    $video_url      = get_post_meta( $urun_id, '_tanitim_video', true );
    $kurulum_suresi = get_post_meta( $urun_id, '_kurulum_suresi', true );

    // Üretici ülke bilgisi varsa göster
    if ( ! empty( $uretici_ulke ) ) {
        echo '<div class="uretici-bilgi" style="display:flex; align-items:center; gap:8px; padding:10px 16px; background:#f8f9fa; border-radius:4px; margin-bottom:15px;">';
        echo '<strong>Üretim Yeri:</strong> ' . esc_html( $uretici_ulke );
        echo '</div>';
    }

    // Kurulum süresi varsa göster
    if ( ! empty( $kurulum_suresi ) ) {
        echo '<div class="kurulum-bilgi" style="background:#d1ecf1; border-left:4px solid #17a2b8; padding:10px 16px; margin-bottom:15px; border-radius:4px;">';
        echo '<strong>Ortalama Kurulum Süresi:</strong> ' . esc_html( $kurulum_suresi ) . ' dakika';
        echo '</div>';
    }

    // Tanıtım videosu varsa embed et
    if ( ! empty( $video_url ) && filter_var( $video_url, FILTER_VALIDATE_URL ) ) {
        echo '<div class="tanitim-video" style="margin-bottom:20px;">';
        echo '<h4>Ürün Tanıtım Videosu</h4>';
        echo wp_oembed_get( esc_url( $video_url ) );
        echo '</div>';
    }
}

get_post_meta() ile çektiğiniz verileri asla doğrudan echo etmeyin. esc_html(), esc_url(), esc_attr() gibi WordPress escape fonksiyonlarını kullanmak hem XSS açıklarını kapatır hem de WordPress kodlama standartlarına uyum sağlar.

Açıklama Sekmesinin İçine the_content Filtresi ile Müdahale

Bazen before_tabs yerine doğrudan açıklama içeriğinin başına HTML eklemek istersiniz. Bunun için the_content filtresini ürün sayfasına özel olarak kullanabilirsiniz.

add_filter( 'the_content', 'onurlabs_aciklama_basi_icerik' );

function onurlabs_aciklama_basi_icerik( $icerik ) {
    // Sadece ürün sayfasında ve ana döngüde çalış
    if ( ! is_product() || ! in_the_loop() || ! is_main_query() ) {
        return $icerik;
    }

    global $product;

    if ( ! $product instanceof WC_Product ) {
        return $icerik;
    }

    // Sadece belirli ürün tiplerinde çalış (basit ve değişken ürünler)
    $desteklenen_tipler = array( 'simple', 'variable' );
    if ( ! in_array( $product->get_type(), $desteklenen_tipler ) ) {
        return $icerik;
    }

    $on_icerik = '<div class="aciklama-on-bilgi" style="background:#e8f4fd; border:1px solid #bee5eb; padding:15px; margin-bottom:20px; border-radius:6px;">';
    $on_icerik .= '<h4 style="margin-top:0; color:#0c5460;">Ürün Hakkında</h4>';
    $on_icerik .= '<p style="margin-bottom:0;">Aşağıdaki açıklama ürün ekibimiz tarafından hazırlanmış olup tüm teknik bilgiler doğrulanmıştır. Sorularınız için destek hattımıza başvurabilirsiniz.</p>';
    $on_icerik .= '</div>';

    return $on_icerik . $icerik;
}

Bu filtreyi kullanırken in_the_loop() ve is_main_query() kontrollerini es geçmeyin. Aksi takdirde sidebar widget’larında, ilgili ürünlerde veya diğer döngülerde de çalışabilir ve sayfa düzeninizi bozabilir.

Kullanıcı Rolüne Göre Farklı İçerik Gösterme

B2B ve B2C müşterilerinizin aynı ürün sayfasında farklı bilgiler görmesini istiyorsanız, kullanıcı rolü kontrolü ekleyebilirsiniz.

add_action( 'woocommerce_before_tabs', 'onurlabs_rol_bazli_icerik', 20 );

function onurlabs_rol_bazli_icerik() {
    if ( ! is_product() ) {
        return;
    }

    // Giriş yapmamış kullanıcılar için
    if ( ! is_user_logged_in() ) {
        echo '<div class="giris-cta" style="background:#f8f9fa; border:1px dashed #6c757d; padding:15px; margin-bottom:20px; border-radius:4px; text-align:center;">';
        echo '<p style="margin:0;"><strong>Üye girişi yaparak</strong> toplu alım fiyatlarını ve özel teklifleri görebilirsiniz. ';
        echo '<a href="' . esc_url( wc_get_account_endpoint_url( 'dashboard' ) ) . '">Giriş Yap</a> | ';
        echo '<a href="' . esc_url( wp_registration_url() ) . '">Üye Ol</a></p>';
        echo '</div>';
        return;
    }

    $mevcut_kullanici = wp_get_current_user();
    $roller          = (array) $mevcut_kullanici->roles;

    // Toptancı rolü için toplu fiyat tablosu
    if ( in_array( 'toptanci', $roller ) || in_array( 'wholesale_customer', $roller ) ) {
        global $product;
        $normal_fiyat = $product->get_regular_price();

        if ( ! empty( $normal_fiyat ) ) {
            $toplu_fiyatlar = array(
                '10-49 adet'  => number_format( floatval( $normal_fiyat ) * 0.90, 2 ) . ' TL',
                '50-99 adet'  => number_format( floatval( $normal_fiyat ) * 0.85, 2 ) . ' TL',
                '100+ adet'   => number_format( floatval( $normal_fiyat ) * 0.80, 2 ) . ' TL',
            );

            echo '<div class="toplu-fiyat" style="background:#d4edda; border-left:4px solid #28a745; padding:15px; margin-bottom:20px;">';
            echo '<strong>Toplu Alım Fiyatları (Size Özel):</strong><ul style="margin:10px 0 0 0;">';

            foreach ( $toplu_fiyatlar as $miktar => $fiyat ) {
                echo '<li>' . esc_html( $miktar ) . ': <strong>' . esc_html( $fiyat ) . '</strong></li>';
            }

            echo '</ul></div>';
        }
    }
}

Koşullu Mantığı Temiz Tutma: Helper Fonksiyon Yaklaşımı

Birden fazla kural eklemeye başladığınızda kod karmaşıklaşabilir. Helper fonksiyonlar kullanmak kodu daha okunabilir ve bakımı kolay hale getirir.

// Helper: Ürün belirli kategoride mi?
function onurlabs_urün_kategoride_mi( $urun_id, $kategori_slug ) {
    $kategoriler = wp_get_post_terms( $urun_id, 'product_cat', array( 'fields' => 'slugs' ) );
    if ( is_wp_error( $kategoriler ) ) {
        return false;
    }
    return in_array( $kategori_slug, $kategoriler );
}

// Helper: Bildirim kutusu HTML'i oluştur
function onurlabs_bildirim_kutusu( $mesaj, $tip = 'bilgi' ) {
    $tipler = array(
        'bilgi'   => array( 'bg' => '#d1ecf1', 'kenar' => '#17a2b8', 'yazi' => '#0c5460' ),
        'basari'  => array( 'bg' => '#d4edda', 'kenar' => '#28a745', 'yazi' => '#155724' ),
        'uyari'   => array( 'bg' => '#fff3cd', 'kenar' => '#ffc107', 'yazi' => '#856404' ),
        'tehlike' => array( 'bg' => '#f8d7da', 'kenar' => '#dc3545', 'yazi' => '#721c24' ),
    );

    $stil = isset( $tipler[ $tip ] ) ? $tipler[ $tip ] : $tipler['bilgi'];

    return sprintf(
        '<div style="background:%s; border-left:4px solid %s; color:%s; padding:12px 16px; margin-bottom:18px; border-radius:4px;"><p style="margin:0;">%s</p></div>',
        esc_attr( $stil['bg'] ),
        esc_attr( $stil['kenar'] ),
        esc_attr( $stil['yazi'] ),
        wp_kses_post( $mesaj )
    );
}

// Ana fonksiyon
add_action( 'woocommerce_before_tabs', 'onurlabs_merkezi_urun_bildirimleri', 10 );

function onurlabs_merkezi_urun_bildirimleri() {
    if ( ! is_product() ) {
        return;
    }

    global $product;
    $urun_id = $product->get_id();
    $cikti   = '';

    if ( onurlabs_urün_kategoride_mi( $urun_id, 'bebek-urunleri' ) ) {
        $cikti .= onurlabs_bildirim_kutusu(
            '<strong>Güvenlik Testi:</strong> Bu ürün CE sertifikalıdır ve Avrupa bebek güvenlik standartlarını karşılamaktadır.',
            'basari'
        );
    }

    if ( onurlabs_urün_kategoride_mi( $urun_id, 'kimyasal-urunler' ) ) {
        $cikti .= onurlabs_bildirim_kutusu(
            '<strong>Dikkat:</strong> Bu ürün tehlikeli madde kapsamındadır. Çocuklardan uzak tutunuz.',
            'tehlike'
        );
    }

    if ( ! empty( $cikti ) ) {
        echo $cikti; // WPCS: XSS OK - tüm veriler esc_ ile temizlendi
    }
}

Performans ve Bakım Notları

Pratik deneyimden birkaç önemli nokta:

  • Hook priority’sini doğru ayarlayın: WooCommerce’in varsayılan woocommerce_before_tabs priority’si genellikle 10’dur. Daha önce çalışmasını istiyorsanız 5, sonra çalışmasını istiyorsanız 20 kullanın.
  • is_product() kontrolünü asla atlama: Hook’lar düşündüğünüzden daha geniş kapsamda tetiklenebilir.
  • Transient ile veritabanı sorgularını önbelleğe alın: Eğer her sayfa yüklemesinde veritabanına sorgu atıyorsanız, get_transient() ve set_transient() kullanmayı değerlendirin.
  • wp_kses_post() vs esc_html(): Dinamik HTML çıktısı üretiyorsanız wp_kses_post() kullanın; sadece metin çıktısı üretiyorsanız esc_html() yeterlidir.
  • CSS’i ayrı dosyaya taşıyın: Inline stil kullanmak hızlı prototipleme için iyidir ama production ortamında CSS’i wp_enqueue_style() ile ayrı bir dosyadan yüklemek daha doğrudur.
  • Child tema kullanın: Tüm bu kodları her zaman child temanın functions.php dosyasına yazın, ana tema güncellemesi kodlarınızı silmez.
  • WooCommerce sürüm uyumluluğunu kontrol edin: Bazı hook isimleri WooCommerce sürümleri arasında değişebilir. Kullandığınız WooCommerce sürümünün dokümantasyonunu kontrol edin.

Sonuç

WooCommerce ürün açıklamasının üzerine içerik eklemek, ilk bakışta basit bir tema görevi gibi görünse de doğru yapıldığında güçlü ve sürdürülebilir bir sistem oluşturmanızı sağlar. Hook sistemi üzerinden çalışmak, tema güncellemelerinden bağımsız kalmanızı garanti eder ve kod organizasyonunu temiz tutar.

Bu yazıda ele aldığımız yaklaşımları özetlersek; woocommerce_before_tabs hook’u genel amaçlı içerik eklemek için en güvenli başlangıç noktasıdır. Kategori, etiket, meta alan ve kullanıcı rolüne göre koşullu içerik göstermek için WordPress’in yerleşik fonksiyonlarını kullanmak hem performanslı hem de güvenlidir. Helper fonksiyonlarla kod tekrarını azaltmak ise uzun vadede bakım maliyetini düşürür.

Eğer projeniz büyüdükçe bu tür özelleştirmelerin sayısı artıyorsa, bir plugin olarak paketlemeyi de düşünebilirsiniz. Bu sayede farklı sitelerde yeniden kullanabilir, versiyon kontrolü yapabilir ve daha kolay test edebilirsiniz.

Bir yanıt yazın

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