İçeriğe geç
academia.sh

Ders 23 / 25

Yerelleştirme Gereksinimleri

Biçimlemenin yerel ayardan türetilmesi, çoğul biçimi sayısının dile göre değişmesi, kısa dizgilerin orantılı olarak daha çok uzaması, dizgi birleştirmenin sözcük sırasını gömmesi ve çeviri kapsamının ölçülmesi.

İçindekiler

Önceki iki ders arayüz metnini tek bir dilde ele aldı: rehber kuralları ve hata iletisinin yapısı. Katalog başka bir dile açıldığında metnin kendisi kadar çevresi de değişir. Aynı düğme yazısı bazı dillerde iki katına çıkar ve kutusuna sığmaz; tarih, sayı ve yüzde biçimleri değişir; “kayıt bulundu” gibi bir cümlenin sözcük sırası dilden dile aynı kalmaz.

Bu ders yerelleştirmeyi çeviri işi olarak değil, arayüzün taşıması gereken bir esneklik olarak ele alır. Esnekliğin ölçüleri vardır ve hepsi hesaplanabilir.

Biçimleme Metnin Parçası Değildir

Tarih, sayı, yüzde ve para birimi arayüz metnine yazılmaz; yerel ayardan türetilir. Aşağıdaki hesap aynı değerin altı yerel ayardaki karşılığını üretir ve çoğul kurallarını sayar.

// yerel.mjs — metin uzamasi, bicimleme ve cogul kurallarinin yerel ayardan turetilmesi

const DILLER = ["tr", "en", "de", "fr", "ru", "ja"];

// 1. Bicimleme: ayni deger, alti yerel ayar.
const TARIH = new Date(Date.UTC(2026, 7, 12, 9, 30));
const SAYI = 1234567.89;
console.log("yerel  tarih (uzun)            sayi              yuzde");
for (const d of DILLER) {
  const tarih = new Intl.DateTimeFormat(d, { dateStyle: "long", timeZone: "UTC" }).format(TARIH);
  const sayi = new Intl.NumberFormat(d).format(SAYI);
  const yuzde = new Intl.NumberFormat(d, { style: "percent", maximumFractionDigits: 1 }).format(0.427);
  console.log(`${d.padEnd(6)} ${tarih.padEnd(24)} ${sayi.padEnd(17)} ${yuzde}`);
}

// 2. Cogul kurallari: kac ayri bicim gerekiyor?
console.log("\nyerel  gereken cogul bicimi  1        2        5        11       0.5");
for (const d of DILLER) {
  const kural = new Intl.PluralRules(d);
  const bicimler = new Set([0, 1, 2, 3, 5, 11, 21, 100].map((n) => kural.select(n)));
  const ornek = [1, 2, 5, 11, 0.5].map((n) => kural.select(n).padEnd(8)).join(" ");
  console.log(`${d.padEnd(6)} ${String(bicimler.size).padStart(18)}  ${ornek}`);
}

// 3. Liste birlestirme: dizgi toplama neden kirilir?
console.log("\nyerel  liste birlestirme (uc oge)");
for (const d of DILLER) {
  const liste = new Intl.ListFormat(d, { style: "long", type: "conjunction" })
    .format(["gökbilim", "meteoroloji", "arşivcilik"]);
  console.log(`${d.padEnd(6)} ${liste}`);
}

// 4. Metin uzamasi: kisa dizgiler orantili olarak daha cok uzar.
// Olcum yerine kural: uzunluga gore beklenen uzama pay araligi.
const UZAMA = [
  { altSinir: 1,  ustSinir: 10,  pay: 2.0 },
  { altSinir: 11, ustSinir: 20,  pay: 1.8 },
  { altSinir: 21, ustSinir: 30,  pay: 1.6 },
  { altSinir: 31, ustSinir: 50,  pay: 1.4 },
  { altSinir: 51, ustSinir: 70,  pay: 1.3 },
  { altSinir: 71, ustSinir: 999, pay: 1.15 },
];
const payBul = (n) => UZAMA.find((u) => n >= u.altSinir && n <= u.ustSinir).pay;

const ARAYUZ = [
  { anahtar: "dugme.odunc", metin: "Ödünç al", kutu: 120 },
  { anahtar: "dugme.iptal", metin: "İptal", kutu: 90 },
  { anahtar: "etiket.raf", metin: "Raf kodu", kutu: 110 },
  { anahtar: "baslik.sonuc", metin: "Arama sonuçları", kutu: 220 },
  { anahtar: "yardim.isbn", metin: "ISBN 13 hane olmalı; çizgi kodun altında yazar.", kutu: 420 },
];
const KARAKTER_GENISLIGI = 8; // px, gövde metni için ortalama
console.log("\nanahtar         karakter  pay   en genis hal (px)  kutu  sigar mi");
for (const a of ARAYUZ) {
  const pay = payBul(a.metin.length);
  const genislik = Math.ceil(a.metin.length * pay * KARAKTER_GENISLIGI);
  console.log(
    `${a.anahtar.padEnd(15)} ${String(a.metin.length).padStart(8)} ${pay.toFixed(2).padStart(5)} ` +
      `${String(genislik).padStart(17)} ${String(a.kutu).padStart(5)}  ${genislik <= a.kutu ? "evet" : "HAYIR"}`
  );
}

// 5. Dizgi birlestirme tuzagi: parcali cumle ile tam cumle.
const parcali = (n) => "Toplam " + n + " kayıt bulundu";       // parcalar ayri cevrilir
const tam = (n, dil) =>
  new Intl.NumberFormat(dil).format(n) +
  ({ tr: " kayıt bulundu", en: " records found" }[dil] ?? " kayıt bulundu");
console.log("\nparcali kurulum : " + parcali(1234567));
console.log("tam kurulum (tr): " + tam(1234567, "tr"));
console.log("tam kurulum (en): " + tam(1234567, "en"));
console.log("  -> parcali kurulumda sayi bicimlenmez ve sozcuk sirasi sabitlenir.");

// 6. Ceviri kapsami: eksik anahtar denetimi.
const KATALOG = {
  tr: { "dugme.odunc": "Ödünç al", "dugme.iptal": "İptal", "etiket.raf": "Raf kodu", "baslik.sonuc": "Arama sonuçları", "yardim.isbn": "ISBN 13 hane olmalı." },
  en: { "dugme.odunc": "Borrow", "dugme.iptal": "Cancel", "etiket.raf": "Shelf mark", "baslik.sonuc": "Search results" },
  de: { "dugme.odunc": "Ausleihen", "dugme.iptal": "Abbrechen" },
};
const anahtarlar = Object.keys(KATALOG.tr);
console.log("\ndil  ceviri  kapsam  eksik anahtarlar");
for (const [dil, tablo] of Object.entries(KATALOG)) {
  const eksik = anahtarlar.filter((a) => !(a in tablo));
  console.log(
    `${dil.padEnd(4)} ${String(Object.keys(tablo).length).padStart(6)}  ` +
      `%${String(Math.round((100 * (anahtarlar.length - eksik.length)) / anahtarlar.length)).padStart(4)}  ${eksik.join(", ") || "-"}`
  );
}
yerel  tarih (uzun)            sayi              yuzde
tr     12 Ağustos 2026          1.234.567,89      %42,7
en     August 12, 2026          1,234,567.89      42.7%
de     12. August 2026          1.234.567,89      42,7 %
fr     12 août 2026             1 234 567,89      42,7 %
ru     12 августа 2026 г.       1 234 567,89      42,7 %
ja     2026年8月12日               1,234,567.89      42.7%

yerel  gereken cogul bicimi  1        2        5        11       0.5
tr                      2  one      other    other    other    other   
en                      2  one      other    other    other    other   
de                      2  one      other    other    other    other   
fr                      2  one      other    other    other    one     
ru                      3  one      few      many     many     other   
ja                      1  other    other    other    other    other   

yerel  liste birlestirme (uc oge)
tr     gökbilim, meteoroloji ve arşivcilik
en     gökbilim, meteoroloji, and arşivcilik
de     gökbilim, meteoroloji und arşivcilik
fr     gökbilim, meteoroloji et arşivcilik
ru     gökbilim, meteoroloji и arşivcilik
ja     gökbilim、meteoroloji、arşivcilik

anahtar         karakter  pay   en genis hal (px)  kutu  sigar mi
dugme.odunc            8  2.00               128   120  HAYIR
dugme.iptal            5  2.00                80    90  evet
etiket.raf             8  2.00               128   110  HAYIR
baslik.sonuc          15  1.80               216   220  evet
yardim.isbn           47  1.40               527   420  HAYIR

parcali kurulum : Toplam 1234567 kayıt bulundu
tam kurulum (tr): 1.234.567 kayıt bulundu
tam kurulum (en): 1,234,567 records found
  -> parcali kurulumda sayi bicimlenmez ve sozcuk sirasi sabitlenir.

dil  ceviri  kapsam  eksik anahtarlar
tr        5  % 100  -
en        4  %  80  yardim.isbn
de        2  %  40  etiket.raf, baslik.sonuc, yardim.isbn

Çıktının ilk bölümü tek bir tarihin ve tek bir sayının altı ayrı görünümünü veriyor: ayıraçlar değişiyor, ay adının yeri değişiyor, yüzde işareti kimi dilde önde kimi dilde arkada duruyor ve arada boşluk olup olmadığı bile dile bağlı. Bu farkların hiçbiri tasarımcının kararı değildir; kararın tamamı yerel ayara aittir.

Kural şudur: biçimleme çalışma zamanında yapılır. Metin kataloğuna “12 Ağustos 2026” yazmak, o dizgiyi bir dilde dondurmaktır; katalog yalnız kalıbı taşır, değeri biçimleyici üretir.

Çoğul İki Biçimden İbaret Değildir

İkinci bölüm sık yapılan bir varsayımı yıkıyor. Türkçe, İngilizce, Almanca ve Fransızca iki çoğul biçimiyle yetinirken Rusça üç ayrı biçim gerektiriyor; Japoncada ise sayıya göre biçim değişmiyor. Ondalık sayılar da ayrı davranıyor: Fransızcada 0.5 tekil biçimi alıyor, Türkçede almıyor.

Bunun sonucu doğrudandır: “1 kayıt” ve “N kayıt” biçiminde iki dallı bir kurulum, üç biçim gerektiren dilde yanlış metin üretir. Doğru kurulum çoğul biçimini yerel ayardan sorar ve her biçim için ayrı bir metin tutar. Aynı şey liste birleştirmede de geçerlidir: üçüncü bölümdeki çıktı, virgül ve bağlacın dilden dile değiştiğini — Japoncada bağlacın hiç kullanılmadığını — gösteriyor.

Metin Uzaması Bir Düzen Kısıtıdır

Dördüncü bölüm uzamayı ölçüyor. Kural şudur: kısa dizgiler orantılı olarak daha çok uzar. Sekiz karakterlik bir düğme yazısı iki katına çıkabilirken elli karakterlik bir yardım metni yaklaşık yüzde kırk uzar. Nedeni, kısa metinlerin çoğu dilde tek bir sözcükle karşılanamamasıdır.

Hesap üç bileşenin en geniş hâlinin kutusuna sığmadığını gösteriyor. Bu bulgu tasarım aşamasına aittir: kutuların sabit genişlikte verilmesi, arayüzü tek dile bağlar. Çözüm iç boşluğa göre büyüyen kutular, satır kaymasına izin veren düzen ve — Düzen ve Aralık konusundaki kuralla — genişliğin içerikten türetilmesidir.

Ölçünün kendisi bir tahmindir ve tahmin olduğu söylenmelidir; gerçek uzama çeviri yapıldıktan sonra ölçülür. Tahminin işlevi, çeviri gelmeden önce hangi bileşenlerin riskli olduğunu göstermektir.

Dizgi Birleştirme Çeviriyi Bozar

Beşinci bölüm parçalı kurulumla tam kurulumu karşılaştırıyor. Parçalı kurulumda sayı ham hâliyle yapıştırılır ve sözcük sırası koda gömülür: “Toplam “ + n + “ kayıt bulundu”. Bu yapı iki şeyi birden kaybeder — sayı biçimlenmez ve çevirmen sözcük sırasını değiştiremez.

Doğru kurulum tek bir kalıp tutar ve değerleri adlandırılmış yuvalarla yerleştirir. Böylece çevirmen yuvaları kendi dilinin sırasına göre taşıyabilir, sayı da yerel ayara göre biçimlenir. Bu, Uluslararasılaştırma dersinde kurulan kuralın arayüz metni tarafındaki karşılığıdır.

Kapsam Ölçülür

Son bölüm çeviri kapsamını sayıyor. Eksik anahtar bir kusur değil, bir durumdur: çeviri her zaman koddan geride gelir. Önemli olan eksikliğin görünür olması ve bir yedek davranışın tanımlanmasıdır — eksik anahtar için hangi dilin metni gösterilecek ve arayüzde bu durum nasıl işaretlenecek.

Kapsam ölçümü aynı zamanda bir yayın ölçütüdür: bir dil, kapsamı belli bir eşiğin altındayken kullanıcıya sunulmaz. Eşiğin sayısı ürüne göre değişir; ölçümün varlığı değişmez.

Özet

  • Tarih, sayı ve yüzde biçimleri metnin parçası değildir; çalışma zamanında yerel ayardan türetilir — aynı değer altı yerel ayarda altı ayrı görünüm alır.
  • Çoğul biçimi sayısı dile bağlıdır: modelde bir dil üç biçim gerektiriyor, bir dil hiç ayırt etmiyor; iki dallı kurulum bu dillerde yanlış metin üretir.
  • Kısa dizgiler orantılı olarak daha çok uzar; sabit genişlikli kutular arayüzü tek dile bağlar ve modelde üç bileşen en geniş hâlinde kutusuna sığmıyor.
  • Dizgi birleştirme sözcük sırasını koda gömer ve sayıyı biçimlenmemiş bırakır; kalıp ve adlandırılmış yuva bu iki sorunu birden çözer.
  • Çeviri kapsamı ölçülür ve eksik anahtar için yedek davranış tanımlanır; kapsam bir yayın ölçütüdür.

Sonraki Adım

Bu dersin bütün örnekleri soldan sağa yazılan dillerdeydi. Arayüz sağdan sola yazılan bir dile açıldığında değişen şey yalnız metnin yönü değildir: düzenin kendisi aynalanır, simge yönleri anlam değiştirir, sayılar ve gömülü Latin harfli terimler kendi yönlerini korur. Sonraki ders yön duyarlı düzen kararlarını ele alır ve fiziksel özelliklerle mantıksal özellikler arasındaki farkın neden bir çeviri sorunu değil bir mimari karar olduğunu hesapla gösterir.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat