BookTranslator
BookTranslator

Cara Menerjemahkan File Bahasa JSON Tanpa Merusak Kunci atau Placeholder

Lihat nilai mana dalam file en.json yang diterjemahkan, apa yang ditulis ulang oleh penerjemah file (komentar, urutan kunci, ID besar), dan cara memeriksa placeholder, plural ICU, serta kunci dengan skrip gratis dan file uji.

BookTranslator

BookTranslator Team

12 menit baca

Untuk menerjemahkan file bahasa JSON seperti en.json, berikan seluruh file kepada penerjemah yang memahami JSON. Menempelkan teks mentah ke jendela obrolan atau penerjemah web adalah cara yang berisiko. Penerjemah yang sadar JSON membaca file, hanya menerjemahkan nilai teks, dan menulis kunci yang sama kembali, sehingga aplikasi Anda masih dapat memuat file tersebut. Salin dan tempel dapat menerjemahkan kunci, mengubah tanda kutip, atau menghilangkan kurung kurawal. Salah satu dari itu merusak file.

Menjaga kunci adalah bagian yang mudah. Sebagian besar masalah datang setelahnya: placeholder {name} yang kembali sebagai {nom}, plural ICU yang kehilangan kasus other-nya, URL yang dikirim untuk diterjemahkan seperti teks biasa, dan beberapa perubahan yang dilakukan penerjemah pada file itu sendiri. Itulah yang dibahas dalam panduan ini.

Kami membuat file uji dengan setiap kasus tersebut di dalamnya dan menulis pemeriksa gratis yang membandingkan file sumber dengan terjemahannya. Kami juga menjalankan file uji melalui salinan lokal kode penguraian dan penulisan JSON yang digunakan BookTranslator, dengan penanda sebagai pengganti model, sehingga Anda dapat melihat dengan tepat nilai mana yang dikirim dan bagaimana file itu kembali.

Jawaban Singkat: Apa yang Terjadi pada Setiap Bagian File

Bagian fileContoh dari uji kamiApa yang dilakukan BookTranslatorApa yang perlu diperiksa
Kunci"greeting", "error"Dibiarkan apa adanyaTidak ada
Nilai teks biasa"Reading list"DiterjemahkanMakna, panjang di layar
Nilai dengan placeholder"Welcome back, {name}!", "Saved %s of %d chapters"Diterjemahkan, placeholder disertakan dalam teks yang dikirimNama dan jumlah placeholder (pemeriksa melakukan ini)
Pesan plural ICU"{count, plural, one {# book} other {# books}}"Dikirim sebagai satu stringKasus other, dan kategori plural untuk bahasa target
HTML inline"accept the <b>Terms</b>."Diterjemahkan; jumlah tag diperiksa setelah terjemahanNama dan jumlah tag (pemeriksa melakukan ini)
URL yang disimpan sebagai teks"https://example.com/help"Dikirim untuk diterjemahkanBahwa nilainya kembali tanpa perubahan
Nilai tanpa huruf"2.4.1", "—", ""Dibiarkan apa adanyaTidak ada
Angka, true/false, null20, trueDibiarkan apa adanyaID yang sangat besar (lihat di bawah)
Array string["Open", "Save", "Export as EPUB"]Diterjemahkan dalam file terjemahan; dibiarkan tidak diterjemahkan dalam file bilingualFile bilingual, jika Anda menggunakannya
Komentar (JSONC)// Shown on the home screenDihapus. Jika suatu nilai juga mengandung //, file bisa gagal dimuatHapus komentar sebelum mengunggah

Sisa panduan ini menunjukkan asal setiap baris dan apa yang harus dilakukan.

Langkah 1: Periksa File Sumber Sebelum Mengunggah

Jalankan pemeriksa pada file yang akan Anda terjemahkan. Hanya perlu Python 3, tidak perlu yang lain:

python3 check_i18n_json.py en.json

Pada file uji kami, hasilnya:

WARN  limits.projectId: 9007199254740993 is above 2^53 and can change in a JavaScript round trip; store IDs as strings
WARN  error.network: a flat key with dots and a nested key resolve to the same dot path; tools that address strings by dot path can mix them up
INFO  (root): 3 keys look like integers; JavaScript sorts those first and in numeric order when it rewrites the object
INFO  source: 17 strings, 2 numbers

Dua peringatan dan catatan tentang kunci mirip bilangan bulat masing-masing sesuai dengan perubahan yang kami lihat saat file uji kami melewati penerjemah. Jika file Anda tidak memunculkan satu pun dari itu, Anda bisa langsung ke Langkah 3.

Pemeriksa juga menolak file yang bukan JSON ketat, misalnya yang berisi komentar atau koma di akhir, karena itu masalah berikutnya.

Apa yang Kembali dari File Uji Kami

Uji dijalankan pada 2 November 2026, terhadap penanganan JSON saat ini di backend BookTranslator. Alih-alih memanggil model, uji mengganti setiap nilai yang akan dikirim untuk diterjemahkan dengan [ZH] ditambah teks asli. Itu membuat hasilnya dapat diprediksi: apa pun yang diawali [ZH] telah dikirim, yang tanpa itu tidak. Kedua keluaran dipublikasikan: file terjemahan dan file bilingual.

File terjemahan

Setiap kunci kembali tanpa perubahan, dan file tetap dapat diurai. Nilai yang mengandung huruf dikirim, termasuk {name}, %s, pesan ICU, tag <b>, dan URL bantuan. String versi "2.4.1", tanda hubung, dan string kosong tidak dikirim karena tidak mengandung huruf. Angka dan boolean dibiarkan apa adanya.

Empat hal lain berubah:

  1. Satu string masuk ke kunci yang salah. Dalam pengujian kami, file kami memiliki kunci datar "error.network" dengan teks "Check your connection." dan juga "error": { "network": "Network error" } yang bersarang. Penerjemah mengidentifikasi setiap string berdasarkan jalurnya dengan titik di antara bagian-bagiannya, sehingga kedua string memiliki alamat yang sama, error.network. Pada output, kedua kunci berisi terjemahan dari "Network error". "Check your connection." hilang. Ini memerlukan kedua gaya dalam file yang sama, yang jarang terjadi, tetapi gagal secara diam-diam. Pemeriksa memperingatkan tentang hal ini sebelum Anda mengunggah.
  2. Kunci mirip bilangan bulat diurutkan ulang. "steps": { "10": ..., "2": ..., "1": ... } kembali sebagai "1", "2", "10". JavaScript selalu mendaftarkan kunci mirip bilangan bulat terlebih dahulu, dalam urutan numerik, saat membangun ulang objek. Kunci dan nilai tetap cocok, jadi aplikasi Anda baik-baik saja, tetapi diff terhadap file sumber akan berisik.
  3. ID besar kehilangan presisi. 9007199254740993 kembali sebagai 9007199254740992. JavaScript menyimpan angka sebagai floating point 64-bit, dan bilangan bulat di atas 2^53 tidak semuanya dapat direpresentasikan secara tepat (MDN tentang Number.MAX_SAFE_INTEGER). Simpan ID panjang sebagai string, atau jauhkan dari file bahasa.
  4. Formatnya ditulis ulang. Output menggunakan indentasi dua spasi dan diakhiri dengan baris baru. Jika sumber Anda menggunakan tab atau empat spasi, perkirakan perubahan spasi dalam diff.

File pengujian kami tidak memiliki kunci duplikat, tetapi ada baiknya Anda mengetahuinya: parser JSON JavaScript hanya menyimpan nilai terakhir untuk kunci yang berulang, sehingga teks sebelumnya tidak pernah diterjemahkan. Aplikasi Anda akan memuat nilai terakhir yang sama, jadi tidak ada yang terlihat rusak, tetapi pemeriksa mendaftarkan kunci duplikat agar Anda dapat membersihkannya.

File bilingual

File bilingual mempertahankan setiap nilai asli dan menambahkan kunci saudara dengan _translated di akhir:

"greeting": "Welcome back, {name}!",
"greeting_translated": "[ZH] Welcome back, {name}!",

Itu berfungsi baik untuk peninjauan, karena sumber dan terjemahan berdampingan. Ini bukan file yang dapat dimuat aplikasi Anda, karena setiap kunci sekarang memiliki kembaran. Gunakan file terjemahan di aplikasi Anda.

Satu celah: string di dalam array tidak mendapatkan saudara _translated, karena item array tidak memiliki kunci untuk menambahkannya. Dalam pengujian kami, "menu": ["Open", "Save", "Export as EPUB"] kembali dalam bahasa Inggris di file bilingual, tetapi diterjemahkan di file terjemahan. Jika Anda meninjau dari file bilingual, periksa array di file terjemahan.

File dengan komentar

Banyak proyek menyimpan komentar di file bahasa mereka (JSONC), yang tidak diizinkan oleh JSON ketat. Penerjemah pertama-tama mencoba JSON ketat. Jika gagal, ia menghapus komentar dan koma di akhir lalu mencoba lagi. Menghapus komentar berarti menghapus semua yang ada setelah // pada suatu baris, dan itu termasuk // dalam https://.

File kami dengan komentar dan URL tidak dimuat sama sekali; penguraian gagal pada komentar pertama. File dengan komentar tetapi tanpa // di dalam nilai apa pun dimuat dengan baik, dan komentar dihapus dari output.

Jadi: jika file Anda memiliki komentar, hapus sebelum mengunggah, atau simpan salinan dengan komentar dan terima bahwa terjemahan tidak akan memilikinya.

Langkah 2: Siapkan File

Anda dapat memperbaiki sebagian besar masalah ini sebelum menerjemahkan:

  • Jadikan JSON ketat. Hapus komentar dan koma di akhir. Jika alat build Anda membaca JSONC, simpan file berkomentar sebagai sumber dan ekspor salinan bersih untuk diterjemahkan.
  • Gunakan satu gaya kunci. Baik bersarangkan kunci atau ratakan dengan titik, jangan keduanya dalam satu file. Jika Anda menggunakan i18next, opsi keySeparator mengontrol bagaimana titik dalam kunci dibaca, jadi periksa pengaturan itu sebelum meratakan apa pun.
  • Pindahkan data non-teks keluar. ID, URL, feature flag, dan batas belong in config, not in the language file. Jika URL harus tetap ada, pertahankan, tetapi perkirakan untuk memeriksanya setelah terjemahan. Panduan jangan-terjemahkan kami membahas cara memutuskan apa lagi yang harus tetap dalam bahasa asli.
  • Tulis placeholder dengan cara yang sama di mana-mana. Satu gaya, seperti {name}, lebih mudah diperiksa daripada campuran {name}, {{name}}, dan %s.

Langkah 3: Terjemahkan Seluruh File

Unggah file yang telah dibersihkan ke penerjemah dokumen BookTranslator, yang mencantumkan .json bersama format lokalisasi dan teks terstruktur lain yang diterimanya. Harga ditampilkan sebelum checkout. Saat tugas selesai, halaman riwayat Anda menawarkan file terjemahan dan file bilingual sebagai unduhan terpisah.

Ada dua hal tentang cara teks diterjemahkan yang memengaruhi hasilnya:

  • Model tidak melihat kunci Anda. Setiap nilai dikirim sebagai segmen bernomor, tanpa nama kunci. Jika "button.open" dan "status.open" sama-sama berbunyi "Open", model tidak punya cara untuk mengetahui bahwa yang satu adalah kata kerja dan yang lain adalah kata sifat. String pendek yang ambigu adalah yang perlu diperiksa secara manual.
  • Setiap nilai diterjemahkan secara terpisah. Tidak ada yang mengaitkan dua kunci, sehingga kata yang sama di dua tempat bisa kembali dengan dua cara berbeda, dan kata yang membutuhkan dua terjemahan berbeda bisa kembali sama. Glosarium otomatis opsional BookTranslator mengumpulkan nama, tempat, dan istilah khusus serta menjaganya tetap konsisten, tetapi Anda tidak dapat memberinya terjemahan tetap versi Anda sendiri. Untuk istilah yang harus diterjemahkan dengan satu cara yang tepat, simpan daftar istilah dan periksa string tersebut setelah terjemahan; panduan glosarium kami menjelaskan cara merencanakannya.

Tag HTML inline dihitung setelah terjemahan, dan segmen yang tag-nya tidak cocok akan dicoba ulang. Placeholder kurung kurawal, placeholder gaya %s, dan sintaks ICU dikirim sebagai bagian dari teks tetapi tidak diperiksa dengan cara yang sama. Jalankan Langkah 4 pada setiap terjemahan.

Jika Anda lebih suka menerjemahkan dengan model chat atau model lokal, kirim hanya nilainya, jangan pernah file mentahnya, dan kembalikan berdasarkan kunci dengan skrip. Pemeriksaan di bawah ini berlaku untuk kedua cara.

Langkah 4: Periksa File Terjemahan

Bandingkan terjemahan dengan sumbernya:

python3 check_i18n_json.py en.json fr.json

Untuk menunjukkan apa yang ditangkapnya, kami membuat file Prancis dengan kesalahan yang ditanam. File ini dibuat manual, bukan keluaran model. Setelah peringatan sumber yang sama seperti pada Langkah 1, pemeriksa mencetak:

ERROR app.greeting: placeholders differ; lost ['name'] extra ['nom']
ERROR app.help_url: urls differ; lost ['https://example.com/help'] extra ['https://example.com/aide']
ERROR app.items: ICU message has no 'other' case
ERROR app.legacy: placeholders differ; lost ['%d'] extra []
ERROR limits.maxFiles: type changed from int to str
ERROR limits.projectId: non-text value changed: 9007199254740993 -> 9007199254740992
INFO  menu[1]: identical to source: 'Save'
INFO  compared 20 source values, 1 unchanged strings

Masing-masing akan muncul sebagai bug di aplikasi: nama kosong, tautan rusak, crash atau pesan mentah saat plural dirender, jumlah bab yang hilang, batas yang dibandingkan sebagai teks. Baris INFO mencantumkan string yang kembali tidak berubah. Beberapa memang wajar, seperti nama merek; "Save" dalam menu Prancis tidak.

Pemeriksa membandingkan kunci, tipe nilai, nilai non-teks, placeholder ({name}, {{name}}, %s, %1$s, %@), nama argumen ICU, tag HTML, dan URL. Pemeriksa tidak menilai terjemahannya sendiri.

Kasus plural memang seharusnya berubah

Plural ICU mencantumkan satu pesan per kategori plural. Bahasa Inggris memiliki dua kategori, one dan other, tetapi banyak bahasa memiliki kumpulan yang berbeda. Terjemahan Rusia yang baik dari pesan items kami biasanya akan menggunakan one, few, many, dan other, dan terjemahan Jepang hanya other. Jadi ketidakcocokan di sini tidak selalu merupakan kesalahan.

Kategori-kategori tersebut berasal dari aturan plural Unicode CLDR, dan other adalah kategori yang dimiliki setiap bahasa. Berikut adalah kategori kardinal yang dilaporkan oleh Intl.PluralRules di Node.js dengan CLDR 48:

BahasaKategori plural
Inggris, Jermanone, other
Prancis, Spanyol, Portugisone, many, other
Rusia, Polandiaone, few, many, other
Arabzero, one, two, few, many, other
Jepang, Tionghoa, Korealainnya

Bahasa Prancis, Spanyol, dan Portugis hanya menggunakan many untuk bilangan bulat yang sangat besar, seperti satu juta, sehingga pesan untuk jumlah kecil biasanya tidak memerlukannya. Pemeriksa melaporkan other yang hilang sebagai kesalahan, dan perubahan lain pada kategori sebagai peringatan untuk dibandingkan dengan tabel ini. Anda dapat mencetak daftar untuk bahasa apa pun sendiri:

node -e 'console.log(new Intl.PluralRules("ru").resolvedOptions().pluralCategories)'

Penerjemah diberikan kasus bahasa Inggris, jadi periksa hasilnya. Jika pesan bahasa Rusia atau Arab masih hanya memiliki one dan other, tambahkan kasus yang hilang secara manual, atau minta penerjemah melakukannya.

Lalu muat di aplikasi

Pemeriksa membuktikan file aman untuk dimuat, bukan bahwa isinya enak dibaca. Ganti aplikasi ke bahasa baru dan periksa layarnya: kata-kata panjang dalam bahasa Jerman atau Finlandia yang meluap dari tombol, teks kanan-ke-kiri dalam bahasa Arab atau Ibrani, serta tanggal atau angka yang diformat kode Anda secara terpisah dari file bahasa. Panduan kami tentang terjemahan versus lokalisasi membahas apa lagi yang berubah antar pasar selain kata-katanya.

Masalah Umum

File terjemahan tidak dapat dimuat di aplikasi saya. Jalankan pemeriksa pada file tersebut. Jika pemeriksa tidak dapat mengurainya, file telah diedit setelah diterjemahkan atau memang tidak valid sejak awal. Jika berhasil diurai, cari baris ERROR tentang kunci atau tipe.

Sebuah string muncul sebagai pesan ICU mentah, seperti {count, plural, ...}. Sintaks ICU rusak dalam terjemahan, biasanya karena kurung kurawal yang hilang atau kasus other yang hilang. Salin struktur dari sumber dan terjemahkan hanya kata-kata di dalam setiap kasus.

File saya adalah YAML, file .po, atau Markdown. BookTranslator juga menerima format tersebut, tetapi setiap format memiliki aturannya sendiri. Untuk dokumentasi, lihat panduan terjemahan Markdown kami; untuk halaman web, lihat panduan file HTML.

Bisakah saya menerjemahkan hanya kunci baru? Tidak dalam satu unggahan; seluruh file diterjemahkan. Letakkan kunci baru dalam file terpisah, terjemahkan, lalu gabungkan hasilnya berdasarkan kunci. Pemeriksa akan memastikan file gabungan memiliki semua kunci.

Haruskah saya menerjemahkan kuncinya? Tidak. Kunci adalah pengenal yang dicari oleh kode Anda. Hanya nilainya yang merupakan teks untuk dibaca orang.

Artikel Terkait

Cara Menerjemahkan File Bahasa JSON Tanpa Merusak Kunci atau Placeholder