Wordpress İle Özel Bir Dinamik Çoklu Dil Destekli İçerik Sistemi Nasıl Yapılır?

Wordpress İle Özel Bir Dinamik Çoklu Dil Destekli İçerik Sistemi Nasıl Yapılır?
Wordpress İle Özel Bir Dinamik Çoklu Dil Destekli İçerik Sistemi Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Bu sistemi kurmadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. WordPress 6.x sürümleri ve PHP 8.2+ üzerinde test edilmiş bir altyapı, performans ve güvenlik açısından kritik öneme sahiptir.

  • PHP 8.2 veya üzeri bir sunucu ortamı.
  • WordPress'in kurulu olduğu ve veritabanı erişiminizin bulunduğu bir geliştirme ortamı.
  • Özel veritabanı tabloları oluşturmak için dbDelta fonksiyonu kullanımı hakkında temel bilgi.
  • Tema dosyalarınıza (functions.php) müdahale edebilme yetkisi.

Adım 1: Dil Yönetimi İçin Özel Veritabanı Tablosu Oluşturma

WordPress varsayılan olarak içerikleri tek bir dilde tutar. Çoklu dil desteği için içeriklerin hangi dilde olduğunu belirten bir ilişkilendirme tablosuna ihtiyacımız var. Aşağıdaki kod, aktif temanızın functions.php dosyasına eklendiğinde, sistem etkinleştirildiğinde gerekli tabloyu oluşturur.

function ozel_dil_sistemi_tablosunu_olustur() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'dil_icerik_eslesme';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        post_id bigint(20) NOT NULL,
        dil_kodu varchar(5) NOT NULL,
        grup_id bigint(20) NOT NULL,
        PRIMARY KEY  (id)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}
register_activation_hook(__FILE__, 'ozel_dil_sistemi_tablosunu_olustur');

Bu kod bloğu, wp_dil_icerik_eslesme adında bir tablo oluşturur. post_id mevcut yazıyı, dil_kodu (tr, en, de vb.) dil bilgisini, grup_id ise aynı içeriğin farklı dillerdeki karşılıklarını birbirine bağlayan benzersiz bir anahtarı temsil eder.

Adım 2: İçerik Kaydederken Dil Bilgisini İşleme

İçerik oluşturulurken veya güncellenirken, veritabanına dil bilgisini kaydetmemiz gerekir. Bunun için save_post kancasını (hook) kullanacağız. Bu işlem, içerik her kaydedildiğinde tetiklenir.

add_action('save_post', 'dil_bilgisini_kaydet', 10, 3);

function dil_bilgisini_kaydet($post_id, $post, $update) {
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if (!isset($_POST['dil_kodu_nonce'])) return;

    $dil_kodu = sanitize_text_field($_POST['dil_kodu']);
    $grup_id = intval($_POST['grup_id']);

    global $wpdb;
    $wpdb->replace(
        $wpdb->prefix . 'dil_icerik_eslesme',
        array('post_id' => $post_id, 'dil_kodu' => $dil_kodu, 'grup_id' => $grup_id),
        array('%d', '%s', '%d')
    );
}

Burada sanitize_text_field ve intval fonksiyonlarını kullanarak SQL Injection saldırılarına karşı verileri temizledik. $wpdb->replace metodu, eğer kayıt varsa günceller, yoksa yeni bir satır ekler.

Adım 3: Dinamik Dil Değiştirici (Switcher) Oluşturma

Kullanıcının diller arasında geçiş yapabilmesi için mevcut içeriğin diğer dillerdeki karşılığını bulmamız gerekir. Aşağıdaki fonksiyon, mevcut sayfanın grup_id değerini kullanarak diğer dillerdeki bağlantıları listeler.

function dil_degistirici_getir() {
    global $wpdb, $post;
    $table = $wpdb->prefix . 'dil_icerik_eslesme';
    
    $mevcut_grup = $wpdb->get_var($wpdb->prepare("SELECT grup_id FROM $table WHERE post_id = %d", $post->ID));
    $diger_diller = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table WHERE grup_id = %d AND post_id != %d", $mevcut_grup, $post->ID));

    foreach ($diger_diller as $dil) {
        echo '' . strtoupper($dil->dil_kodu) . '';
    }
}

Bu fonksiyon, temanızın herhangi bir yerinde (header.php gibi) çağrıldığında, mevcut içeriğin diğer dillerdeki versiyonlarına giden linkleri otomatik olarak oluşturacaktır.

Karşılaştırma: Eklenti vs. Özel Kodlama

Özellik Hazır Eklenti Özel Kodlama
Performans Düşük (Ek yük) Yüksek (Optimize)
Esneklik Kısıtlı Tam Kontrol
Bakım Kolay Geliştirici Gerektirir

Adım 4: Sorguları Optimize Etme ve Güvenlik

Özel bir sistem kurarken en büyük risk performans kaybıdır. Çok dilli bir yapıda her sayfa yüklenişinde ekstra sorgular çalıştırılır. Bunu engellemek için WordPress'in transient (geçici veri depolama) API'sini kullanmalısınız.

function get_ceviri_id($post_id, $hedef_dil) {
    $transient_key = 'ceviri_' . $post_id . '_' . $hedef_dil;
    $ceviri_id = get_transient($transient_key);

    if (false === $ceviri_id) {
        global $wpdb;
        $table = $wpdb->prefix . 'dil_icerik_eslesme';
        $grup_id = $wpdb->get_var($wpdb->prepare("SELECT grup_id FROM $table WHERE post_id = %d", $post_id));
        $ceviri_id = $wpdb->get_var($wpdb->prepare("SELECT post_id FROM $table WHERE grup_id = %d AND dil_kodu = %s", $grup_id, $hedef_dil));
        set_transient($transient_key, $ceviri_id, 12 * HOUR_IN_SECONDS);
    }
    return $ceviri_id;
}

Güvenlik Uyarısı: Veritabanı sorgularında her zaman $wpdb->prepare kullanın. Kullanıcıdan gelen verileri asla doğrudan sorguya dahil etmeyin. Üretim ortamında (production) hata ayıklama modunu (WP_DEBUG) kapalı tutun.

Adım 5: İçerik Yönetim Paneline Dil Seçimi Ekleme

Yöneticilerin içerik eklerken dil seçebilmesi için add_meta_box kullanarak bir arayüz oluşturmalıyız. Bu, içerik editörüne bir dropdown menü sunarak dil seçimini kolaylaştırır.

add_action('add_meta_boxes', 'dil_secim_meta_box');

function dil_secim_meta_box() {
    add_meta_box('dil_secimi', 'İçerik Dili', 'dil_secim_render', 'post', 'side');
}

function dil_secim_render($post) {
    echo 'Türkçeİngilizce';
    echo '';
}

Sıkça Sorulan Sorular

Özel dil sistemi SEO uyumlu mu?

Evet, eğer her dil için doğru hreflang etiketlerini wp_head kancası ile başlık kısmına eklerseniz, arama motorları içeriğinizi mükemmel şekilde indeksleyecektir.

Veritabanı tablolarını silersem içeriklerim kaybolur mu?

Hayır, içerikleriniz WordPress'in kendi wp_posts tablosunda kalmaya devam eder. Sadece diller arası bağlantı bilgisi silinir.

Bu sistem çoklu dil için performans sorunu yaratır mı?

Veritabanı indekslemelerini (index) doğru yaptığınız ve transient API kullandığınız sürece, hazır eklentilerden çok daha hızlı çalışacaktır.

Farklı içerik türlerini (Custom Post Types) destekler mi?

Evet, add_meta_boxes fonksiyonundaki 'post' parametresini kendi özel içerik türünüzün adıyla değiştirerek tüm sistemlerde kullanabilirsiniz.

Neden hazır eklenti kullanmamalıyım?

Hazır eklentiler genellikle çok fazla gereksiz sorgu çalıştırır ve veritabanını şişirir. Özel sistem, sadece ihtiyacınız olan veriyi çeker.

İleri Seviye Hata Ayıklama ve Loglama Stratejileri

Özel bir çoklu dil sistemi geliştirirken, en büyük zorluk dil anahtarlarının (language keys) eşleşmemesi veya yanlış dil verisinin çekilmesidir. Sisteminizin sağlıklı çalıştığından emin olmak için bir hata ayıklama katmanı eklemek, geliştirme sürecini ciddi oranda hızlandırır.

Aşağıdaki kod bloğu, sisteminizde bir dil eşleşmesi hatası oluştuğunda WordPress hata günlüğüne (debug.log) kayıt düşmenizi sağlar:

function log_language_mismatch($post_id, $requested_lang) {
    $current_lang = get_post_meta($post_id, '_content_language', true);
    if ($current_lang !== $requested_lang) {
        error_log(sprintf(
            'Dil Eşleşme Hatası: Post ID %d için beklenen %s, ancak veritabanında %s bulundu.',
            $post_id,
            $requested_lang,
            $current_lang
        ));
    }
}

Performans İçin Object Caching Kullanımı

Veritabanı sorgularını optimize etmek tek başına yeterli değildir. Özellikle çok dilli sitelerde, her sayfa yüklemesinde dil kontrolü yapmak CPU tüketimini artırabilir. WordPress'in wp_cache_set ve wp_cache_get fonksiyonlarını kullanarak dil verilerini belleğe almak, veritabanı yükünü %80'e kadar azaltabilir.

function get_translated_content_cached($post_id, $lang) {
    $cache_key = 'translated_content_' . $post_id . '_' . $lang;
    $cached_data = wp_cache_get($cache_key);

    if (false === $cached_data) {
        // Veritabanı sorgusu burada yapılır
        $cached_data = $wpdb->get_var($wpdb->prepare("SELECT content FROM my_custom_lang_table WHERE post_id = %d AND lang = %s", $post_id, $lang));
        wp_cache_set($cache_key, $cached_data, 'translations', 3600);
    }
    return $cached_data;
}

Deployment ve Yayına Alma Süreci

Sisteminizi yerel sunucudan canlı ortama taşırken dikkat etmeniz gereken en kritik nokta, dil tablolarındaki post_id referanslarının güncelliğidir. WordPress'in wp_posts tablosundaki ID'ler ile sizin özel tablonuzdaki ID'lerin eşleştiğinden emin olmak için bir "Sync" aracı geliştirmeniz önerilir.

Deployment Kontrol Listesi:

  • Veritabanı Şeması: Canlı sunucuda özel dil tablosunun varlığını kontrol eden bir kurulum scripti çalıştırın.
  • Rewrite Kuralları: flush_rewrite_rules() fonksiyonunu kullanarak dil bazlı URL yapınızın (örneğin: site.com/en/post-name) doğru çalıştığını doğrulayın.
  • Cache Temizliği: Deployment sonrası tüm nesne önbelleğini (Object Cache) temizleyin.
Profesyonel İpucu: Eğer sisteminizde çok fazla içerik varsa, wp_posts tablosuna bir lang_code sütunu eklemek yerine, özel bir tablo (Custom Table) kullanmak, WordPress'in çekirdek güncellemeleriyle çakışmanızı engeller ve veritabanı indekslemesini daha performanslı hale getirir.

Sonuç

WordPress ile özel bir dinamik çoklu dil destekli içerik sistemi oluşturmak, projenizin performansını ve kontrolünü tamamen elinize almanızı sağlar. Bu rehberde öğrendiğiniz veritabanı yönetimi, meta kutuları ve sorgu optimizasyonu teknikleri, profesyonel seviyede bir çoklu dil altyapısı kurmanız için yeterlidir. Bir sonraki adım olarak, bu sistemi REST API ile entegre ederek Headless WordPress projelerinizde de kullanmayı deneyebilirsiniz.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Uygulamadan önce mutlaka veritabanı yedeği alınız. Kodların üretim ortamında çalıştırılmasından doğabilecek veri kayıplarından yazılımcı sorumludur.

Bu yazıya tepkinizi paylaşın:
Mert Çelik

Teknoloji dünyasını ve dijital araçları günlük hayata entegre etme konusunda içerikler üretiyorum. Karmaşık teknik rehberleri en yalın haliyle sunmayı hedefliyorum.

Yorumlar (0)

Yorum Yaz