Türkçe İ, CSS ve büyük harfle yazılan İngilizce terimler
Türkçe bir sayfada text-transform: uppercase, i harfini İ yapar. Türkçe kelimeler için doğru, JavaScript ya da Firebase için yanlış. Bu sitede sorunu elle tutulan bir kelime listesiyle değil, iki dilli verinin kendisiyle çözdüm; aynı kural paylaşım kartlarında da çalışıyor.
01Tarayıcı aslında haklı
Bu sitede küçük mono yazılar, etiketler, filtre düğmeleri ve menü bağlantıları CSS ile büyük harfe çevriliyor. base.css içinde .mono, .tag, .chip ve .lk sınıflarının hepsinde text-transform: uppercase var. Kaynakta metin küçük harfle duruyor; büyütme işini tarayıcı, metni ekrana çizerken yapıyor.
Tarayıcı bunu yaparken dile bakıyor, çünkü büyük-küçük harf dönüşümü evrensel değil. İngilizcede i büyüyünce I olur. Türkçede ise dört harf iki ayrı çift oluşturur: noktasız ı ile I, noktalı i ile İ. Sayfa lang="tr" olduğunda tarayıcı Türkçe eşlemeyi uyguluyor ve "Mühendislik" etiketi MÜHENDİSLİK oluyor. İstediğimiz tam olarak bu. Aynı kelime lang="en" altında MÜHENDISLIK olurdu ki bu da Türkçe okuyan biri için yanlış.
Sorun, aynı kuralın teknoloji ve proje adlarına da uygulanması. JavaScript JAVASCRİPT, Firebase FİREBASE, Linux LİNUX oluyor. Tarayıcı burada hata yapmıyor; metnin Türkçe olduğunu ona biz söylüyoruz. Sitede <html lang> değeri App.vue içinde useHead ile URL'den gelen dile bağlı. Yani Türkçe sayfalarda, aksi belirtilmedikçe, her şey Türkçe kuralla büyüyor.
02İlk deneme: kelime listesi
İlk refleksim, İngilizce kalması gereken kelimeleri bir listede toplayıp eşleşen etiketlere lang="en" vermek oldu. Demo içerikle çalıştı. Sonra projelere ve Hakkımda sayfasına gerçek içerik girdi: araç listesine Go, Dart, gRPC, Kubernetes ve NVIDIA Jetson Nano geldi, proje adları ve ilgi alanları değişti. Liste bir anda eskidi ve etiketler yine noktalı İ ile görünmeye başladı.
Listenin asıl kusuru eskimesi değildi, eskidiğini kimseye söylememesiydi. Yeni bir araç eklediğimde hiçbir şey kırılmıyor, build geçiyor, yalnızca bir etiket sessizce yanlış görünüyordu. Bu tür hatalar ancak biri sayfaya dikkatle baktığında fark ediliyor.
Elle tutulan bir liste, içerik büyüdükçe sessizce bozulur.
03Kural: iki dilde aynıysa isimdir
Site zaten iki dilli. Her etiketin src/i18n/locales altında bir Türkçe, bir de İngilizce karşılığı var ve bu veri, listenin tutmaya çalıştığı bilgiyi zaten içeriyor. Bir etiket iki dilde birebir aynıysa çevrilmemiş demektir; çevrilmeyen şey de neredeyse her zaman bir isim ya da terimdir: Linux, Firebase, Motice, Blockchain. Farklıysa (Sensör haberleşmesi / Sensor communication) bir çeviridir ve sayfanın dilinde kalmalıdır.
export const sameInBoth = (a: string | undefined, b: string | undefined) =>
a !== undefined && a === b ? 'en' : undefined
/** Project stacks: always technology names. */
export const STACK_LANG = 'en'
export const catLang = (c: ProjectCat | 'all') =>
sameInBoth(tr.cats[c], en.cats[c])
export const toolTagLang = (group: number, item: number) =>
sameInBoth(tr.about.tools[group]?.items[item], en.about.tools[group]?.items[item])Fonksiyon ya "en" ya da undefined döndürüyor. undefined bilinçli bir seçim: Vue, değeri undefined olan bir özelliği DOM'a hiç yazmıyor, böylece etiket sayfanın dilini miras alıyor. Bileşenlerde yapılan tek şey :lang="catLang(c)" yazmak. Aynı kuraldan geçen dört yardımcı var: proje kategorileri için catLang, ana sayfadaki alan etiketleri için fieldTagLang, Hakkımda sayfasındaki araçlar için toolTagLang ve ilgi alanları için outsideLang.
Teknoloji yığınları ayrı bir durum. Projelerin stack listesi tek ve dilden bağımsız bir diziden geliyor; karşılaştırılacak ikinci bir dil yok. Oradaki her öğe zaten bir teknoloji adı olduğu için ProjectView doğrudan STACK_LANG, yani "en" kullanıyor.
04CatLabel ve sınır durumları
Bir projenin birden fazla kategorisi olabiliyor ve bunlar "Web / Platform · Mobil" gibi tek satırda gösteriliyor. Satırın tamamına tek bir lang vermek yanlış olurdu: Blockchain İngilizce kuralla, Mobil Türkçe kuralla büyümeli. CatLabel.vue bu yüzden her kategoriyi kendi span'ine koyuyor ve her span'e kendi lang değerini veriyor; aradaki ayraçlar sayfanın dilinde kalıyor.
Kuralın sınırlarını da bilmek gerekiyor. Karşılaştırma tam eşitlik arıyor ve büyük-küçük harfe duyarlı. "Web / Platform" ile "Web / Platforms" farklı olduğu için Türkçe kuralla büyüyor; içinde i olmadığından sonuç değişmiyor. "Edge sistemler" Türkçede kalıyor ve EDGE SİSTEMLER oluyor; kelimenin yarısı Türkçe olduğu için bu doğru. Alan ve araç etiketleri dizideki sırayla eşleşiyor, yani Türkçe ve İngilizce listelerin sırası kayarsa kural yanlış iki etiketi karşılaştırır. Bir Türkçe kelime İngilizce karşılığıyla tesadüfen aynı yazılırsa kural onu isim sanar; şu anki etiketlerde böyle bir örnek görmedim. Bunları bilerek kabul ettim, çünkü iki dil dosyası zaten aynı yapıyı paylaşıyor.
05Aynı kural paylaşım kartlarında
Her sayfanın 1200×630 paylaşım kartı build sırasında Satori ile çiziliyor ve kartın üstündeki bölüm etiketi orada da büyük harfle yazılıyor. Ama Satori'de lang özelliği ve text-transform ile çalışan bir sayfa yok; büyütmeyi JavaScript yapıyor. toLocaleUpperCase('tr') ile toLocaleUpperCase('en') arasındaki fark, CSS'teki lang farkının birebir karşılığı. scripts/seo-files.mjs, kategori etiketleri için aynı karşılaştırmayı tekrar ediyor.
const up = (s) => s.toLocaleUpperCase(lang === 'en' ? 'en' : 'tr')
// same rule as src/utils/lang.ts
const upCat = (c) => (tr.cats[c] === en.cats[c]
? d.cats[c].toLocaleUpperCase('en')
: up(d.cats[c]))Böylece sitede BLOCKCHAIN olarak görünen bir kategori kartta BLOCKCHAİN olmuyor. Kural iki yerde yazılı ama ikisi de aynı veriye bakıyor; yeni bir kategori eklediğimde ikisini ayrıca güncellemem gerekmiyor.
06Başka bir projede yeniden kullanmak
Bu yaklaşımı taşımak için iki dilli içerik şart değil, ama işi çok kolaylaştırıyor. Genel fikir üç parçadan oluşuyor: büyük harf dönüşümünü dilden bağımsız sanmamak, lang özelliğini sayfa düzeyinde değil metin parçası düzeyinde düşünmek ve "bu İngilizce mi" kararını elle değil veriden çıkarmak. Tek dilli bir sitede bile terimleri ayrı bir alanda tutup onlara lang="en" vermek, bir kelime listesinden daha dayanıklı. Büyütmeyi CSS'e bırakmanın da bir yan faydası var: kaynakta metin doğal halinde kalıyor ve aynı veri büyük harf gerekmeyen yerlerde olduğu gibi kullanılabiliyor.