WordPress'ten 3.000 Yazı Taşımak: Öğrendiklerim

Kendi WordPress sitelerimden ~3.000 yazıyı jekcms'e taşıdım. SQL→CSV içe aktarma akışı ve canımı gerçekten yakanlar: encoding, görseller, slug'lar.

WordPress'ten 3.000 Yazı Taşımak: Öğrendiklerim

Kendi WordPress sitelerimden ~3.000 yazıyı jekcms'e taşıdım. SQL→CSV içe aktarma akışı ve canımı gerçekten yakanlar: encoding, görseller, slug'lar.

Bu yazıda anlattığım içe aktarıcıyı ben yazdım; içinden geçen yaklaşık 3.000 yazı da kendi WordPress sitelerimden geldi. Müşteri projesi değil, laboratuvar testi değil — kendi arşivim, akşamlara ve hafta sonlarına yayılan bir süreçte jekcms'e taşındı. İçe aktarıcıyı yazan kişi olmanın pürüzsüz bir göç garantilediğini düşünebilirsiniz. Daha çok şunu garantiliyor: pürüzleri gece birde, Türkçe karakterleri bozulmuş bir CSV'ye bakarken bizzat keşfediyorsunuz.

Bugün ağımda 14 site jekcms üzerinde çalışıyor; en büyüğünde 2.300'den fazla yazı var, filo toplamı 5.500'ü geçti. Bu yazı ise taşınmanın kendisi hakkında: SQL→CSV içe aktarma akışı adım adım nasıl işliyor ve canımı gerçekten yakan dört şey — encoding, görsel yolları, slug çakışmaları ve kategori eşleme.

Neden WXR dosyası değil de SQL ve CSV?

WordPress'in kendi dışa aktarımı WXR üretir — çoğu zaman devasa bir XML dosyası. Paylaşımlı hostingde işlemesi eziyettir: bellek limitleri, zaman aşımları ve işin ilginç kısımlarının (öne çıkan görsel, kategori ilişkileri) nasılsa postmeta üzerinden çözülmesi gerektiği gerçeği. jekcms başka bir yol izliyor. Admin'deki İçe Aktar ekranı size hazır bir SQL sorgusu verir; bunu phpMyAdmin'de (ya da herhangi bir MySQL istemcisinde) WordPress veritabanınıza karşı çalıştırır, sonucu CSV olarak dışa aktarır ve o CSV'yi jekcms'e yüklersiniz. Üç sekme var — Yazılar, Sayfalar, Yorumlar — her birinin kendi sorgusu ve kendi yükleme formu.

Bu tasarımın pratikte iki artısı var. Birincisi, sunucudan sunucuya erişim yok: WordPress siteniz nerede olursa olsun — küs ayrıldığınız bir hosting firmasında bile — veritabanını internete açmanız gerekmiyor. İkincisi, sorgu okuyabileceğiniz düz bir SELECT. Fazladan bir sütun lazımsa çalıştırmadan önce eklersiniz. Burada kara kutu yok.

Sorgular neyi çekiyor, neyi bilerek atlıyor

Yazılar sorgusu wp_posts'tan başlık, slug, içerik, özet, durum ve yayın tarihini seçer; yazarın adını, slug'ını ve e-postasını wp_users'tan alır; öne çıkan görseli wp_postmeta'daki _thumbnail_id üzerinden çözer; kategori ve etiketleri wp_term_relationships, wp_term_taxonomy ve wp_terms'ten toplar. Sayfalar aynı yapının taksonomisiz hali. Yorumlar wp_comments'tan gelir; varsayılan olarak yalnızca onaylılar.

Bilerek seçmediği şey: rastgele postmeta. ACF alanları yok, sayfa oluşturucu verisi yok, Yoast veya RankMath başlık/açıklamaları yok. Bu bir eksik değil, tercih — WordPress postmeta'sı serileştirilmiş dizilerden ve eklenti öneklerinden oluşan bir bataklık; körlemesine içeri almak kurtardığından fazlasını kirletiyor. Ben göçte eski SEO eklentisi açıklamalarımı kaybettim ve önemli olanları jekcms'in kendi SEO alanlarına elle yeniden yazdım. Sıkıcıydı; ama çoğu zaten başka bir on yılın arama sonuçları için yazılmıştı.

İlk ısıran: encoding

En eski WordPress tablolarım utf8mb4 öncesinden kalmaydı. Bazıları düz utf8'di — MySQL'in üç baytlık türü — ve bir sitede 2010'ların başındaki bir sunucu taşınmasından kalma latin1 tortusu vardı. Türk alfabesi bunun için acımasız bir testtir: zincirdeki tek bir halka charset konusunda anlaşmazsa ı, İ, ş, ğ ve ö anında anlamsız karakter çorbasına dönüşür.

Kontrolü dışa aktarmadan önce yapın, sonra değil:

-- kaynak tablolar gerçekte hangi karakter setinde?
SHOW TABLE STATUS WHERE Name IN ('wp_posts', 'wp_comments');

-- eski üç baytlık utf8 tabloyu dışa aktarmadan önce yükselt
ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

Can sıkıcı yoldan öğrendiğim iki kural daha. CSV'yi phpMyAdmin'den dışa aktarırken UTF-8'i açıkça seçin. Ve o CSV'yi "şöyle bir bakayım" diye asla Excel'de açmayın — Excel dosyayı seve seve bir Windows kod sayfasıyla yeniden kaydeder ve ASCII dışı her karakteri mahveder. Düzgün bir editörde inceleyin. Bir de hiçbir içe aktarıcının düzeltemeyeceği bir durum var: eski üç baytlık utf8 tablolar, dört baytlık emojileri yıllar önce daha yazma anında sessizce kırpmıştı. Eski bir yazıda emoji yerine ???? görüyorsanız o veri gitmiş demektir.

Günlerin gittiği yer: görsel yolları

"Görselleri içe aktar" seçeneği işaretliyken jekcms hem öne çıkan görseli hem de yazı içeriğinde geçen her görseli HTTP üzerinden çekip yerel olarak kaydeder; eski domaine işaret eder halde bırakmaz. Büyük bir göçün açık ara en yavaş kısmı budur — veritabanı satırı kopyalamıyorsunuz, binlerce dosya indiriyorsunuz — ve on yıllık özensiz alışkanlıkların faturası da burada kesilir.

Benim faturam şöyleydi: artık çözümlenmeyen domainlerden hotlink'lenmiş görseller, yıllar önce iptal ettiğim bir CDN aboneliği ve kendi siteme yönlendirme zinciri üzerinden giden http:// URL'leri. Ölü her kaynak, içe aktarma sonrasında eksik bir görsel demek. "Öne çıkan görseli ayarla" seçeneği — WordPress'te hiç öne çıkan görsel atanmamış yazılar için içerikteki ilk görseli terfi ettirir — boşlukların bir kısmını kapattı; ama yalnızca bir kısmını.

Yeniden yapsam yine şöyle yapardım: partiler halinde içe aktar, her partiden sonra eksik dosyaları parti hâlâ küçükken kontrol et. Görseller yerelleştiğinde jekcms'in medya hattı devreye girip hepsini 1920px sınırıyla AVIF/WebP'ye dönüştürüyor — o hattın nasıl çalıştığını ayrıca yazdım.

Slug çakışmalarına hazırlıklı olun — ve satırları sayın

Ben birden fazla WordPress sitesini birleştiriyordum; kaynaklar arasında slug çakışması kaçınılmazdı. jekcms, slug'ı zaten var olan yazıları kopya üretmek yerine atlayabiliyor. Güvenli tekrar koşular için tam istediğiniz şey — yarıda kesilen bir içe aktarma baştan değil kaldığı yerden sürdürülür — ama sessizce atlanan her satır, aynı zamanda sessizce eksik kalan bir yazıdır. Benim alışkanlığım: CSV'deki satırları say, içe aktarma sonrası yazıları say; aradaki fark yuvarlama hatası değil, iş listesidir.

WordPress'in kendi eklediği -2, -3 soneklerine ve tuhaf harf çevrimli eski slug'lara dikkat. Göçün ortasında bunları "temizleme" dürtüsüne direnin: slug URL'dir, URL de sıralamalarınızın yaşadığı yerdir. Göç sırasında slug değiştirmek, Google sıralamalarını öldüren klasik CMS hatalarından biridir.

Kategori işi göçten önce yapılır

Kategoriler ve etiketler slug'a göre eşleştirilir: aynı slug'a sahip bir kategori jekcms'te zaten varsa gelen yazılar oraya dosyalanır; WordPress'in varsayılan "Uncategorized" kovası ise içeri alınmak yerine atlanır. Yazarlarda da benzer mantık işler — önce e-posta, sonra slug ile eşleştirme; eşleşme varsa jekcms yalnızca boş profil alanlarını doldurur, ayarladığınız hiçbir şeyin üzerine yazmaz.

Slug eşleştirmesi makul; ama on yıllık taksonomi savrukluğunu onaramaz. Sitelerimden birinde "incelemeler", "inceleme" ve "urun-incelemeleri" yıllar içinde ayrı ayrı yazı biriktirmişti — ve üçü ayrı kategori olarak geldi, çünkü bilgisayara göre üç ayrı şeyler. Birleştirmeyi dışa aktarmadan önce WordPress'te yapın ya da CSV'deki kategori sütununu düzenleyin. Sonradan jekcms'te yapmak, yazıları elle yeniden atamak demek; hangi benzer kategorinin "asıl" olduğunu bilen bir sorgu yok.

Kısa kodlar: elinden geleni yapan bir temizlik

İsteğe bağlı "İçeriği biçimlendir" adımı yaygın WordPress kalıntılarını hallediyor: [caption] düzgün <figure>/<figcaption> işaretlemesine dönüşür, [gallery] temizlenir, [embed] çıplak URL'ye açılır, artakalan Gutenberg blok yorumları silinir. Sayfa oluşturucu işaretlemesi — Elementor, Divi ve akrabaları — işlenmez; etkilenen yazılarda elle geçiş ister. Benim siteler baştan beri düz editör kullanıyordu, bu dertten büyük ölçüde kurtuldum; tek başına [caption] dönüştürücüsü bile beni yığınla elle düzenlemeden kurtardı.

SQL'e hiç dokunmak istemiyorsanız?

Bunun için resmî bir WordPress eklentisi var: jekcms-migrator, şu anda wordpress.org eklenti inceleme sürecinde. wp-admin içinden çalışıyor ve tek satır sorgu yazmadan içeriği karşıya aktarıyor. jekcms tarafında ayrıca bir göç sihirbazı da var. Küçük ve derli toplu bir site için rahat yol bunlar; büyük ya da dağınık bir veritabanında ben hâlâ SQL→CSV'yi tercih ediyorum, çünkü her satırı yeni sisteme girmeden önce görüp düzenleyebiliyorsunuz. Üç yolun ayrıntısı dokümantasyonda; taşınıp taşınmama sorusunu hâlâ tartıyorsanız WordPress'ten neden ayrıldığımı ayrıca yazdım.

Bitti demeden önce

  • Önce jekcms veritabanını yedekleyin. İçe aktarma ekleme yapar; yine de 3.000 satır inmeden önce temiz bir dönüş noktası isteyeceksiniz.
  • Kısaltılmış bir CSV ile deneyin. İçe aktarma sizin kontrolünüzdeki bir dosyadan çalışır — birkaç düzine satıra indirip görseller dahil tüm akışı prova edin.
  • Yönlendirmeleri elle planlayın. Tarih tabanlı kalıcı bağlantılar, /?p=123 URL'leri ve eski kategori yolları otomatik yönlendirilmez. Hangileri önemliyse DNS taşınmadan önce yönlendirme yöneticisine ekleyin.
  • Site haritasını yeniden gönderin. Doğal taramayı beklemek yerine yeni /sitemap.xml'i Search Console'a iletin.
  • Yorumları yoklayın. İçe aktardıysanız, WordPress'in kaçırdığı bir miktar spam da beraberinde gelmiştir.

Üç bin yazının ardından dürüst özetim şu: göç, özellik listesinin ima ettiğinden uzun, korktuğumdan kısa sürdü. Asıl istediği şey dikkatti — karakter setlerine, dosya yollarına, slug'lara. Veriyi içe aktarıcı taşıyor. Muhakeme hâlâ sizin işiniz.

Yazar

Celil Uyanıkoğlu

25 yılı aşkın süredir bilgi işlem sektöründe çalışan bir bilgisayar mühendisi. jekcms'i geliştiriyor ve kendi yayın ağındaki sitelerin tamamını jekcms üzerinde çalıştırıyor — burada yayımlanan her rehber önce o canlı kurulumlarda denenir.

Tüm yazılarını gör →

Hemen Sipariş Verin

Tek seferlik ödeme, ömür boyu erişim. Kurulum 30 dakika.

Fiyatlara Bak
  • 30 dakikada kurulum ve yayın
  • 13 profesyonel tema
  • AVIF/WebP görsel optimizasyonu
  • Otomatik SEO — Sitemap, Schema.org
  • ZeroTrack çerezsiz analitik

Yeniliklerden ilk sen haberdar ol

Yeni özellikler, sürüm notları ve CMS rehberleri — ayda birkaç e-posta, spam yok.