🇬🇧 English: Read this article in English →

Solup gitmesini izlediğim bütün platformlar arasında beni gerçekten üzeni Drupal’dır. Gerçek bir sorunun inandırıcı cevabıydı — güvenli, kurumsal sınıf, açık kaynaklı CMS. Üniversiteler onu kullandı. Devletler onu kullandı. Beyaz Saray onu kullandı. Ciddi bir müşteri “kodu herkes görebiliyor” diye WordPress’e elini sürmediğinde, güveneceği açık kaynak sistem Drupal olurdu.

Sonra Drupal 7, Drupal 8’e dönüştü, bütün mimari Symfony üzerine yeniden kuruldu ve geçiş o kadar acımasızdı ki insanlar öylece çekip gitti. Küçük ve orta ölçekli projeler WordPress’e ve Webflow’a kaydı. Büyük kurumsal taraf headless’a ya da bir DXP’ye gitti. Drupal iki taraftan birden sıkıştı — yazılım kötüleştiği için değil, yükseltme yolu insanlardan sitelerini baştan kurmalarını istediği için; ve pek çoğu, madem yeniden kurmak zorundayım, başka bir yerde kurarım dedi.

İşte bu yüzden bu geçişi kişisel olarak sahipleniyorum. Nedenini birazdan anlatacağım. Önce, bu taşımayı yapıp yapmamaya karar veren herkes için sade dille anlatayım.

Ekipler Drupal’ı neden bırakıp WordPress’e geçiyor

Sebepler nadiren kod kalitesiyle ilgilidir. Drupal’ın kodu iyidir. Sebepler insanlarla ve zamanla ilgilidir:

  • Yetenek havuzu. Bu öğleden sonra bir WordPress developer’ı işe alabilirsin. Drupal developer’ları daha az, daha pahalı ve biri ayrıldığında yerini doldurmak daha zordur. Orta ölçekli bir kuruluş için bu, her yıl büyüyen operasyonel bir risktir.
  • Editoryal sürtünme. Drupal’ın admin’i güçlü ama affetmez. Sadece bir sayfa yayımlamak isteyen içerik editörleri, bunu yapabilmek için çoğu zaman bir developer’ın yardımına muhtaç kalır. Block editor ve ACF ile WordPress, bunun büyük kısmını editörlere geri verir.
  • Yükseltme yarası. Drupal 7 → 8’i yaşamış ekipler onu hatırlar ve her major sürümde bunu tekrar yaşamak istemezler. WordPress’in vaadi — yıllar önce kurulan bir sitenin bir güncellemeden sonra hâlâ çalışması — tam da Drupal’ın bozduğu vaattir.
  • Maliyet. Daha az developer, daha uzun build’ler ve daha ağır barındırma birikir. Bir içerik sitesi için WordPress’i çalıştırmak yalnızca daha ucuzdur.

Bu neden kişisel

Drupal’ın dersini okuyarak öğrenmedim. Aynı hatayı yapan bir CMS inşa ederek öğrendim.

Yıllar önce, o dönemde kurumsal müşterilere WordPress’i satamadığımız için, Microsoft’un ASPX yığını üzerinde kendi CMS’imizi kurduk. Onu WordPress’i model alarak yaptık, çünkü WordPress’i incelemiştik ve mimarisinin akıllıca olduğunu biliyorduk. Gerçekten iyi çıktı. Onlarca ajans üzerine iş kurdu. Ve sonra tamamen kendi elimizle ördüğümüz bir duvara tosladık: CMS’imizin hiçbir backward compatibility’si yoktu. Her yeni sürüm geçmişi unutuyordu. Bize göre bu sorun değildi — biz zaten hep en yeni build’deydik. Onu kullanan herkes için ise her sürüm bir felaketti, çünkü verileri her seferinde elle taşınmak zorundaydı. O yükü kaldıramadık. Vazgeçtik. Büyük bir banka o terk edilmiş sistemi bugün hâlâ çalıştırıyor, elle ayakta tutarak; çünkü biz çekip gittik ve onlar peşimizden gelemedi.

İçeriden bakınca Drupal 7 → 8 hikâyesi işte tam olarak budur. Geçmişi kırdığında yalnızca iş yaratmazsın — insanlara, seni takip etmeye devam edip etmemeleri gerektiğini sordurursun. WordPress tam da bunu yapmayı reddettiği için ayakta. Bugün güncelle, on yıl önceki kod büyük ölçüde hâlâ çalışsın. Bu teknik bir dipnot değil. Bir varlıkla bir yük arasındaki farkın tamamıdır ve bir Drupal geçişinin neden bu kadar sık özellikle WordPress’te bittiğinin sebebidir.

Bir Drupal geçişini nasıl planlıyorum

Drupal çoğu insanın beklediğinden daha yapılıdır ve bu bir geçiş için iyi haber — yapıya saygı gösterirsen, yapılandırılmış içerik temiz eşleşir. Yöntemim, kısaca:

  1. Modeli envanterle. Her content type, her field, her vocabulary, her paragraph type, her view, her URL alias. Taşımadan önce şekli çiz.
  2. Buda. Uzun ömürlü bir Drupal sitesi, kimsenin artık sebebini hatırlamadığı field’lar ve content type’larla doludur. Geçiş, bunları geride bırakmak için tek şansın. Kullan onu.
  3. WordPress’e eşle. Content type’lar custom post type’lara, field’lar ACF field’larına, vocabulary’ler taxonomy’lere, paragraph’lar block’lara dönüşür. Yapısını hak etmeyeni düzleştir.
  4. Önce boş hedefi kur ve içinde yaşayacak editörlerle doğrula.
  5. Staging’de tekrar tekrar dönüştür ve prova yap. Asla doğrudan production’a değil.
  6. Cutover’dan önce redirect’ler. Drupal’ın URL alias’ları burada bir hediyedir — hazır redirect haritan bunlar.
  7. Geç, sonra izlemeye devam et — ta ki editörler seni aramadan yayımlayana kadar.

Teknik Kısım: Bir Drupal Geçişi Asıl Nerede Kırılıyor

İşte sonucu ayrıntıların belirlediği yer. İşi yapan developer sensen, saklaman gereken bölüm bu.

Nodes, content type’lar ve field’lar iyi eşleşir — paragraphs eşleşmez

Drupal nodes doğal olarak WordPress post’larına, content type’lar custom post type’lara ve Field API field’ları ACF field’larına eşlenir. O kısmı keyiflidir. Tuzak Paragraphs‘ta — Drupal’ın yeniden kullanılabilir, iç içe geçebilen içerik bileşenleri; ki birçok modern Drupal sitesi sayfa kurma işinde bunlara ağır biçimde yaslanır. Birebir bir WordPress karşılığı yoktur. Her paragraph type için, onun bir Gutenberg block’una mı, bir block pattern’e mi yoksa bir ACF flexible-content layout’una mı dönüşeceğine sen karar vermek — ve sonra her tipi elle ele almak zorundasın. İç içe paragraph’lar (paragraph içinde paragraph) özellikle acı vericidir; bir dönüştürücünün doğru tahmin etmesini ummak yerine bilinçli olarak düzleştir.

Text formats ve body field

Drupal, body içeriğini bir text format üzerinden filtrelenmiş HTML olarak saklar (Filtered HTML, Full HTML, Restricted). Saklanan markup, hangi format uygulandığına bağlıdır ve Drupal’a özgü token’lar, media embed tag’leri (<drupal-media> / <drupal-entity>) ve filtre artıkları içerebilir. Bunu ham haliyle bir WordPress core/html block’una atmak çoğu zaman işe yarar, ama gömülü media tag’leri ve satır içi entity referansları render olmaz. Body field’larındaki embed kalıplarını envanterle ve onlar için handler yaz; yoksa kırık media placeholder’larıyla dolu post’lar yayımlarsın.

Taxonomy ve term-reference iki-geçişli sorunu

Vocabulary’ler WordPress taxonomy’lerine temiz dönüşür, ama term reference‘lar — node’lar arası ilişkiler gibi — WordPress’te hiçbir anlam ifade etmeyen Drupal term ID’lerini işaret eder. İki geçişte içe aktar: önce her node’u ve term’ü taşı ve eski Drupal ID’leri ile yeni WordPress ID’leri arasında bir harita kur, sonra o haritayı kullanarak her referansı ve term ataması yeniden yaz. İkinci geçiş bitene kadar orijinal Drupal nid/tid‘lerini post meta’da sakla. Term hiyerarşisine dikkat et — Drupal vocabulary’leri derinlemesine iç içe olabilir ve yalnızca term’ler değil, parent ilişkilerinin de yeniden kurulması gerekir.

Password hash’leri taşınmaz

Drupal ve WordPress parolaları farklı hash’ler ve bu hash’ler birbirinin yerine geçmez. User tablosunu öylece kopyalayamazsın. Ya cutover’da tüm kullanıcılar için bir parola sıfırlaması zorla (temiz seçenek), ya da ilk başarılı giriş anında bir Drupal parolasını yeniden hash’leyen bir köprü kur. Bunu, “sorunsuz” bir hesap geçişi vaat etmeden önce karara bağla; çünkü ilk gün sessizce çalışmayan bir login, müşterinin güvenini anında kaybetmenin yoludur. Drupal rollerini WordPress rollerine elle eşle — rol modelleri kendiliğinden hizalanmaz.

Views, block’lar ve display mantığı taşınmaz

Bu, proje yöneticilerini şaşırtan olandır. Bir Drupal sitesinin Views‘ları — listelemeleri, feed’leri, filtrelenmiş sayfaları — içerik değil, config’dir. WordPress’e export olmazlar. Her view’ın bir WordPress query’si, block’u ya da template’i olarak yeniden kurulması gerekir. Aynısı Drupal’ın block layout’ları ve her türlü özel display mantığı için de geçerlidir. Sitenin dinamik sayfalarını yeniden implemente etmek için bütçe ayır; içerik taşınır, ama onu düzenleyen makine taşınmaz.

Çok dillilik

Site Drupal’ın content translation’ını kullanıyorsa, WordPress hedefini — multisite, Polylang ya da WPML — taşımadan önce karara bağla; çünkü her biri çevirileri farklı modeller ve Drupal’ın dil-başına field değerlerini seçtiğin yapıya bölen dönüşüm hiç de basit değildir. Beş dilli multisite’lar çalıştırdım ve hep söylediğimi tekrarlayayım: çok dillilik bir çeviri sorunu değil, bir mimari sorunudur. Önce mimariye karar ver.

Media entity’ler ve dosyalar

Eski Drupal dosyaları file-field ekleri olarak saklardı; yeni Drupal ise kendi field’ları ve yeniden kullanılabilirliği olan media entity‘leri kullanır. İkisinin de indirilip WordPress media library’ye yeniden aktarılması gerekir ve her referansın — body field’larında ve media-reference field’larında — yeni attachment ID’lerine ve URL’lerine yeniden yazılması gerekir. Zengin metnin içinde referans verilen dosyaları unutma; sessizce kırılanlar tam da onlardır.

Araçlar üzerine bir not

FG Drupal to WordPress gibi eklentiler var ve dümdüz siteler için makul bir başlangıç noktası. Ama paragraph’ların, özel text format’ların, önemsiz olmayan taxonomy hiyerarşilerinin ya da çok dilli içeriğin olduğu an, eklentiyi aşarsın ve bir veritabanı snapshot’ından çalışan özel bir dönüşüme ihtiyacın olur. Drupal veritabanının snapshot’ını al, dönüşümünü donmuş kopya üzerinde çalıştır ve çıktı sıkıcı olana kadar tekrarla — asla hareket eden bir production veritabanına karşı taşıma yapma.

Dürüst kapanışım

Drupal başına geleni hak etmedi. Kritik bir sürümde kullanıcılarıyla arasındaki güveni kıran iyi bir sistemdi ve pek çoğu bir daha geri dönmedi. Kalan ekiplerden biriysen ve şimdi taşınmaya karar veriyorsan, WordPress doğal varış noktasıdır — daha güçlü olduğu için değil, tam tersi bahsi oynadığı için. Geçmişi ileriye taşımayı seçti, hiç de gösterişli olmayan bir biçimde, yirmi yıl boyunca; ve o seçim, taşınan bir Drupal ekibinin aradığı şeyin ta kendisidir.

Modeli eşle. Sert buda. Paragraph’ları ve text format’ları elle ele al. Taxonomy’yi iki geçişte yap. Parola sıfırlamalarını planla. View’ları yeniden kur. Cutover’dan önce redirect’lerini URL alias’larından kur.

Bunu yap; içerik, üç yıl sonra kimseye onu yeniden kurdurmadan doğru ve canlı kalabileceği bir yere insin — ki Drupal’ın bunu zorun yoluyla öğrenmesini izledikten ve ben de aynısını zorun yoluyla öğrendikten sonra, gerçekten önemsediğim tek sonuç budur.


Son Bir Şey: Peki Drupal’ın Yaptığını WordPress’le Yapamaz mısın?

İşte taşınmayı düşünen her ciddi Drupal ekibinden aldığım itiraz: WordPress, Drupal’ın yaptığını gerçekten yapamaz — yapılandırılmış içeriği, field’ları, taxonomy’yi, decoupled arayüzü. O sadece bir blog. Hayır. Değil; ve biz WP Clan olarak, geçişi olduğundan kolay göstermek için WordPress’i eksik anlatmayacağız. WordPress, Drupal’ın yaptığı her şeyi zaten yapıyor.

Custom post types ve ACF sana Drupal’ın content type’larını ve Field API’sini verir. Taxonomy’ler vocabulary’leri ve hiyerarşik term’leri verir. Multisite, Polylang ve WPML çok dilliliği karşılar. Ve en kritiği, WordPress bütün bunları, Drupal’ın 7 → 8’de kırdığı tek şeyin üzerine kurar: backward compatibility. Yapıyı, her major sürümde yeniden-kurma vergisini ödemeden alırsın.

Ve Drupal’da asıl sevdiğin şey decoupled, JSON:API tarafıysa — yani headless seçeneğiyse — WordPress ona da denk düşer, üstelik bu işe dün girmedi:

  • 2016 sonundan beri core’da REST API — neredeyse on yıllık saha olgunluğu, Drupal’ın JSON:API’sinin doğrudan karşılığı.
  • WPGraphQL — artık Automattic’in arkasında durduğu, kanonikleşme yolundaki katman; içeriğinin üzerinde bir GraphQL katmanı tercih ediyorsan.
  • Drupal’ın hiç sahip olmadığı ekosistem — gerçek ticaret için WooCommerce, sıfırdan yazmadığın bir eklenti ekonomisi, yalnızca developer’lar için değil insanlar için editoryal güç.
  • Kullanıcı başı ücret yok, kullanım sayacı yok ve sahiplik — WordPress’i kimse ayağının altından satın alamaz.

Drupal yapılandırılmış içeriği gerçekten iyi yapıyordu; söyledim, arkasındayım. Ama “yapılandırılmış içerik ve bir API istiyoruz” cümlesi, Drupal’ı bırakmaktan korkmak için bir sebep değil — WordPress bunların hepsini yapıyor, geçmişi yeniden-kurmaya zorlamak yerine ileri taşıyor ve üstüne sana bir ekosistem veriyor. Hiçbir şey kaybetmezsin. Alet çantasını kazanırsın.

Bir yanıt yazın

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

Close Search Window