Localizzare un'applicazione dinamica come Sprout Social in più lingue è un'impresa complessa. La traduzione del testo che appare nell'applicazione è solo metà della storia. Implica anche lo sviluppo della nostra applicazione in un modo che semplifichi l'estrazione e lo scambio di quel testo con le traduzioni. In Sprout, ci affidiamo a fornitori di terze parti per le traduzioni. Ma abbiamo ancora bisogno di strumenti per estrarre, raggruppare e inviare richieste di traduzione a quei fornitori e quindi servire e rendere le traduzioni agli utenti finali.



Per anni, il team di ingegneri di Sprout se l'è cavata con una soluzione di localizzazione personalizzata, poiché le soluzioni open source erano ancora in fase di maturazione. Ci ha permesso di accogliere i nostri clienti più grandi nelle nostre lingue supportate, ma mancava di alcune funzionalità utili. In questo articolo, illustrerò il nostro nuovo sistema di localizzazione, come affronta gli scenari di localizzazione più complicati e come abbiamo introdotto in modo incrementale tali modifiche nell'organizzazione di progettazione web.



Il nostro vecchio sistema

Per comprendere il nostro nuovo sistema di localizzazione, devi prima capire come funzionava il nostro vecchio sistema e le aree in cui potevamo migliorarlo.


numero angelico 1227

Sintassi del messaggio

La localizzazione dell'applicazione funziona astraendo il testo visibile all'utente finale in unità di stringa, chiamate messaggi. Questi messaggi vengono estratti e inviati ai traduttori. Astraendo queste stringhe, possiamo facilmente sostituirle a seconda della lingua preferita dell'utente finale.

Questi messaggi possono essere semplici stringhe statiche come 'Ciao, mondo' o avere segnaposto come 'Ciao, {nome}' o formattazione RTF come 'Ciao, mondo'. Poiché queste funzionalità devono essere serializzate in stringhe, è necessaria una sintassi comprensibile sia ai traduttori che al codice dell'applicazione per tradurre e rendere correttamente il testo.

Parte di ciò che rendeva difficile l'uso del nostro vecchio sistema di localizzazione era che avevamo creato la nostra sintassi e mantenuto un 'parser' fatto in casa per detta sintassi. Questo codice richiedeva molto tempo per essere mantenuto e la sintassi era piuttosto minima. Volevamo funzionalità aggiuntive per rendere più complessi i messaggi.

Esempio: nell'applicazione Sprout, abbiamo bisogno di un modo per rendere 'Hai X post' dove X è un valore numerico dinamico.



Considera il caso plurale, 'Hai 5 post ”. Considera il caso singolare 'Hai 1 inviare ”. Considera il caso '0'. Considera le lingue che potrebbero avere una grammatica per il caso '1' come il cinese e il giapponese. Considera le lingue che hanno una grammatica per il caso in cui X è un 'numero grande' come l'arabo, il polacco e il russo.

Gestione dei messaggi

Abbiamo messaggi che possiamo inviare ai traduttori e scambiarli nella nostra applicazione. La nostra applicazione ha bisogno di un modo per archiviare questi messaggi e servirli ai nostri utenti finali.

Il nostro vecchio sistema memorizzava tutti i nostri messaggi in file JSON (che chiamavamo 'file lang'), che venivano gestiti manualmente. Abbiamo fatto riferimento ai messaggi in questi file utilizzando gli ID nel nostro codice javascript di origine. Quando un utente desiderava l'applicazione in spagnolo, servivamo i nostri file in lingua spagnola, quindi il javascript eseguiva il rendering del messaggio spagnolo corrispondente utilizzando l'ID.



Per motivi di prestazioni, abbiamo provato a servire solo i messaggi utente che erano su quella pagina, quindi avevamo file lang separati per le diverse pagine dell'applicazione. Questo era un sistema valido, ma man mano che il nostro team e la nostra applicazione si ridimensionavano, significava più tempo per gli sviluppatori manuali per creare e gestire questi ID e file lang.

  Screenshot di JavaScript utilizzato in precedenza per gestire manualmente i messaggi e la traduzione in Sprout's codebase.

Per aggiungere un nuovo messaggio all'applicazione, gli sviluppatori dovevano aggiungerlo manualmente al file lang corretto con un ID univoco per fare riferimento a quel messaggio. A volte, ci imbattevamo in problemi di collisioni di ID e errori di battitura dell'ID che portavano alla mancanza di lang nell'applicazione. L'aggiunta di testo all'applicazione web sembrava noiosa con numerosi passaggi che non erano intuitivi.

La nostra nuova soluzione

Conoscendo queste carenze, gli ingegneri web di tutta l'organizzazione del prodotto hanno creato un gruppo di lavoro sulla localizzazione per sviluppare una soluzione. Ci siamo incontrati regolarmente per fare brainstorming. Dopo un approfondito processo di ricerca, abbiamo deciso di migrare l'applicazione Sprout dal nostro sistema di localizzazione fatto in casa per utilizzare FormatJS reagire-intl library e costruiamo attorno ad essa un'infrastruttura per la gestione dei nostri messaggi. React-intl era la libreria di localizzazione open source più ricca di funzionalità e popolare nell'ecosistema javascript e ben integrata nella nostra base di codice.

Sintassi del messaggio

Volevamo una soluzione più robusta e non volevamo creare qualcosa da zero. Abbiamo adottato il Sintassi dei messaggi in terapia intensiva , una sintassi standardizzata utilizzata nelle applicazioni Java, PHP e C e cattura le complessità dei messaggi dinamici delle applicazioni. IL reagire-intl La libreria supporta anche l'analisi e il rendering dei messaggi di sintassi dei messaggi ICU.

  Un esempio affiancato di come la sintassi dei messaggi in terapia intensiva acquisisce casi plurali. A sinistra c'è il messaggio in inglese, prima di essere tradotto in russo. Sulla destra c'è il messaggio tradotto in russo. Nota come quando i traduttori convertono questo messaggio in altre lingue, possono aggiungere e rimuovere casi se necessario per supportare correttamente la lingua. La traduzione russa di questo messaggio aggiunge 'pochi' e 'molti' casi.

Questo è un esempio di come la sintassi dei messaggi ICU cattura i casi plurali. Questo è il messaggio in inglese e russo. Nota come quando i traduttori convertono questo messaggio in altre lingue, possono aggiungere e rimuovere casi se necessario per supportare correttamente la lingua. La traduzione russa di questo messaggio aggiunge 'pochi' e 'molti' casi.

La sintassi dei messaggi ICU è stata testata in battaglia da molte applicazioni in innumerevoli lingue. Potevamo fidarci che potesse supportare le nostre sofisticate esigenze dei clienti e che ci fossero molte soluzioni e/o risorse educative per qualsiasi domanda sulla localizzazione che incontrassimo.

Gestione dei messaggi

Abbiamo sviluppato un sistema utilizzando gli strumenti forniti da FormatJS per automatizzare il processo di aggiunta, rimozione e memorizzazione dei messaggi. Ciò ha comportato alcuni cambiamenti filosofici nel modo in cui ci siamo avvicinati alla memorizzazione e al riferimento dei messaggi.

Un importante cambiamento rispetto al nostro vecchio sistema incoraggiato da FormatJS è stato l'utilizzo del nostro codice dell'interfaccia utente come fonte di verità per i messaggi. Nel nostro sistema precedente, l'origine dei messaggi e l'utilizzo dei messaggi si trovavano in due posizioni diverse, il che significava che dovevamo mantenerli sincronizzati. Il nostro nuovo sistema mantiene le origini dei messaggi con il resto del codice dell'interfaccia utente. Abbiamo semplicemente bisogno di eseguire uno script che estragga tutti i messaggi dai file dell'interfaccia utente per generare i nostri file lang e il contenuto del messaggio diventa gli ID univoci con l'aiuto di una funzione hash.

  Screenshot di JavaScript utilizzato in precedenza per gestire automaticamente i messaggi e la traduzione in Sprout's codebase.

Questa modifica colloca i messaggi con il codice dell'interfaccia utente e ha diversi vantaggi:

  • Più leggibile: Niente più ID progettati per i robot nel nostro codice dell'interfaccia utente. Ora possiamo leggere i messaggi in inglese nel codice dell'interfaccia utente e capire quale testo vedrà l'utente.
  • ID non manuali: Questi ID che erano usati solo dalle macchine sono ora generati dalle macchine e, per definizione, univoci per messaggio.
  • Nessun file lang gestito manualmente: Gli sviluppatori non dovrebbero aver bisogno di toccare questi file lang. I nostri script gestiscono l'aggiunta e la cancellazione dei messaggi.

Come siamo migrati?

Ma come abbiamo migrato tutto il nostro team di ingegneri web e la base di codice a questo nuovo sistema? L'abbiamo suddiviso in quattro pietre miliari: pilotare il nuovo sistema, istruire il nostro team, deprecare il vecchio sistema e migrare alla nostra nuova soluzione.


numero 313 bibbia

Pilotare il nuovo sistema

Il gruppo di lavoro ha testato il nuovo sistema in sezioni specifiche dell'applicazione per avere un'idea delle sue migliori pratiche e dell'intero ambito di migrazione. Ciò ha consentito di impostare il nuovo sistema sul lato client (poly-fill, ecc.) E sul lato build dell'applicazione. Questo ci ha permesso di ripetere l'esperienza degli sviluppatori e mitigare i rischi.


5555 numero angelico significato

Formazione scolastica

Abbiamo preso ciò che abbiamo appreso dal progetto pilota e lo abbiamo utilizzato per istruire l'intero team di ingegneri web. Abbiamo sviluppato una FAQ e altra documentazione educativa e presentazioni per aiutare gli sviluppatori a utilizzare la nuova libreria. È facile sottovalutare questo passaggio, ma questa parte di una migrazione è estremamente importante. Non importa quanto sia buono il tuo nuovo sistema: le persone devono sapere come e perché dovrebbero usarlo.

Abbiamo anche sviluppato un programma per ambasciatori in cui ogni team di funzionalità web di Sprout aveva un ambasciatore della localizzazione nominato, che era responsabile di aiutare a istruire il proprio team sul nuovo sistema e segnalare problemi o punti deboli al gruppo di lavoro.

Questo ci ha permesso di delegare le responsabilità educative e identificare i problemi specifici dei singoli team.

Deprecare il vecchio sistema

Dopo esserci sentiti sicuri dell'esperienza degli sviluppatori, della conoscenza condivisa e del potenziale di scalabilità del nuovo sistema, abbiamo deprecato il vecchio sistema. Abbiamo creato alcune regole di eslint personalizzate e utilizzato lo strumento di linting, splint , per bloccare l'utilizzo del vecchio sistema pur consentendo gli utilizzi esistenti. Da questo momento in poi, gli ingegneri web avrebbero dovuto utilizzare il nuovo sistema durante la scrittura del nuovo codice.

Migrazione al nostro nuovo sistema

Con fiducia nel nostro nuovo sistema e un numero fisso di vecchi utilizzi, abbiamo iniziato la migrazione.

Molti usi avevano equivalenti uno a uno nel nuovo sistema. Laddove esistono questi equivalenti, siamo stati in grado di automatizzare la migrazione scrivendo un code-mod using jscodeshift . Siamo stati in grado di eseguire in modo iterativo la mod del codice su sezioni della base di codice, imparando e risolvendo i problemi man mano che procedevamo. C'erano pochi casi limite rimanenti che non potevano essere facilmente modificati in codice che ci sentivamo a nostro agio nel risolverli manualmente.

Srotolare

Perché abbiamo optato per un approccio così iterativo invece di provare a migrare tutto in una volta? L'utilizzo di un approccio iterativo fa parte della cultura ingegneristica di Sprout e crediamo nell'apprendimento e nel miglioramento costanti.

Affrontando la migrazione in questo modo, siamo stati in grado di imparare strada facendo, adattando e risolvendo i problemi in tempo reale. Potremmo anche ripristinare le modifiche se la migrazione ha iniziato a bloccare lo sviluppo dell'applicazione. Il nostro approccio iterativo ci ha permesso di fare progressi mentre lavoravamo su altre iniziative e ci ha consentito di segnalare i principali cambiamenti con un gruppo più piccolo prima di distribuirli a tutti. Gli stessi principi di sviluppo delle funzionalità per un'applicazione si applicano allo sviluppo di strumenti di sviluppo interni.

Apprendimenti e takeaway

Reinventare il nostro sistema di localizzazione è stata un'impresa enorme per l'intera organizzazione di progettazione web. Il mio consiglio ad altri che affrontano progetti o sfide simili sarebbe di:

  • Utilizzare standard ampiamente adottati: Perché creare una sintassi dei messaggi personalizzata quando gli ingegneri che hanno passato anni a pensare a questo spazio problematico hanno già sviluppato la sintassi dei messaggi ICU?
  • Prendi in considerazione la collocazione di elementi correlati: Renderà l'aggiunta, la modifica e l'eliminazione molto più semplice.
  • Abbraccia un'implementazione iterativa: Progetta l'implementazione del tuo cambiamento in un modo che ti permetta di imparare mentre procedi. Non puoi anticipare tutto, quindi costruisci lo spazio per ricorrere al tuo piano.
  • Condividi i tuoi apprendimenti: L'istruzione è la metà di un lancio. Non importa quanto sia buono il tuo nuovo sistema se le persone non sanno come usarlo o perché è migliore.

Per ulteriori informazioni sulla cultura ingegneristica di Sprout, consulta il nostro pagina delle carriere Oggi.

Condividi Con I Tuoi Amici: