Localizarea unei aplicații dinamice precum Sprout Social în mai multe limbi este o activitate complexă. Traducerea textului care apare în aplicație este doar o jumătate din poveste. De asemenea, implică dezvoltarea aplicației noastre într-un mod care facilitează extragerea și schimbarea textului respectiv pentru traduceri. La Sprout, ne bazăm pe furnizori terți pentru traduceri. Dar avem încă nevoie de instrumente pentru a extrage, a grupa și a trimite cererile de traducere acelor furnizori și apoi a servi și a reda traducerile utilizatorilor finali.



Ani de zile, echipa de ingineri Sprout s-a descurcat cu o soluție de localizare personalizată, deoarece soluțiile open source erau încă în curs de maturizare. Ne-a permis să găzduim cei mai mari clienți ai noștri în limbile acceptate, dar ne-au lipsit unele funcții utile. În acest articol, voi prezenta noul nostru sistem de localizare, modul în care abordează cele mai complicate scenarii de localizare și modul în care am introdus treptat acele schimbări în organizația de inginerie web.



Vechiul nostru sistem

Pentru a înțelege noul nostru sistem de localizare, mai întâi trebuie să înțelegeți cum a funcționat vechiul nostru sistem și zonele în care l-am putea îmbunătăți.

Sintaxa mesajului

Localizarea aplicației funcționează prin extragerea textului care este vizibil pentru utilizatorul final în unități de șir, numite mesaje. Aceste mesaje sunt extrase și trimise traducătorilor. Abstragând aceste șiruri, le putem schimba cu ușurință în funcție de limba preferată a utilizatorului final.

Aceste mesaje pot fi simple șiruri statice precum „Bună ziua, lume” sau pot avea substituenți precum „Bună ziua, {nume}” sau formatare text îmbogățit precum „Bună ziua, lume”. Deoarece aceste caracteristici trebuie serializate în șiruri de caractere, aveți nevoie de o sintaxă pe care atât traducătorii, cât și codul aplicației să o înțeleagă pentru a traduce și a reda corect textul.

O parte din ceea ce a făcut ca vechiul nostru sistem de localizare să fie dificil de utilizat a fost că ne-am creat propria sintaxă și am menținut un „parser” de casă pentru sintaxa menționată. Menținerea acestui cod a fost consumatoare de timp, iar sintaxa a fost destul de minimă. Ne doream funcții suplimentare pentru a ajuta la redarea mesajelor mai complexe.

Exemplu: În aplicația Sprout, avem nevoie de o modalitate de redare „Aveți X postări” unde X este o valoare numerică dinamică.



Luați în considerare cazul la plural, „Aveți 5 postări ”. Luați în considerare cazul singular, „Aveți 1 post ”. Luați în considerare cazul „0”. Luați în considerare limbi care ar putea avea o gramatică pentru cazul „1”, precum chineza și japoneză. Luați în considerare limbile care au o gramatică pentru cazul în care X este un „număr mare” precum arabă, poloneză și rusă.

Gestionarea mesajelor

Avem mesaje pe care le putem trimite traducătorilor și le putem schimba în aplicația noastră. Aplicația noastră are nevoie de o modalitate de a stoca aceste mesaje și de a le oferi utilizatorilor finali.

Vechiul nostru sistem a stocat toate mesajele noastre în fișiere JSON (noi le-am numit „fișiere limba”), care au fost gestionate manual. Am făcut referire la mesajele din aceste fișiere folosind ID-uri în codul nostru javascript sursă. Când un utilizator dorea aplicația în spaniolă, ne servim fișierele în limba spaniolă, iar apoi javascript-ul redau mesajul spaniol corespunzător folosind ID-ul.



Din motive de performanță, am încercat să difuzăm numai mesajele utilizatorului care se aflau pe pagina respectivă, așa că am avut fișiere lang separate pentru diferitele pagini ale aplicației. Acesta a fost un sistem valid, dar pe măsură ce echipa și aplicația noastră s-au extins, a însemnat mai mult timp pentru dezvoltatori manual pentru crearea și gestionarea acestor ID-uri și fișiere lang.

  Captură de ecran a JavaScript folosită anterior pentru a gestiona manual mesajele și traducerea în Sprout's codebase.

Pentru a adăuga un mesaj nou în aplicație, dezvoltatorii au trebuit să le adauge manual în fișierul lang corect cu un ID unic pentru a face referire la acel mesaj. Uneori, ne confruntam cu probleme de coliziuni ale ID-ului și greșeli de tip ID care duceau la lipsa limbajului din aplicație. Adăugarea de text în aplicația web a fost obositoare cu numeroși pași care nu erau intuitivi.

Noua noastră soluție

Cunoscând aceste deficiențe, inginerii web din întreaga organizație de produse au creat un grup de lucru pentru localizare pentru a dezvolta o soluție. Ne-am întâlnit regulat pentru a face brainstorming. După un proces de cercetare aprofundat, am decis să migrăm aplicația Sprout din sistemul nostru de localizare de casă pentru a folosi formatul FormatJS. react-intl bibliotecă și să construim infrastructură în jurul ei pentru gestionarea mesajelor noastre. React-intl a fost cea mai bogată în funcții și cea mai populară bibliotecă de localizare open source din ecosistemul javascript și sa integrat bine în baza noastră de cod.

Sintaxa mesajului

Am vrut o soluție mai robustă și nu am vrut să creăm ceva de la zero. Am adoptat Sintaxa mesajului ICU , o sintaxă standardizată care este utilizată în aplicațiile Java, PHP și C și surprinde complexitatea mesajelor dinamice ale aplicației. The react-intl biblioteca acceptă, de asemenea, analizarea și redarea mesajelor de sintaxă a mesajelor ICU.

  Un exemplu alăturat al modului în care sintaxa mesajelor ICU surprinde mai multe cazuri. În stânga este mesajul în engleză, înainte de a fi tradus în rusă. În dreapta este mesajul tradus în rusă. Observați cum, atunci când traducătorii convertesc acest mesaj în alte limbi, ei pot adăuga și elimina cazuri după cum este necesar pentru a accepta limba în mod corespunzător. Traducerea în limba rusă a acestui mesaj adaugă cazuri „puține” și „multe”.

Acesta este un exemplu despre modul în care sintaxa mesajelor ICU captează cazurile plurale. Acesta este mesajul în engleză și rusă. Observați cum, atunci când traducătorii convertesc acest mesaj în alte limbi, ei pot adăuga și elimina cazuri după cum este necesar pentru a accepta limba în mod corespunzător. Traducerea în limba rusă a acestui mesaj adaugă cazuri „puține” și „multe”.

Sintaxa mesajelor ICU a fost testată de multe aplicații în nenumărate limbi. Am putea avea încredere că ar putea sprijini nevoile noastre sofisticate ale clienților și că au existat multe soluții și/sau resurse educaționale pentru orice întrebări de localizare pe care le-am întâlnit.

Gestionarea mesajelor

Am dezvoltat un sistem folosind instrumente furnizate de FormatJS care ar automatiza procesul de adăugare, eliminare și stocare a mesajelor. Acest lucru a implicat unele schimbări filozofice în modul în care am abordat stocarea și referirea mesajelor.

O schimbare majoră față de vechiul nostru sistem pe care FormatJS o încurajează a fost utilizarea codului nostru UI ca sursă de adevăr pentru mesaje. În sistemul nostru anterior, sursa mesajelor și utilizarea mesajelor erau în două locuri diferite, ceea ce însemna că trebuia să le menținem sincronizate. Noul nostru sistem păstrează sursele mesajelor cu restul codului UI. Trebuie pur și simplu să rulăm un script care va extrage toate mesajele din fișierele UI pentru a genera fișierele noastre lang, iar conținutul mesajului devine ID-urile unice cu ajutorul unei funcții hash.

  Captură de ecran a JavaScript folosită anterior pentru a gestiona automat mesajele și traducerea în Sprout's codebase.

Această modificare coloca mesajele cu codul UI și a avut mai multe beneficii:

  • Mai lizibil: Nu mai există ID-uri care sunt concepute pentru roboți în codul nostru UI. Acum putem citi mesajele în limba engleză din codul UI și putem înțelege ce text va vedea utilizatorul.
  • ID-uri non-manuale: Aceste ID-uri care au fost folosite doar de mașini sunt acum generate de mașini și, prin definiție, unice pe mesaj.
  • Nu există fișiere lang gestionate manual: Dezvoltatorii nu ar trebui să atingă aceste fișiere lang. Scripturile noastre gestionează adăugarea și ștergerea mesajelor.

Cum am migrat?

Dar cum am migrat întreaga noastră echipă de inginerie web și baza de cod la acest nou sistem? Am împărțit acest lucru în patru etape: pilotarea noului sistem, educarea echipei noastre, deprecierea vechiului sistem și migrarea către noua noastră soluție.

Pilotarea noului sistem

Grupul de lucru a pilotat noul sistem în anumite secțiuni ale aplicației pentru a obține o idee despre cele mai bune practici ale acestuia și despre domeniul complet de migrare. Acest lucru a făcut ca noul sistem să fie configurat pe partea clientului (poly-umplere, etc.) și pe partea de construcție a aplicației. Acest lucru ne-a permis să repetăm ​​experiența dezvoltatorului și să reducem riscul.


care este numărul 711

Educaţie

Am luat ceea ce am învățat de la pilot și l-am folosit pentru a educa întreaga echipă de inginerie web. Am dezvoltat un Întrebări frecvente și alte documentații educaționale și prezentări pentru a ajuta dezvoltatorii care folosesc noua bibliotecă. Este ușor să subevaluezi acest pas, dar această parte a migrației este extrem de importantă. Nu contează cât de bun este noul tău sistem – oamenii trebuie să știe cum și de ce ar trebui să-l folosească.

De asemenea, am dezvoltat un program de ambasador în care fiecare echipă de funcții web de la Sprout avea un ambasador de localizare desemnat, care era responsabil să ajute să-și educe echipa cu privire la noul sistem și să raporteze problemele sau punctele dureroase grupului de lucru.

Acest lucru ne-a permis să delegam responsabilitățile educaționale și să identificăm problemele specifice echipelor individuale.

Deprecierea vechiului sistem

După ce ne-am simțit încrezători în experiența dezvoltatorului, cunoștințele împărtășite și potențialul de scară al noului sistem, am renunțat la vechiul sistem. Am creat câteva reguli personalizate de eslint și am folosit instrumentul de scame, esplint , pentru a bloca utilizarea vechiului sistem, permițând în același timp utilizările existente. Din acest moment, inginerii web trebuiau să folosească noul sistem atunci când scriu cod nou.

Migrarea la noul nostru sistem

Având încredere în noul nostru sistem și un număr fix de utilizări vechi, am început migrarea.

O mulțime de utilizări au avut echivalente unu-la-unu în noul sistem. Acolo unde există aceste echivalente, am putut automatiza migrarea scriind un cod-mod folosind jscodeshift . Am putut rula iterativ codul-mod peste secțiuni ale bazei de cod, învățând și remediand problemele pe măsură ce mergeam. Au rămas destul de puține carcase de margine care nu puteau fi ușor modificate prin cod, încât să ne simțim confortabil să le reparăm manual.

Rola

De ce am optat pentru o astfel de abordare iterativă în loc să încercăm să migrăm totul deodată? Utilizarea unei abordări iterative face parte din cultura inginerească a lui Sprout și credem în învățarea și îmbunătățirea constantă.

Abordând migrația în acest fel, am reușit să învățăm din mers, ajustând și remediând problemele în timp real. De asemenea, am putea anula modificările dacă migrarea ar începe să blocheze dezvoltarea aplicației. Abordarea noastră iterativă ne-a permis să facem progrese în timp ce lucrăm la alte inițiative și ne-a împuternicit să semnalăm schimbări majore cu un grup mai mic înainte de a le implementa tuturor. Aceleași principii de dezvoltare a caracteristicilor pentru o aplicație se aplică și dezvoltării instrumentelor interne pentru dezvoltatori.

Învățături și rezultate

Reimaginarea sistemului nostru de localizare a fost o activitate masivă în întreaga organizație de inginerie web. Sfatul meu pentru alții care se confruntă cu proiecte sau provocări similare ar fi:

  • Utilizați standarde larg adoptate: De ce să creați o sintaxă a mesajelor personalizată când inginerii care au petrecut ani de zile gândindu-se la acest spațiu problematic au dezvoltat deja sintaxa mesajelor ICU?
  • Luați în considerare aranjarea articolelor asociate: Va face mult mai ușoară adăugarea, modificarea și ștergerea acestora.
  • Îmbrățișați o lansare iterativă: Proiectați lansarea schimbării dvs. într-un mod care vă permite să învățați pe măsură ce mergeți. Nu poți anticipa totul, așa că construiește spațiu pentru recurs în planul tău.
  • Împărtășiți-vă învățările: Educația este jumătate din lansare. Nu contează cât de bun este noul tău sistem dacă oamenii nu știu cum să-l folosească sau de ce este mai bun.

Pentru mai multe informații despre cultura inginerească a lui Sprout, consultați-ne pagina cariere astăzi.

Imparte Cu Prietenii Tai: