Sviluppatore web, freelancer, blogger e pensatore nonconformista a Milano

i18n & L10n for themes and plugins

La comunità italiana di WordPress è completamente rinata e con il WordCamp a Torino 2016 festeggia questo enorme successo. Sono fiero di potere fare parte di tutto questo – da organizzatore e da speaker. Durante il WordCamp ho parlato del tema “i18n & L10n for themes and plugins” e questo post faceva prima parte della mia preparazione per lo speech ma adesso deve fungere da referenza per tutti quelli che vogliono approfondire la materia. Ecco le slide e le relative descrizioni…

Nel mio talk di oggi parlo della base di quello che dovete sapere per poter preparare un theme o un plugin che deve funzionare bene in una configurazione multilingua. Che cosa dovete sapere per poter seguire bene questo speech? Be’, il vostro interesse e se sapete anche un po’ di PHP siete già molto avvantaggiati. Se alla fine di questo talk avete la sensazione che siete più informati e avete pure voglia di approfondire, allora diciamo che ho pienamente raggiunto il mio obbiettivo.

Però prima mi voglio presentare: Mi chiamo Dennis Ploetner. Sono nato e cresciuto a Berlino in Germania. Circa 10 anni fa mi sono trasferito in Italia e vivo da allora nelle vicinanze di Milano. Da quasi 20 anni lavoro nel settore IT. Da un paio di anni mi sono – prima innamorato – e poi specializzato in WordPress. Lavoro come Senior WordPress Developer per DriveK Italia. Sono molto attivo nella comunità di WordPress sia come plugin developer che co-organizzatore del WordPress meetup Milano.

Chi crea oggi siti web ha sempre più spesso a che fare con il tema multilingua. Infatti, avere un sito in più lingue è spesso fra le prime cose quando un cliente descrive quello che vuole ottenere. Tutte le funzionalità necessarie sono già nel core di WordPress, e non parliamo delle ultime novità. Nella versione 1.5.0 di WordPress credo che troviamo per la prima volta traccia della misteriosa parola i18n, quindi da Febbraio 2005. Si parla allora di funzionalità matura e con un paio di indicazioni su dove cominciare che è digeribile anche per principianti.

Tanti di voi hanno magari già notato i cosidetti numeronyms come i18n, L10n, g11n, a11y, p13n e così via. Le prime volte ti senti probabilmente un po’ perso ma una volta imparato che si parla di internationalisation, localisation, globalisation, accessibility e personalization tutto diventa più chiaro. Non è più complicato quando si dice o scrive i18n o L10n? Una delle versioni su come è nata questa usanza racconta dei server con il sistema operativo VMS che aveva una limitazione della lunghezza degli username – siamo negli anni ’70 per intenderci. Un sysadmin della DEC creò l’utenza S12N per il suo collega Scherpenhuizen per risolvere il problema.

L’internazionalizzazione è diventata negli anni sucessivi un tema caldo per l’ISO e l’usanza dei numeronyms è diventata normale.

Allora che cos’è i18n?

Avete notato la i minuscola? Questo dettaglio è importante per non sbagliare e scambiare la i con una l minuscola. Ci sono tanti testi che descrivono in un modo molto esauriente che cos’è l’internazionalizzazione ma in sostanza si può dire che si tratta delle azioni che sono necessarie per preparare un prodotto per l’uso sul mercato internazionale. Tipicamente si rende la traduzione possibile o più facile è si controlla la possibilità di poter usare i caratteri non-latini.

Per dirlo ancora in modo più sintetico: Dopo i18n possiamo cominciare (con la traduzione).

Tutto questo è di solito terreno degli sviluppatori.

A questo punto: Che cos’è L10n?

In questo caso si tratta delle azioni o dei processi per rendere un prodotto usabile in un paese o una regione.

Anche qui in modo ancora più sintetico: (La traduzione) è stata eseguita.

Questa è tipicamente la zona dove si muovono i traduttori.

La “Developer Zone”

I plugin usano la funzione “load_plugin_textdomain”, i temi invece usano “load_theme_textdomain” … la sintassi è leggermente diversa – come potete notare. Ci sono anche funzioni simili come load_textdomain, unload_textdomain, load_default_textdomain, load_muplugin_textdomain e load_child_theme_textdomain ma questi mi limito solo a nominarli (per mancanza di tempo). Un dettaglio importante è il momento in cui si devono chiamare queste funzioni.

Per i plugin “plugins_loaded” è il momento giusto, per caricare un textdomain. Per i temi “after_setup_theme” è il coretto hook; il blocco di codice viene inserito tipicamente nel file functions.php. Non usate lo hook “init” perché questo viene chiamato dopo – quindi in ritardo.

Funzioni regolari

Ci sono 3 funzioni essenziali nell’uso quotidiano per l’18n: __(), _e() e _n(). I primi due sono wrapper della funzione translate(), che però non si deve usare direttamente. __() torna la stringa tradotta, _e() invece stampa quella a video. _n() fa tornare il singolare o plurale di una stringa secondo il valore dato come parametro. In questo modo si possono gestire stringhe del tipo ‘1 stella’, ‘2 stelle’ e così via.

Il contesto

Le funzioni regolari hanno anche dei cugini che rapresentano loro estensioni. _x(), _ex() e _nx() funzionano come i loro omologhi ma accettano un contesto. Questa può essere una scelta propria del programmatore come il nome del template-file per esempio che può essere utile se la traduzione deve essere leggermente diversa in un template diverso. Ma il contesto può essere anche importante quando si tratta di omonimia … per esempio quella geografica, o di sostantivi come per esempio ‘imposta’ che può essere una persiana o una tassa.

Sul contesto dico ancora qualcosa nella parte per i traduttori.

Sicurezza per l’output

Le funzioni esc_attr_* e esc_html_* sono una combinazione delle funzionalità nelle slide precedenti e delle funzioni di WordPress che rendono l’output di stringhe più sicuro. Questo è probabilmente importante per gli attributi nei tag HTML o quando si stampa l’input degli user a video.

Notate anche anche il commento che comincia con ‘translators:’ Questa è una possibilità per dare un’ informazione in più alla persona che deve tradurre le vostre stringhe. Così avete anche un modo per poter usare un codice come stringa e un esempio con le frasi complete che spiegano il perché.

Date e numeri

Come si stampa una data in base alla lingua che abbiamo configurato? Come si formattano i numeri così che l’output sembri naturale anche per un madrelingua? Anche qua ci aiuta WordPress con le funzioni adatte: date_i18n e number_format_i18n fanno quello che ci serve.

Le stringhe nel nostro JavaScript

Come dobbiamo gestire le stringhe nel nostro JavaScript? Questo è un dettaglio nei nostri prodotti che viene dimenticato spesso e volentieri. Una buona parte la possiamo gestire con l’uso di JavaScript templates dove potete usare le funzionalità delle slide precedenti ancora prima del rendering: la combinazione degli Underscore templates con i Backbone views per dare un esempio. Se ci sono ancora stringhe da gestire vi può essere di aiuto la funzione wp_localize_script().

E poi?

Dal punto di vista del programmatore abbiamo parlato degli aspetti più importanti. Dopo un po’ di esercizio userete le funzioni in automatico. Ma non è ancora tutto. Aprite per iniziare il file /wp-includes/l10n.php e studiate le funzionalità offerte dal core di WordPress. Troverete get_locale() e get_available_languages() ma anche funzionalità come _n_noop() che sono altrettanto interessanti. Purtroppo il tempo non è abbastanza.

La “Translator Zone”

In un mondo ideale abbiamo già parlato della parte più complicata. Il nostro sviluppatore ci ha creato il file di traduzione e noi possiamo cominciare la nostra traduzione in santa pace. Magari parliamo un attimo di come si presenta un file di traduzione al traduttore … parliamo quindi di L10n o Localizzazione. Negli esempi uso poEdit che funziona abbastanza bene e che tra l’altro usiamo in azienda su Windows, Mac e Linux.

Proprietà traduzione

Il consiglio che vorrei dare a tutti voi: Andate prima a controllare le proprietà del catalogo quando aprite il file di traduzione la prima volta. Non fa male e poi siete sicuri che tutto è a posto. Se manca qualcosa potete almeno allo sviluppatore indicare dov’è il problema. Controllate le cose più essenziali come la lingua e il set di caratteri, e settate il vostro nome e l’email.

Percorsi sorgente

Questa e la parte prossima hanno rilevanzasolo se volete aggiornare il file po dalle sorgenti. Cliccate su “Percorsi sorgente” e controllate se i percorsi – dove poEdit dovrebbe cercare le sorgenti – vanno bene. Se il nostro file di lingua è in una sottocartella (come “languages” nell’esempio all’inizio della presentazione) va aggiunto ‘..’ – quindi la cartella superiore.

Chiavi ricerca sorgente

Questa parte contiene le parole che poEdit cerca quando fate uno scan per aggiornare la traduzione. Notate anche come sono impostate le query per _n e _x. Praticamente tutti i file po di un progetto devono essere impostati nello stesso modo. Quindi se volete aggiungere un’altra lingua potete teoricamente copiare i file e aggiustare soltanto la parte “Proprietà traduzione”.

Come tradurre con poEdit

Infine ho degli esempi di come si presentano le stringhe esposte dalle funzioni delle quali abbiamo parlato oggi

  • prima le stringhe regolari – Notate anche i suggerimenti per la traduzione. Questa stringhe fanno parte della memoria di poEdit e con l’uso dell’editor si vedono sempre più suggerimenti.
  • poi le stringhe con il contesto – poEdit mette il contesto tra parentesi quadre nella visualizzazione e queste stringhe non devono essere tradotte
  • le stringhe con la versione singolare e plurale hanno un’interfaccia leggermente diversa ma comunque semplice da gestire
  • e per finire come si presentano le note ai traduttori nell’interfaccia di poEdit

That’s it! Any questions? 😉

Parla alla tua mente

*