Progetti multilingua in Python (parte 3/9).
Attenzione!
Queste guide non sono più aggiornate, e in alcuni punti sono proprio superate.Il mio libro Python in Windows tratta questi temi, e molto altro, in modo molto più completo e aggiornato.
Produrre il template .pot
del catalogo.
Quando avete marcato “abbastanza” stringhe per la traduzione, è ora di iniziare a produrre i file che darete ai traduttori. Non è necessario completare il codice prima di tradurlo: potete cominciare a tradurre, e poi produrre integrazioni e revisioni man mano che il lavoro va avanti. D’altra parte, i traduttori potrebbero stancarsi di star dietro alle vostre revisioni, quindi dovreste fare attenzione a non cominciare troppo presto il lavoro di produzione dei cataloghi.L’obiettivo è produrre un file di traduzione per ciascuna lingua (oltre all’originale con cui avete scritto il codice). Il primo passo però è quello di produrre un template da cui ricavare poi i singoli file.
Tradizionalmente il template ha estensione
.pot
, e i singoli file per ciascuna lingua hanno lo stesso nome del template ma con estensione .po
. Alcuni tool producono subito un template con estensione .po
. In ogni caso, si tratta sempre di semplici file di testo.Python dispone di un piccolo script che scansiona il vostro codice e produce un template
.pot
. In Windows si trova in .../Python36/Tools/i18n/pygettext.py
. Per testarlo, scriviamo prima di tutto un modulo Python che riassume alcuni tipi di stringhe di cui abbiamo parlato finora:# -*- coding: utf-8 -*-
_ = lambda i: i # TODO eliminare in seguito...
ngettext = lambda i, j, k: i # TODO eliminare in seguito...
def main():
print(_('stringa semplice versione originale'))
print(_('stringa non-ascii: èéàòì versione originale'))
print(_('stringa interpolata {} versione originale').format(123))
print(_("""stringa
multilinea
versione originale"""))
num = 12
s = ngettext('Stringa singolare {} versione originale',
'Stringa plurale {} versione originale', num)
print(s.format(num))
# translators: questo e' un commento
print(_('stringa commentata versione originale'))
if __name__ == '__main__':
main()
Chiamate questo file test.py
, fatelo girare e controllate che in effetti funziona: senza gettext
né traduzioni ancora installate, semplicemente i vari print
producono le stringhe originali, interpolate dove occorre.Quindi, dalla shell invocate
pygettext.py
:> py "C:/Program Files/Python36/Tools/i18n/pygettext.py" -d myapp test.py
Se non volete scrivere ogni volta tutto il percorso potete aggiungere la directory alla PYTHONPATH
, creare un collegamento o semplicemente copiare lo script nella directory corrente. L’opzione -d
specifica il “dominio” del catalogo da creare: in Windows come vedremo questo non è molto importante, ma per compatibilità con il mondo Linux conviene specificarlo. In pratica potete passare il nome della vostra applicazione (qui myapp
): l’effetto concreto è che il catalogo prodotto sarà myapp.pot
. Infine, passate come argomenti i nomi dei file che volete scansionare. Se avete marcato più di un file, non vi conviene generare cataloghi separati per ciascuno: passate invece tutti i nomi dei file, in successione (pygettext.py -d myapp foo.py bar.py baz.py
). Ci sono altre opzioni che potete scoprire con la documentazione online (pygettext.py --help
).Il template
myapp.pot
sarà creato nella directory corrente. Apritelo con un editor e trovere qualcosa del genere:# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2018-03-31 19:06+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=cp1252\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: test.py:7
msgid "stringa semplice versione originale"
msgstr ""
#: test.py:8
msgid "stringa non-ascii: èéàòì versione originale"
msgstr ""
#: test.py:9
msgid "stringa interpolata {} versione originale"
msgstr ""
#: test.py:10
msgid ""
"stringa\n"
" multilinea\n"
" versione originale"
msgstr ""
#: test.py:21
msgid "stringa commentata versione originale"
msgstr ""
Il vostro compito adesso è modificare questo template, prima di copiarlo e distribuirlo ai traduttori. Nelle prime righe di commento, sostituite il titolo del progetto e i metadati relativi: potete aggiungere righe di commento a piacere. Il resto del file è composto da coppie msgid
/ msgstr
che contengono rispettivamente le stringhe originali estratte dal vostro codice, e le traduzioni da inserire. Le stringhe sono delimitate da virgolette doppie (escapabili all’occorrenza: \"
). Una stringa multilinea si crea dalla concatenazione di più stringhe successive (senza righe bianche in mezzo).La prima coppia
msgid
/ msgstr
è destinata per convenzione a “tradurre” la stringa vuota ""
: la “traduzione” contiene ancora dei metadati, alcuni dei quali spetta al traduttore completare. La cosa importante da notare è la riga:"Content-Type: text/plain; charset=cp1252\n"
In effetti pygettext
produce file .pot
nell’encoding del sistema (per un Windows italiano, cp1252 appunto) e non in utf-8. Questo succede anche se la dichiarazione di encoding nei moduli Python è per utf-8. Potete controllare con il vostro editor che in effetti il file .pot
è salvato in cp1252.Qui si pone un problema, specialmente in Windows. Se il traduttore siete voi stesso, fate un po’ come credete. Ma se distribuite il file a un traduttore esterno, dovete capire che probabilmente lo aprirà con il Blocco Note, se non addirittura con Word. In questo caso, l’encoding cp1252 tutto sommato potrebbe andar bene: è difficile spiegare a un non-tecnico come aprire e salvare file utf-8 con il Blocco Note. Tenete conto però che se mandate il file a un traduttore all’estero, non è detto che il suo Blocco Note usi cp1252 di default (già nei Paesi dell’Est Europa, per esempio, non è così).
È una questione di convenienza, vostra e dei traduttori. Se preferite avere utf-8, non vi resta che cambiare l’encoding del file con il vostro editor, e ri-salvarlo. In questo caso, correggete per scrupolo anche l’indicazione del charset dentro il file. Dovete però spiegare ai vostri traduttori come usare un file encodato in utf-8 (o forse, meglio ancora, dire loro di installare un editor come Sublime Text o NotePad++ che lavorano nativamente in utf-8, e lasciar perdere il Blocco Note). Va detto comunque che esistono anche degli editor grafici specializzati, riservati ai traduttori, che permettono di lavorare sui cataloghi senza aprire direttamente il file: ne riparleremo.
Le successive coppie
msgid
/ msgstr
contengono le stringhe da tradurre, precedute da una riga di commento che indica il file e la riga di provenienza (ai traduttori non importa, ma a voi può far comodo). Notate che, come abbiamo detto, pygettext
non supporta i commenti “translator” che avete inserito nel codice. Inoltre pygettext
non supporta le stringhe plurali.Per il momento non dovete toccare nulla oltre ai metadati. Una volta apportate le modifiche opportune, salvate e chiudete il template
.pot
.
Commenti
Posta un commento