Internazionalizzazione e localizzazione

Internazionalizzazione e Localizzazione dei Custom Post Type

Nei due capitoli precedenti abbiamo creato un custom post type con le relative tassonomie. Le stringhe utilizzate per generare le etichette erano in lingua inglese, e in questo capitolo vedremo come fare in modo che il software visualizzi le stringhe nella lingua dell’utente corrente. Vedremo, quindi, come internazionalizzare il plugin e localizzare i custom field e le custom taxonomy ad esso associate in lingua italiana.

Internazionalizzazione e Localizzazione

Internazionalizzazioneinternationalization (I18N) – e localizzazionelocalization (I10N) – sono due termini che indicano concetti differenti, seppur strettamente collegati.

  • Internazionalizzare un software, come un tema o un plugin di WordPress, significa svilupparlo in modo che possa essere tradotto in qualsiasi lingua.
  • La localizzazione del software, invece, è lo step successivo, ossia quello della traduzione in una determinata lingua, utilizzando strumenti software.

L’internazionalizzazione di un plugin di WordPress

Per la localizzazione dei custom post type dobbiamo procedere a localizzare il plugin con il quale li abbiamo implementati.

Per consentire l’internazionalizzazione del software, WordPress utilizza la libreria gettext. Questa libreria permette di visualizzare la traduzione di una stringa di testo in una lingua locale, se questa è presente. A questo scopo gli sviluppatori hanno a disposizione diverse funzioni, alcune delle quali definite da WordPress. Prima di analizzare queste funzioni nel codice, è però necessario preparare il plugin per l’internazionalizzazione.

Per internazionalizzare un plugin di WordPress è necessario definire, nell’intestazione del plugin, il Text Domain e il Domain Path, quindi caricare il Text Domain nel codice del plugin.

Text Domain

Il Text Domain è un identificativo univoco che permette a WordPress di distinguere tra tutte le traduzioni caricate.

A partire da WordPress 4.6, il Text Domain non è più richiesto, in quanto corrisponde allo slug del plugin, che ora è il valore predefinito.

Nel nome del Text Domain possono esserci trattini, ma non caratteri di sottolineatura. Lo slug che identifica il Text Domain, inoltre, deve essere una stringa e non può essere sostituita dal nome di una variabile o da una costante.

Il Text Domain deve, inoltre, essere inserito nell’header del plugin in quanto viene utilizzato da WordPress per internazionalizzare i meta dati del plugin anche quando il plugin non è attivo:

<?php
/**
 * @package frammenti
 * @version 1.0
 *
 * Plugin Name: Frammenti
 * Plugin URI: http://wordpress.org/extend/plugins/#
 * Description: This is a development plugin 
 * Author: Carlo Daniele
 * Version: 1.0
 * Text Domain: frammenti
 * Author URI: https://frammentidicodice.com/
 */

Domain Path

Il Domain Path è il percorso utilizzato da WordPress per individuare le traduzioni quando il plugin non è attivo, ed è utile solo nel caso in cui le traduzioni sono collocate in una cartella diversa dalla cartella principale del plugin.

Il Domain Path può essere omesso se il plugin è nella directory di WordPress.org.

Nell’esempio che segue, le traduzioni saranno da cercare nella cartella /languages/:

<?php
/**
 * @package frammenti
 * @version 1.0
 *
 * Plugin Name: Frammenti
 * Plugin URI: http://wordpress.org/extend/plugins/#
 * Description: This is a development plugin 
 * Author: Carlo Daniele
 * Version: 1.0
 * Text Domain: frammenti
 * Domain Path: /languages/
 * Author URI: https://frammentidicodice.com/
 */

Per essere riconosciute, le stringhe devono essere passate come argomenti di specifiche funzioni, elencate nella documentazione ufficiale. Alcune delle funzioni di internazionalizzazione di WordPress di utilizzo più comune sono le seguenti:

__()

__() restituisce la traduzione di un testo.
Questa funzione accetta due argomenti:

  • $text (string) (Required): Il testo da tradurre
  • $domain (string) (Required): il Text Domain

Se non viene rilevata una traduzione, oppure il Text Domain non è caricato, viene restituito il testo originale.

_e()

_e(): manda a video la traduzione di un testo.
Questa funzione è molto simile alla precedente, con la differenza che, invece di restituire una stringa, la mancìda a video. Come la funzione precedente, anche questa accetta due argomenti:

  • $text (string) (Required): Il testo da tradurre
  • $domain (string) (Required): il Text Domain

Se non viene rilevata una traduzione, oppure il Text Domain non è caricato, viene restituito il testo originale.

_x()

_x(): restituisce la traduzione di un testo dato il contesto gettext.
Questa funzione accetta un terzo parametro rispetto alla precedente:

  • $text (string) (Required): Il testo da tradurre
  • $context (string) (Required): Il contesto di utilizzo di una traduzione, utile ad evitare conflitti tra stringhe uguali ma utilizzate in diversi contesti
  • $domain (string) (Required): il Text Domain

_n()

_n(): restituisce la traduzione nella forma singolare o plurale a seconda del numero fornito come argomento:

  • $single (string) (Required): Il testo da utilizzare al singolare.
  • $plural (string) (Required): Il testo da utilizzare al plurale.
  • $number (int) (Required): Il numero da cui dipende la scelta del singolare o del plurale.
  • $domain (string) (Required): il Text Domain

A questo punto non rimane che dare un’occhiata al codice descritto nei capitoli precedenti. Il plugin registra un nuovo tipo di post, associa due tassonomie, registra e carica il Text Domain. Il codice completo è disponibile su Gist.

Caricare il Text Domain del plugin

Dopo aver dichiarato Text Domain e Domain Path, andiamo a caricare il Text Domain del plugin. Si noti che, a partire da WordPress 4.6, per i plugin tradotti via translate.wordpress.org non è più necessario caricare il Text Domain, come facciamo invece in questo plugin. Maggiori informazioni nel Codex.

In questo plugin ci atteniamo alla regola generale, quindi procediamo a caricare il Text Domain:

function frammenti_load_textdomain(){
	load_plugin_textdomain( 'frammenti', false, basename( dirname( __FILE__ ) ) . '/languages/' ); 
}
add_action('plugins_loaded', 'frammenti_load_textdomain');

La callback viene agganciata all’hook plugins_loaded, che si attiva non appena sono stati caricati tutti i plugin.

La funzione load_plugin_textdomain accetta tre argomenti:

  • $domain (string) (Required): Il testo da tradurre
  • $abs_rel_path (string) (Required): (deprecato) è il percorso assoluto della della cartella dove risiedono i file lingua. Di default è false
  • $plugin_rel_path (string) (Required): il percorso relativo a WP_PLUGIN_DIR dove risiedono i file lingua

La funzione nativa PHP basename, invece, fornisce il nome della directory del plugin.

Maggiori informazioni sull’internazionalizzazione dei plugin sono disponibili nel manuale dei Plugin di WordPress.org.

La localizzazione di un plugin di WordPress

La localizzazione è la creazione dei file lingua che saranno utilizzati da WordPress per visualizzare le stringhe di testo nelle specifiche lingue degli utenti che accedono al sito. Saranno necessari i seguenti file:

  • .pot: è il file che contiene le stringhe originali in inglese
  • .po: è lo stesso file ma con le traduzioni delle stringhe originali. Esiste un file .po per ogni lingua disponibile
  • .mo: è il file machine-readable binario utilizzato dalle funzioni gettext per recuperare le traduzioni

I file dovranno essere collocati nella directory stabilita, che nel nostro esempio sarà /languages/. I nomi dei file dovranno avere la seguente struttura:

[textdomain]-[locale].mo

Dove [textdomain] è il Text Domain, che ricordiamo deve corrispondere allo slug del plugin, mentre [locale] è il codice lingua (ad esempio it_IT). Nel plugin di esempio, il nome del file in lingua italiana dovrà avere questa struttura:

frammenti-it_IT.mo

Il passo conclusivo è la creazione dei file e la traduzione delle stringhe. Tra i vari strumenti a disposizione, ho scelto Poedit, che è uno dei più semplici e popolari. In rete, tuttavia, ve ne sono diversi (si veda il manuale per un elenco degli strumenti disponibili).

Poedit
La home page del progetto Poedit

Poedit

Poedit è un editor che permette di creare i file .pot, .po e .mo necessari alla localizzazione del software, sia che si tratti di temi che di plugin. Poedit viene distribuito in una versione gratuita, dotata di tutto il necessario per creare manualmente i file lingua, e una versione Pro, con funzionalità aggiuntive, come una procedura automatica di localizzazione per WordPress e altri strumenti avanzati.

Poedit
La schermata iniziale di Poedit

1. Nuova traduzione

Il primo passo è la creazione di una nuova traduzione. Si procede dal menu File → Nuovo. Il programma permetterà, quindi di selezionare la lingua della traduzione.

Lingua
La selezione della lingua della traduzione

2. Proprietà del catalogo

Si salvi il file assegnandogli il nome secondo la struttura [textdomain]-[locale]. Nel nostro esempio sarà frammenti-it_IT. A questo punto si dovrà accedere alle proprietà del catalogo appena creato.

Proprietà del catalogo di Poedit
Proprietà del catalogo di Poedit

Si aprirà un pannello composto da tre schede.

3. Proprietà della traduzione

La prima scheda permette di impostare alcune opzioni generali, come il nome del catalogo, la lingua e la modalità di gestione delle forme plurali.

Proprietà della traduzione in Poedit
Proprietà della traduzione in Poedit

4. Percorsi dei sorgenti

In questa scheda vanno inseriti i percorsi dei file sorgente. Si fa click sul segno + per selezionare il file sorgente, che nel nostro caso sarà il file del plugin frammenti.php.

Percorsi dei sorgenti in Poedit
Percorsi dei sorgenti in Poedit

5. Parole chiave sorgenti

Le parole chiave sono i nomi delle funzioni da cui estrarre le stringhe da tradurre. Queste dovranno essere aggiunte cliccando sul pulsante + in alto a sinistra.

Parole chiave dei file sorgente in Poedit
Parole chiave dei file sorgente in Poedit

6. Aggiornamento del codice sorgente

Nel caso in cui dovesse cambiare il codice sorgente, è possibile aggiornare il catalogo dal menu Catalogo → Aggiornamento dal codice sorgente.

Aggiornamento dal codice sorgente in Poedit
Aggiornamento dal codice sorgente in Poedit

A questo punto non rimane che procedere alla traduzione del plugin in italiano.

L'editor delle traduzioni di Poedit
L’editor delle traduzioni di Poedit

Dopo aver tradotto le stringhe e salvato il file, possiamo tornare alla dashboard di WordPress e dare un’occhiata alle etichette del menu e delle pagine di amministrazione.

custom post type localizzato
Il nostro custom post type localizzato in italiano