Tuzaklar¶
Bu site otuz beş dile çevrilmiştir ve bu dil sürümlerinin her biri, bu belgelerin öğrettiği döngü çalıştırılarak üretilmiştir. Sektör ölçülerine göre bu küçük bir derlemdir ve yine de i18n'i göründüğünden zor kılan tuzakların çoğuna düşmeye yetmiştir.
Aşağıdaki her bölüm, burada gerçekten ters giden bir şeydir: o an nasıl göründüğü ve kütüphanenin sizin için denetlediği şeyle sizin muhakemenize kalan şey arasındaki çizginin nereye düştüğü.
Bir değişkeni yeniden adlandırmak bir cümleyi yeniden çevirtir¶
msgid katalog anahtarıdır ve interpolasyona giren bir ad onun içindedir.
Bir sabiti modül kapsamına taşıyıp Python biçem alışkanlığının istediği gibi
büyük harfe çevirmek — author'ı AUTHOR yapmak —
Copyright © 2026 {author} · MIT License mesajını hiçbir kataloğun daha önce
görmediği bir mesaja dönüştürdü. O satırın her dildeki her çevirisi, okurun
görebileceği hiçbir şeyi değiştirmeyen bir yeniden adlandırma uğruna fuzzy
çevrimine geri gidecekti.
Kütüphane sizi durdurmaz: iki yazım da geçerli birer yer tutucu adıdır. Yaptığı şey, o adı korunmaya değer kılmaktır — bir interpolasyon yalın bir ad olmak zorundadır; dolayısıyla katalog anahtarındaki şey, bir çevirmenin okuyabileceği bir kelimedir, bir ifade değil.
Bunun aynadaki hali yapısı gereği güvenlidir. Dönüşümler ve biçim belirtimleri
msgid'nin parçası değildir; bu yüzden {amount:,.2f} biçimini {amount:,.0f}
olarak sıkılaştırmak hiçbir anahtarı değiştirmez ve hiçbir yerde hiçbir
çeviriyi geçersizleştirmez.
nplurals=2, iki farklı dizgi demek değildir¶
Türkçe, Macarca, Farsça ve Bengalce iki çoğul biçim bildirir ve dördünde de
sayılan bir mesajın iki biçimi meşru olarak aynı dizgidir — ad bir sayıdan
sonra tekil kaldığı için {n} sayfa hem bir sayfa hem on sayfa için doğrudur.
Yinelemeyi "düzelten" bir gözden geçiren, çeviriyi bozar.
Ters yöndeki hata da bir o kadar kolaydır. Letoncanın üçüncü biçimi
yalnızca sıfır için vardır; Slovencenin ikincisi bir ikildir, tam
olarak iki içindir; Romencenin son biçimi, ilk ikisinde bulunmaması gereken
de kelimesini gerektirir. Bu yuvaları bir tekil ve bir çoğulla doldurmak,
yalnızca kimsenin denemediği sayılar için yanlış olan bir katalog üretir.
Daha kötüsü, yuvaların sırası anlamsal değildir. Galce beş biçimini öyle
numaralar ki msgstr[0] genel durumdur ve msgstr[1] tekildir. Onları akla
ilk gelen sırayla doldurmak, tekili sayısız her mesajın bulacağı yere koyar.
Kütüphane bunların hiçbirini üstlenmez ve mesele de budur: hedef dilin çoğul kuralı kendi kataloğunun başlığında yaşar ve birleşim/kesişim kuralı bir çevirinin kaynaktan daha çok ya da daha az biçimi olmasına izin verir. Denetlediği şey, dili bilmeden denetleyebileceği tek şeydir — her biçimin ihtiyaç duyduğu yer tutucuları koruduğu.
İki biçim bir sebeple birebir aynı olabilir¶
İrlandacanın beş çoğul biçimi vardır ve bu sitenin derleme raporunda bunların
birkaçı aynı yazılır. Bu bir kopyala-yapıştır kazası değildir: leathanach
l ile başlar ve İrlandaca sayıların tetiklediği iki baş mutasyonun ikisi de
l üzerinde yazıya dökülmez. Biçimler yine de gerçek iş görür — gövde
leathanach ile leathanaigh arasında değişir ve ondan büyük sayılar tekile
döner — ama "sayfa" anlamına gelen hiçbir ad bu karşıtlığı göstermezdi.
Yinelenen biçimleri şüpheli diye işaretleyen her denetim, doğru İrlandacayı işaretleyecektir. Bunun tek gözden geçireni, dili bilen bir insandır.
Bir mesaj yalnızca tek bir sayıyla uyuşabilir¶
Bu sitenin derleme raporu, kaç sayfanın render edildiğini ve bunun ne kadar
sürdüğünü söyler. Bunu "Rendered {n} pages in {seconds} seconds" diye yazmak
zararsız görünür ve çevrilebilir değildir: gettext tek bir sayıdan tek bir
biçim seçer ve o sayı n'dir. seconds kelimesinin, çoğul düzeneğinin hiç
görmediği bir sayıyla uyuşması gerekirdi.
Çözüm, ikinci niceliği bir kelime yerine bir birim simgesi yapmaktır; birim
simgelerinin kendileri de yerelleştirilir: bu sitenin katalogları s, с,
ث, שנ׳ ve mp taşır ve Fransızca, İspanyolca ve İsveççe dizgi geleneği,
İngilizcenin istemediği bir boşluğu simgeden önce ister. Bunların hiçbiri
kütüphanenin işi değildir — ama bir mesajın iki uyuşmaya ihtiyaç duyduğunu
fark etmek işin bir parçasıdır ve bunun tek aracı, mesajı başka türlü
yazmaktır.
Bir İngilizce cümleyi düzenlemek yabancı dil bilgisini düzenler¶
Ana sayfa eskiden "all ten language editions" diyordu. Sayının kaldırılması — tek kelimelik bir İngilizce düzenleme; sayı sürekli bayatladığı için yapıldı — çoğul bir özneyi tekile çevirdi. İspanyolca, İtalyanca, Portekizce, Rusça, Ukraynaca, Yunanca, Felemenkçe ve İbranice sürümlerin hepsinde yüklemin uyumu yeniden kurulmak zorunda kaldı; birkaçında ortacın da değişmesi gerekti.
İngilizcede önemsiz okunan bir kaynak düzenlemesi, akışın aşağısında önemsiz
değildir. pybabel update'in yaptığı şey olan fuzzy işaretleme, her çevirmene
bunu fark etme şansını veren düzenektir.
Görülemeyen farklar her kopyala-yapıştırdan sağ çıkar¶
Kılavuz, (nаme) içeren bir tanıyı alıntılar — bilerek konmuş bir kaçış,
çünkü adlandırdığı karakter, hiçbir okurun Latin olanından ayırt edemeyeceği
bir Kiril а harfidir. Bu sitenin çevirmenleri o kaçışı beş ayrı kez, beş
farklı dilde, karakterin kendisine dönüştürdü ve her seferinde doğru görünen,
yanlış olan bir sayfa üretti.
Bunu kütüphane gerçekten yakalar ve tanıların bu biçimde tasarlanmış olmasının sebebi de budur: harfleri yazı sistemlerini karıştıran bir yer tutucu iki kez raporlanır — bir kez okunur biçimde, bir kez kaçışlanmış olarak; çünkü ikisini birbirinden ayıran tek yazım, kaçışlanmış biçimdir. Ayraçların içindeki bölünmesiz bir boşluk da aynı sebeple kod noktasıyla yazdırılır. Katalog denetleyicisi, mesajı sevk edilebilmesinden önce geri çevirir.
Boş olmaması çevrilmiş olması demek değildir¶
msgid'leri msgstr'lerine kopyalanarak iskeleti kurulmuş bir katalog, her naif denetimden geçer: hiçbir şey boş değildir, hiçbir şey fuzzy değildir, mesaj kümesi tam olarak uyar. Bu sitenin bir dil sürümü birkaç saat boyunca böyle sevk edildi. Bir başka sürümün, İngilizce kaynağın bayt bayt kopyası olan sekiz sayfası da öyle — bu, aralarındaki kod bloklarını karşılaştıran bir denetimden geçer, çünkü onlar aynı dosyadır.
Bunların ikisi de bir çeviri kütüphanesinin görebileceği şeyler değildir.
İkisini de sınamak ucuzdur, ama her girdinin kaynağından farklı olmasını
şart koşarak değil: OK, ürün adları, kişi adları, kısaltmalar ve kod
tanımlayıcıları kendilerine çevrilir; bunu yasaklayan bir denetim ise sonsuza
dek yanlış pozitif üretir.
Bunun yerine oranı ölçün — bütün bir katalog ya da bütün bir sayfa üzerinden — ve aykırı değerleri bir insana gönderin. Bu sitenin kendi testi tam olarak bunu yapar: her dil sürümünün düz metin satırlarını İngilizce kaynakla karşılaştırır ve %25'in üzerinde aynılıkta başarısız olur. Sahte dil sürümü %87'deydi; gerçek çevirilerin hepsi %4 ile %8 arasında oturuyor — bu da URL'ler ve alıntılanmış program çıktısı gibi meşru biçimde çakışan satırların küçük kuyruğudur. İki küme birbirinden yeterince uzak; eşiğin hassas olması gerekmiyor.
Çevrilen tek şey katalog değildir¶
Buradaki iki hatanın gettext'le hiçbir ilgisi yoktu.
Bir başlığı çevirmek, ondan üretilen çapayı değiştirir; böylece o bölüme giren her sayfalar arası bağlantı bozulur — sessizce ve yalnızca o dilde. Bu site, her başlıkta İngilizce çapayı sabitler ve bir test, beklenen listeyi İngilizce sayfadan türetir.
Site üreticisi de arayüz çevirilerini altmış sekiz dil için sevk eder; bu diller arasında Svahili ve İrlandaca yoktur. Biri yoksa derleme İngilizceye düşerek idare etmez; şablon include'u başarısız olur ve o dil sürümü hiç derlenemez. Bu deponun kendi dosyalarından ikisi, o boşluğu doldurmak için vardır.
Sizin araçlarınızın da hataları var¶
Bu belgelerin bayat katalogları yakalamak için önerdiği CI adımı,
pybabel update --check, pgettext ya da npgettext kullanan hiçbir projede
bu işi yapamaz. Babel 2.18.0'da msgctxt taşıyan her kataloğu, her koşuda
güncel değil diye raporlar. Karşılaştırma Catalog.is_identical üzerinden
geçer; bu da her mesajı, saklandığı anahtarla arar — ve bağlamlı bir mesaj
için o anahtar, Catalog.getin kabul etmediği (id, context) çiftidir. Arama
hiçbir şey döndürmez ve kataloglar hiçbir zaman eşit çıkmaz:
>>> from babel.messages.catalog import Catalog
>>> c = Catalog(locale="ja")
>>> c.add("Guide", "ガイド", context="navigation")
<Message 'Guide' (flags: [])>
>>> c.is_identical(c)
False
Burada, kullanılmaya çalışılırken bulundu, üst akışa bildirildi ve yerine geçecek denetim üretim sayfasındadır.
Genel ders, rahatsız edici olanıdır: hep kırmızı yanan bir kapı, hiç kapı olmamasından kötüdür; çünkü ekip onu kapatır. CI denetiminizin başarısız olmasına güvenmeden önce, gerçekten geçebildiğini doğrulayın.
Kütüphane tek cümleyle ne işe yarar¶
Bu sayfanın çoğu, hiçbir aracın devralamayacağı bir muhakemedir. Bir aracın yapabileceği şey, bir çevirinin, çevirdiği cümlenin yapısını değiştiremeyeceğini güvence altına almaktır — bir değeri düşüremez, olmayan birini uyduramaz, birini yeniden biçimlendiremez ya da nesnelerinize uzanamaz — ve bunu, düzeltmek zorunda kalan kişinin üzerine harekete geçebileceği bir cümleyle söyleyebilmektir. Bu kütüphanenin verdiği sözün tamamı budur; bu sitenin geri kalanı da o sözün nasıl tutulduğudur.