Dile Göre Farklı İçerik Gösterme: WordPress’te Koşullu Fonksiyonlar

Çok dilli bir WordPress sitesi yönetiyorsanız, ziyaretçinin diline göre farklı içerik göstermek hem kullanıcı deneyimi hem de dönüşüm oranları açısından kritik önem taşır. “Herkese aynı içerik” dönemi geride kaldı. Artık Almanya’dan gelen bir kullanıcı Almanca promosyon metni görürken, Türkiye’den gelen başka bir kullanıcı Türkçe karşılanmalı. Bu yazıda WordPress functions.php üzerinden koşullu fonksiyonlar yazarak dile göre farklı içerik nasıl sunulur, bunu detaylıca ele alacağız.

Neden functions.php?

Plugin kurmak her zaman doğru yaklaşım değildir. Özellikle kurumsal projelerde ya da performansın kritik olduğu sitelerde gereksiz plugin yükü ciddi sorunlar yaratır. functions.php doğrudan tema katmanında çalışır ve WordPress’in kendi fonksiyon yapısıyla tam entegre olur. Üstelik koşullu dil mantığı için ihtiyaç duyduğunuz şey genellikle birkaç yüz satır temiz PHP kodudur, bütün bir plugin değil.

WPML, Polylang veya TranslatePress gibi eklentiler zaten kuruluysa bunlarla uyumlu çalışan yardımcı fonksiyonlar yazabilirsiniz. Eklenti yoksa ve siteniz tek dil ama kullanıcılar farklı bölgelerden geliyorsa tarayıcı dil başlığını okuyarak da yönlendirme yapabilirsiniz.

Aktif Dili Tespit Etmenin Yolları

Dil tespiti için birkaç farklı yaklaşım var. Hangisini kullandığınız altyapıya bağlıdır.

Polylang ile dil tespiti:

function get_current_language_code() {
    if ( function_exists( 'pll_current_language' ) ) {
        return pll_current_language( 'slug' ); // 'tr', 'en', 'de' gibi döner
    }
    return get_locale(); // fallback: 'tr_TR', 'en_US' gibi
}

WPML ile dil tespiti:

function get_wpml_language_code() {
    if ( defined( 'ICL_LANGUAGE_CODE' ) ) {
        return ICL_LANGUAGE_CODE; // 'tr', 'en', 'de'
    }
    return substr( get_locale(), 0, 2 );
}

Tarayıcı dil başlığından tespit (eklentisiz):

function detect_browser_language( $default = 'en' ) {
    if ( ! isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
        return $default;
    }

    $accepted = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
    // İlk dil kodunu al: "tr-TR,tr;q=0.9,en;q=0.8" => 'tr'
    preg_match( '/^([a-z]{2})/i', $accepted, $matches );

    return isset( $matches[1] ) ? strtolower( $matches[1] ) : $default;
}

Tarayıcı dil tespiti güvenilir ama yanıltıcı olabilir. Kullanıcı İstanbul’da Almanca tarayıcı kullanıyor olabilir. Bu yüzden kritik içeriklerde URL tabanlı dil yönetimi tercih edilmeli, tarayıcı tespiti ise sadece yönlendirme ipucu olarak kullanılmalıdır.

Temel Koşullu İçerik Fonksiyonu

Şimdi işin özüne girelim. En basit koşullu içerik fonksiyonu şöyle görünür:

function show_content_by_language( $contents = array(), $default_lang = 'tr' ) {
    // Aktif dili belirle
    $current_lang = 'tr';

    if ( function_exists( 'pll_current_language' ) ) {
        $current_lang = pll_current_language( 'slug' );
    } elseif ( defined( 'ICL_LANGUAGE_CODE' ) ) {
        $current_lang = ICL_LANGUAGE_CODE;
    } else {
        $current_lang = substr( get_locale(), 0, 2 );
    }

    // İstenen dilde içerik var mı?
    if ( isset( $contents[ $current_lang ] ) ) {
        return $contents[ $current_lang ];
    }

    // Yoksa default dile düş
    if ( isset( $contents[ $default_lang ] ) ) {
        return $contents[ $default_lang ];
    }

    // Hiçbiri yoksa dizinin ilk elemanını döndür
    return reset( $contents );
}

Bu fonksiyonu tema dosyalarında şöyle kullanırsınız:

// header.php veya herhangi bir template dosyasında

$banner_text = show_content_by_language( array(
    'tr' => 'Yaz İndirimi Başladı! %30 Tasarruf Edin',
    'en' => 'Summer Sale! Save 30%',
    'de' => 'Sommerverkauf! 30% Sparen',
    'fr' => 'Soldes d'Été! Économisez 30%',
) );

echo '<div class="banner">' . esc_html( $banner_text ) . '</div>';

Temiz, okunabilir ve genişletilmesi kolay bir yapı. Yeni dil eklediğinizde sadece diziye yeni anahtar-değer çifti ekliyorsunuz.

WooCommerce Ürün Sayfalarında Koşullu Mesajlar

E-ticaret sitelerinde dile göre farklılaştırma en çok değer katan senaryo burası. Kargo bilgisi, iade politikası, promosyon mesajları dile göre değişmeli.

function woo_shipping_notice_by_lang() {
    $lang = function_exists( 'pll_current_language' )
        ? pll_current_language( 'slug' )
        : substr( get_locale(), 0, 2 );

    $notices = array(
        'tr' => array(
            'free_shipping' => '150 TL ve üzeri alışverişlerde ücretsiz kargo!',
            'delivery_time' => 'Aynı gün kargo (saat 14:00'e kadar verilen siparişler)',
            'return_policy' => '14 gün iade garantisi',
        ),
        'en' => array(
            'free_shipping' => 'Free shipping on orders over €15!',
            'delivery_time' => 'Same day shipping (orders placed before 2 PM)',
            'return_policy' => '14-day return guarantee',
        ),
        'de' => array(
            'free_shipping' => 'Kostenloser Versand ab €15!',
            'delivery_time' => 'Gleicher Tag Versand (Bestellungen bis 14 Uhr)',
            'return_policy' => '14 Tage Rückgabegarantie',
        ),
    );

    $current_notices = isset( $notices[ $lang ] )
        ? $notices[ $lang ]
        : $notices['en'];

    return $current_notices;
}

// WooCommerce ürün sayfasına ekle
add_action( 'woocommerce_single_product_summary', 'display_lang_specific_shipping_info', 25 );
function display_lang_specific_shipping_info() {
    if ( ! is_product() ) return;

    $info = woo_shipping_notice_by_lang();

    echo '<div class="shipping-info-box">';
    echo '<p class="free-shipping">' . esc_html( $info['free_shipping'] ) . '</p>';
    echo '<p class="delivery-time">' . esc_html( $info['delivery_time'] ) . '</p>';
    echo '<p class="return-policy">' . esc_html( $info['return_policy'] ) . '</p>';
    echo '</div>';
}

Bu kod snippet’ini functions.php’ye yapıştırdığınızda WooCommerce ürün sayfalarınız otomatik olarak ziyaretçinin diline göre kargo bilgisi gösterecek.

Shortcode ile Kullanım

Bazen editörden de dil bazlı içerik göstermek isteyebilirsiniz. Bir shortcode yazarak content editörüne bu gücü verebilirsiniz:

function lang_content_shortcode( $atts, $content = null ) {
    $atts = shortcode_atts(
        array(
            'lang' => 'tr',
        ),
        $atts,
        'lang_content'
    );

    $current_lang = 'tr';

    if ( function_exists( 'pll_current_language' ) ) {
        $current_lang = pll_current_language( 'slug' );
    } elseif ( defined( 'ICL_LANGUAGE_CODE' ) ) {
        $current_lang = ICL_LANGUAGE_CODE;
    } else {
        $current_lang = substr( get_locale(), 0, 2 );
    }

    // Aktif dil shortcode'da belirtilen dille eşleşiyor mu?
    if ( trim( $atts['lang'] ) === trim( $current_lang ) ) {
        return do_shortcode( $content );
    }

    return ''; // Eşleşmiyorsa hiçbir şey gösterme
}

add_shortcode( 'lang_content', 'lang_content_shortcode' );

Editörde kullanımı şöyle olur:

[lang_content lang="tr"]
Türk müşterilerimize özel: Bu ay tüm ürünlerde KDV dahil fiyat!
[/lang_content]

[lang_content lang="en"]
Special for our international customers: VAT-free pricing this month!
[/lang_content]

[lang_content lang="de"]
Für unsere deutschen Kunden: MwSt.-freie Preise diesen Monat!
[/lang_content]

Bu yaklaşım içerik editörlerine kod bilgisi gerektirmeden dil bazlı içerik yönetimi imkanı tanır. Özellikle ajans ortamında müşteriyi teknik detaylardan uzak tutmak için mükemmel bir çözüm.

Admin Panelinde Dil Bazlı Bildirimler

Sadece frontend değil, admin panelinde de dil bazlı koşullar işe yarar. Örneğin farklı ülkelerdeki yöneticilere farklı bildirimler gösterebilirsiniz:

add_action( 'admin_notices', 'show_localized_admin_notice' );
function show_localized_admin_notice() {
    // Sadece yöneticilere göster
    if ( ! current_user_can( 'manage_options' ) ) return;

    // Kullanıcının WordPress dil tercihini al
    $user_locale = get_user_locale( get_current_user_id() );
    $user_lang   = substr( $user_locale, 0, 2 );

    $messages = array(
        'tr' => array(
            'type'    => 'notice-info',
            'message' => 'Hatırlatma: Bu ay sonu ürün fiyatlarını güncellemeyi unutmayın.',
        ),
        'en' => array(
            'type'    => 'notice-info',
            'message' => 'Reminder: Do not forget to update product prices by end of month.',
        ),
        'de' => array(
            'type'    => 'notice-info',
            'message' => 'Erinnerung: Vergessen Sie nicht, die Produktpreise bis Monatsende zu aktualisieren.',
        ),
    );

    $msg = isset( $messages[ $user_lang ] )
        ? $messages[ $user_lang ]
        : $messages['en'];

    printf(
        '<div class="notice %s is-dismissible"><p>%s</p></div>',
        esc_attr( $msg['type'] ),
        esc_html( $msg['message'] )
    );
}

Dile Göre Farklı Menü Öğeleri

Bazı durumlarda menüde dile özgü linkler göstermek isteyebilirsiniz. Örneğin Türk kullanıcılara Türkçe blog linki, İngiliz kullanıcılara farklı bir sayfa:

add_filter( 'wp_nav_menu_items', 'add_lang_specific_menu_item', 10, 2 );
function add_lang_specific_menu_item( $items, $args ) {
    // Sadece belirli menüye uygula
    if ( $args->theme_location !== 'primary' ) {
        return $items;
    }

    $current_lang = 'en';
    if ( function_exists( 'pll_current_language' ) ) {
        $current_lang = pll_current_language( 'slug' );
    }

    $extra_items = array(
        'tr' => '<li class="menu-item lang-exclusive"><a href="/tr/kampanyalar">Kampanyalar</a></li>',
        'en' => '<li class="menu-item lang-exclusive"><a href="/en/deals">Special Deals</a></li>',
        'de' => '<li class="menu-item lang-exclusive"><a href="/de/angebote">Angebote</a></li>',
    );

    if ( isset( $extra_items[ $current_lang ] ) ) {
        $items .= $extra_items[ $current_lang ];
    }

    return $items;
}

Gelişmiş Senaryo: Coğrafi Konum + Dil Kombinasyonu

Gerçek dünyada sadece dil yetmez, bazen coğrafi konum da devreye girer. Almanya’dan Türkçe tarayıcıyla gelen biri için ne yaparsınız? İşte burada öncelik sırası önemlidir:

function get_content_priority( $content_map ) {
    /**
     * Öncelik sırası:
     * 1. URL'deki dil kodu (WPML/Polylang)
     * 2. Kullanıcı hesap tercihi
     * 3. Tarayıcı dili
     * 4. Varsayılan
     */

    $lang = null;

    // 1. Polylang aktif mi?
    if ( function_exists( 'pll_current_language' ) ) {
        $lang = pll_current_language( 'slug' );
    }

    // 2. WPML aktif mi?
    if ( ! $lang && defined( 'ICL_LANGUAGE_CODE' ) ) {
        $lang = ICL_LANGUAGE_CODE;
    }

    // 3. Giriş yapmış kullanıcının tercihi
    if ( ! $lang && is_user_logged_in() ) {
        $user_locale = get_user_locale();
        $lang = substr( $user_locale, 0, 2 );
    }

    // 4. Tarayıcı dili
    if ( ! $lang && isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
        preg_match( '/^([a-z]{2})/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $m );
        $lang = isset( $m[1] ) ? strtolower( $m[1] ) : 'en';
    }

    // 5. Son çare
    if ( ! $lang ) {
        $lang = 'en';
    }

    // İçerik haritasında bu dil var mı?
    if ( isset( $content_map[ $lang ] ) ) {
        return $content_map[ $lang ];
    }

    // İngilizce fallback
    if ( isset( $content_map['en'] ) ) {
        return $content_map['en'];
    }

    // Dizinin ilk elemanı
    return reset( $content_map );
}

Bu fonksiyon birden fazla kaynaktan dil bilgisi toplayarak en doğru içeriği sunar. Kurumsal projelerde bu tür katmanlı yaklaşım çok daha güvenilir sonuçlar verir.

Performans İçin Caching

Her sayfa yüklemesinde dil tespiti yapıyorsanız bunu cache’lemek mantıklı olur. Özellikle tarayıcı başlığı okuma ve kullanıcı sorgusu gibi işlemler için:

function get_current_lang_cached() {
    static $cached_lang = null;

    if ( $cached_lang !== null ) {
        return $cached_lang;
    }

    if ( function_exists( 'pll_current_language' ) ) {
        $cached_lang = pll_current_language( 'slug' );
    } elseif ( defined( 'ICL_LANGUAGE_CODE' ) ) {
        $cached_lang = ICL_LANGUAGE_CODE;
    } elseif ( is_user_logged_in() ) {
        $cached_lang = substr( get_user_locale(), 0, 2 );
    } else {
        preg_match(
            '/^([a-z]{2})/i',
            $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en',
            $m
        );
        $cached_lang = isset( $m[1] ) ? strtolower( $m[1] ) : 'en';
    }

    return $cached_lang;
}

static $cached_lang kullanımı sayesinde aynı sayfa yüklemesinde fonksiyon kaç kez çağrılırsa çağrılsın dil tespiti sadece bir kez yapılır. PHP’nin static değişken özelliği burada session cache gibi davranır.

Pratik Notlar ve Dikkat Edilmesi Gerekenler

  • XSS güvenliği: İçerikleri echo ederken mutlaka esc_html() veya wp_kses_post() kullanın. Özellikle HTML içeren dil metinlerinde bu kritiktir.
  • Hardcoded içerik tuzağı: functions.php’ye çok fazla metin gömmek zamanla bakımı zorlaştırır. Bir noktadan sonra bu içerikleri custom post type ya da options tablosuna taşımayı düşünün.
  • RTL dil desteği: Arapça, İbranice gibi sağdan sola yazılan diller için sadece metin değil, CSS direction de değişmeli. WordPress’in is_rtl() fonksiyonunu bu durumlarda mutlaka kontrol edin.
  • Dil kodları tutarsızlığı: Polylang ‘tr’ döndürürken PHP locale ‘tr_TR’ döndürür. Her fonksiyonun ne döndürdüğünü test edip ona göre normalize edin.
  • Çeviri dosyalarıyla karışıklık: functions.php’deki dil bazlı içerikler .po/.mo çeviri sistemiyle rekabet eder. İkisini aynı anda kullanıyorsanız hangi sistemin öncelikli olduğunu belirleyin.
  • Cache eklentileriyle uyum: WP Rocket, W3 Total Cache gibi araçlar sayfaları cache’lediğinde dil bazlı içerikler sorun çıkarabilir. Bu tür dinamik içerikleri cookie bazlı dışlama kurallarıyla cache dışında tutun.
  • Polylang’ın pll__() fonksiyonu: Polylang kullanıyorsanız string çevirisi için pll__() fonksiyonu zaten var. Kendi çözümünüzü yazmadan önce bu built-in alternatifi değerlendirin.

Sonuç

Dile göre koşullu içerik göstermek WordPress’te bir eklenti meselesi olmak zorunda değil. functions.php üzerinde doğru yazılmış birkaç fonksiyon, hem daha hafif hem de daha kontrol edilebilir bir çözüm sunar. Önemli olan dil tespit mekanizmasının güvenilir olması ve fallback mantığının doğru kurulmasıdır.

Küçük projeler için tarayıcı dil tespiti yeterli olabilirken, kurumsal e-ticaret sitelerinde mutlaka WPML veya Polylang gibi URL tabanlı bir dil yönetim sistemiyle çalışın. Tarayıcı başlığı manipüle edilebilir, URL edilemez.

Bu yazıdaki fonksiyonları kopyala-yapıştır yapmadan önce kendi altyapınıza göre test edin. Her sitenin dil yönetimi farklı, evrensel bir çözüm yok. Ama bu temel yapıyı anladıktan sonra kendi ihtiyacınıza özel versiyonlarını üretmek çok kolay olacak.

Bir yanıt yazın

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