Selamat siang, habravchane!
Pada artikel ini saya akan berbicara tentang solusi sederhana untuk masalah mengelola teks dan pelokalan dalam aplikasi web, yang dapat Anda implementasikan sendiri atau gunakan yang sudah jadi.

Saya sudah lama ingin berbagi pemikiran dan pengalaman saya sendiri ... dan, tentu saja, berbicara seumur hidup.
Latar belakangJelas, solusi untuk mengelola teks dan pelokalan sudah ada, tetapi mereka tidak cocok untuk saya karena berbagai alasan: rumit, tidak nyaman untuk digunakan, tidak cocok, tidak sesuai dengan visi saya untuk memecahkan masalah ini, kurang fungsional.
Selain itu, saya tidak terlalu suka perpustakaan pihak ketiga karena kecenderungan mereka untuk tumbuh (saat ini kita hanya membutuhkan sebagian kecil dari semua fungsi).
Perusahaan tempat saya bekerja memiliki solusi sendiri, tetapi, menurut saya, juga jauh dari ideal. Dan kebutuhan akan kompatibilitas ke belakang dengan versi yang lebih lama membuatnya menjadi rumit.
Pada titik tertentu, saya menginginkan sesuatu yang sederhana, mudah, dapat dimengerti, dan dapat dikembangkan untuk tugas yang berbeda.
Pernyataan masalah
Segalanya tampak jelas di sini. Atau tidak? Mari kita pikirkan apa yang kita inginkan.
Kita perlu entah bagaimana mendapatkan teks yang dilokalkan. Teks dapat berisi variabel. Bisakah variabel dilokalkan juga ?! Secara teori, ya. Dan jika variabelnya adalah tanggal atau angka ?! Ditambah dukungan penurunan harga. Dan akhirnya, beberapa solusi jika teks tidak ditemukan.
Implementasi
Basisnya akan menjadi objek sederhana, di mana kuncinya adalah kode teks, dan nilainya adalah teks aktual yang Anda butuhkan, tidak ada yang rumit:
const textsBundle = { 'button.open': 'Open', 'button.save': 'Save', }; function TextManager(texts) { this.getText = function(code) { return texts[code]; }; } const textManager = new TextManager(textsBundle); textManager.getText('button.open');
Sedikit tentang nama kunciNama kunci adalah topik yang terpisah. Lebih baik menyepakati satu opsi saja, jika tidak maka kunci yang berbeda akan “membangkitkan” :). Tidak ada satu solusi, pilih apa yang menurut Anda lebih nyaman dan lebih konsisten dengan proyek. Secara pribadi, saya suka yang pertama:
'button.open.label'
'button.open.help_text'
atau
'button.label.open'
'button.help_text.open'
atau
'label.button.open'
'help_text.button.open'
Selanjutnya, kita memerlukan mekanisme yang dapat melakukan beberapa jenis manipulasi dengan teks sebelum memberikan hasil akhir, misalnya, memasukkan parameter. Dan kemudian saya mendapat ide yang menarik - bagaimana jika kita menggunakan middleware untuk memanipulasi teks? Lagipula, saya belum melihat keputusan seperti itu ... yah, atau saya sudah terlihat buruk :).
Kami memutuskan persyaratan untuk middleware: pada input, middleware akan menerima teks dan parameter, dan memberikan teks yang dihasilkan, setelah manipulasi yang diperlukan.
Middleware pertama akan menerima teks asli, dan yang berikutnya akan menerima teks dari middleware sebelumnya. Mari kita tambahkan kode yang hilang:
function TextManager(texts, middleware) { function applyMiddleware(text, parameters, code) { if (!middleware) return text; return middleware.reduce((prevText, middlewareItem) => middlewareItem(prevText, parameters, code), text); } this.getText = function(code, parameters) { return applyMiddleware(texts[code], parameters, code); }; }
TextManager dapat menampilkan teks dengan kodenya. Itu juga dapat diperluas menggunakan middleware, yang membuka banyak kemungkinan, misalnya:
- menangani kasus ketika teks tidak ditemukan
- penggunaan parameter dalam teks
- lokalisasi parameter
- gunakan penurunan harga
- perisai teks, dll.
Berlatih
Kami akan menulis beberapa middleware yang diperlukan. Anda akan membutuhkannya 100%.
InsertParams
Mengizinkan penggunaan parameter dalam teks. Misalnya, kita perlu menampilkan teks "Halo {{username}}". Middleware berikut akan menyediakan ini:
function InsertParams(text, parameters) { if (!text) return text; if (!parameters) return text; let nextText = text; for (let key in parameters) { if (parameters.hasOwnProperty(key)) { nextText = text.replace('{{' + key + '}}', parameters[key]); } } return nextText; }
UseCodeIfNoText
Memungkinkan Anda mengembalikan kode teks, alih-alih undefined
, jika teks tidak ditemukan:
function UseCodeIfNoText(text, parameters, code) { return text ? text : code; }
Total yang kami terima kira-kira sebagai berikut:
const textsBundle = { 'text.hello': 'Hello', 'text.hello_with_numeric_parameter': 'Hello {{0}}', 'text.hello_with_named_parameter': 'Hello {{username}}', }; const textManager = new TextManager(textsBundle, [InsertParams, UseCodeIfNoText]); textManager.getText('nonexistent.code')
Bereaksi Contoh Aplikasi
Pertama, inisialisasi di TextManager
tingkat atas dan tambahkan teks.
Menurut pendapat saya, yang terbaik adalah menarik teks dari server, tetapi untuk kesederhanaan saya tidak akan melakukan ini.
const textsBundle = { 'text.hello': 'Hello {{username}}' } function TextManagerProvider({ children }) { const textManager = new TextManager(textsBundle, [InsertParams, UseCodeIfNoText]); return ( <TextManagerContext.Provider value={textManager}> {children} </TextManagerContext.Provider> ) }
Selanjutnya, dalam komponen, textManager
menggunakan textManager
, misalnya, menggunakan hook, dan kami mendapatkan teks yang diinginkan dengan kode.
function SayHello({ username }) { const textManager = useContext(TextManagerContext); return ( <div> {textManager.getText('text.hello', { username })} </div> ) }
Lokalisasi
Anda bertanya, "Apa kaitannya dengan lokalisasi?".
Semuanya sangat sederhana - saat mengubah bahasa, buat instance TextManager
, tambahkan teks dan segera dapatkan hasilnya.
Bab kedua dari belakang :)
Seperti yang Anda lihat dari contoh, penggunaannya sangat sederhana, dan berkat middleware Anda dapat memperluas fungsionalitas tanpa batas.
Saya memposting implementasi saya di github dan berencana untuk lebih mengembangkan manajer teks . Gunakan, tawarkan peningkatan dan, seperti kata mereka di sana, Sama-sama! :)
Kesimpulannya
Jadi saya memenuhi keinginan daaaaavnee saya - menulis sebuah artikel tentang Habr. Saya sangat berharap artikel ini bermanfaat dan menyenangkan komunitas.
Terima kasih atas perhatian anda