Lang pack: come è fatto e cosa c’è dentro

Contenuti


Cos’è un lang pack

Un lang pack è un archivio con tutti i file riguardanti i contenuti localizzabili di Mozilla, quali interfaccia utente, segnalibri, schede della Sidebar o qualsiasi altro componente specifico alla regione di interesse. L’obiettivo è rendere possibile all’utente, una volta installato un lang pack, la fruizione di un applicativo rispettoso della lingua e delle convenzioni specifiche a una regione di interesse.

Il formato usato consente in un unico file compresso di racchiudere tutti questi contenuti, più uno script di installazione. Una volta aperto il pacchetto in Mozilla, sotto il consenso dell’utente, viene eseguito lo script, in modo da avere un’installazione completamente automatizzata.

Torna ai contenuti

L’interfaccia utente di Mozilla

Uno dei punti di forza di Mozilla è la grande potenza riguardo il trattamento di dati tramite XML. Una sua esigenza è la possibilità di valicare le frontiere del singolo sistema operativo, rendendo gran parte del lavoro degli sviluppatori in una piattaforma, disponibile e funzionante su tutte quelle in cui Mozilla funziona. Questo ha portato gli sviluppatori a creare un interfaccia utente completamente controllata da tecnologie Web come XML (per i contenuti), CSS (per l’aspetto) e JavaScript (come collante “intelligente” tra i file binari e gli eventi che l’utente tramite mouse e tastiera manda all’applicazione).

Ogni finestra in Mozilla è definita da una pagina XML per cui sono stati creati un insieme di tag (etichette in un file di testo, simili all’HTML) chiamati XUL.

Tra le possibilità offerte da XML c’è quella di richiamare delle “entità” (entity) definite in file esterni, ed utilizzarle come segnaposto per il contenuto ad esse assegnato. In pratica è possibile richiamare in una finestra descritta da un file XUL l’entità “openFile.label” definita in un altro file. Questo nome, al momento dell’elaborazione verrà sostituito con il testo che gli è stato assegnato:

navigatorOverlay.xul

<?xml version="1.0"?>

<!DOCTYPE window [
<!ENTITY % navigatorDTD SYSTEM "chrome://navigator/locale/navigator.dtd">
%navigatorDTD;   ]>

<overlay id="navigatorOverlay"
  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

 <menubar>

  <menu id="menu_File">
   <menupopup id="menu_FilePopup">
    </menu>
     <menuitem label="&openCmd.label;" accesskey="&openCmd.accesskey;"
               key="openLocationKb" command="Browser:Open"/>

     <menuitem label="&openFileCmd.label;" accesskey="&openFileCmd.accesskey;"
               key="openFileKb" command="Browser:OpenFile"/>

     <menuitem id="menu_close"/>
     <menuitem id="menu_closeWindow" command="cmd_closeWindow"
               key="key_closeWindow" label="&closeWindow.label;"/>
     <menuseparator/>

     ...
   </menupopup>
  </menu>

...

navigator.dtd

 <!ENTITY openCmd.label "Apri indirizzo web...">
            <!ENTITY openCmd.accesskey "w">

            <!ENTITY openCmd.commandkey "l">
            <!ENTITY openFileCmd.label "Apri file...">
            <!ENTITY openFileCmd.accesskey "A">

            <!ENTITY openFileCmd.commandkey "o">
            <!ENTITY closeWindow.label "Chiudi finestra">

			...

Con JavaScript abbiamo un meccanismo simile. Le differenze risiedono nel fatto che qua vengono assegnate una serie di variabili con le stringhe poi utilizzate. I file impiegati in questo caso conterranno, nella terminologia dei linguaggi ad oggetti, una collezione di proprietà definite; da cui l’estensione dei file .properties.

pref-themes.js

...
function applySkin()
{
  var navbundle =
    strBundleService.createBundle("chrome://navigator/locale/navigator.properties");
  var brandbundle =
    strBundleService.createBundle("chrome://global/locale/brand.properties");
  ...
  if (promptService && navbundle && brandbundle) {
    var dialogTitle = navbundle.GetStringFromName("switchskinstitle");
    var brandName = brandbundle.GetStringFromName("brandShortName");
    var msg = navbundle.formatStringFromName("switchskins", [brandName], 1);
    promptService.alert(window, dialogTitle, msg);
  }
}
...

navigator.properties

searchFor=Cerca in %S "%S"
showskinsdescription=vero
switchskins=Le modifiche al tema avranno effetto dopo il riavvio di %S.
switchskinstitle=Applica tema
...

Il concetto finale da tenere a mente per comprendere i meccanismi che fanno funzionare un lang pack per Mozilla è la combinazione tra file RDF e il protocollo chrome://
In buona sostanza un file RDF contiene dati XML, in un formato manipolabile in modo similare ad un database.

Torna ai contenuti

Il protocollo chrome

I file di cui ci serviamo all’interno del lang pack sono raggruppati in componenti, pensabili ciascuno come file relativi ad un’applicazione di Mozilla (come ad es. il browser Navigator, il modulo di posta Messenger, ecc). Per motivi di sicurezza, i file di un applicazione, hanno privilegi differenti da quelli di una pagina web (nonostante vengano utilizzate in entrambi i casi molte tecnologie comuni, come XML, CSS, JavaScript..). Ai file relativi alle applicazioni di Mozilla si accede infatti solo attraverso il protocollo chrome:// (e non ad esempio http://).
L’indirizzo di questi file non corrisponde al loro indirizzo fisico (ad esempio il percorso all’interno dei dischi fissi del proprio PC), ma un percorso in cui i file sono stati registrati, o installati se si preferisce, sotto il consenso dell’utente.

Al momento di installare una nuova componente (sia una applicazione intera, un tema dell’interfaccia utente, o un lang pack), Mozilla cerca all’interno dei pacchetti appena copiati, un file chiamato chrome.rdf per ciascun nuovo componente che lo script di installazione cerchi di registrare.
Questo file RDF fornisce a Mozilla tutte le informazioni necessarie ad aggiornare il database interno (registry) relativo alle componenti accessibili attraverso il protocollo chrome://, ovvero tutte le componenti registrate.

Essendo il registry un database relazionale, sarà facile per Mozilla, attraverso un percorso unico, restituire ad un’applicazione le risorse relative a differenti lingue (lang pack) o aspetti dell’interfaccia utente (temi).

Vediamo un esempio di quanto descritto:
Supponiamo di avere un applicazione chiamata “navigator”. Supponiamo di voler registrare per questa due lingue: italiano ed inglese, e due temi chiamati classic e modern.

Nome applicazione: navigator
suddivisa in tre componenti:

  • navigator/contents/
    (file dell’applicazione vera e propria. Principalmente file XUL, JS)
  • navigator/skin/
    (file dell’aspetto dell’interfaccia: il tema corrente. Principalmente file CSS ed immagini)
  • navigator/locale/
    (stringhe dell’interfaccia utente, nella lingua attiva. Principalmente file DTD e string bundle Java “.properties”)
Posizione fisica: file di navigator/contents/
archivio compresso in file:///usr/Mozilla/chrome/comm.jar , nella cartella interna navigator/file di navigator/skin/
Per il tema classic:
archivio compresso in file:///usr/Mozilla/chrome/classic.jar , nella cartella interna navigator/
Per il tema modern:
archivio compresso in file:///usr/Mozilla/chrome/modern.jar , nella cartella interna navigator/

file di navigator/locale/
Per l’inglese:
archivio compresso in file:///usr/Mozilla/chrome/en-US.jar , nella cartella interna navigator/
Per l’italiano:
archivio compresso in file:///usr/Mozilla/chrome/it-IT.jar , nella cartella interna navigator/

Punto di registrazione: I file reali a cui puntano gli indirizzi chrome:// vengono fatti puntare internamente da Mozilla nei file del tema o della lingua corrente.file dell’applicazione accessibili attraverso l’url:
chrome://navigator/contents/ (ad esempio chrome://navigator/contents/navigator.xul )

file del tema corrente accessibili attraverso l’url:
chrome://navigator/skin/ (ad esempio chrome://navigator/skin/pageInfo.css )

file della lingua corrente accessibili attraverso l’url:
chrome://navigator/locale/ (ad esempio chrome://navigator/locale/navigator.dtd )

Torna ai contenuti

Da Mozilla Translator 4.x ad un lang pack installabile

Esportato il lang pack da Mozilla Translator 4 come archivio XPI, questo non funzionerà a dovere con le versioni più recenti di Mozilla. Le cause sono due: lo script di installazione può non rispettare/gestire correttamente le restrizioni del sistema operativo, i file chrome.rdf all’interno degli archivi .jar non hanno le informazioni sulla versione di ciascun componente, come Mozilla richiede.

Da ciascun file XPI, essendo un archivio PKzip la cui estensione è stata rinominata, sarà facile estrarre, modificare e quindi creare un nuovo pacchetto di installazione tramite l’utilizzo di un utilità di archiviazione quale WinZip, o il comando Unix zip.

Per quanto riguarda lo script di installazione, è possibile scaricare questo file di esempio e quindi modificare solo le parti di interesse:

// ----LOCALIZATION NOTE: translate only these ------
var prettyName = "Italian (it-IT) Language Pack";
var langcode = "it";
var regcode = "IT";
var requiredSpace = 350; //in kBytes
var langpackVer = "0.9.8";
// --- END LOCALIZABLE STUFF ---

In ordine dalla prima riga, troviamo: la stringa visualizzata dalla finestra di installazione, il codice ISO per la lingua, il codice ISO per la nazione utilizzato anche per il pacchetto dei contenuti relativi alla regione di interesse, i kilobyte richiesti per far procedere l’istallazione, e la versione del lang pack (non necessariamente uguale al revision number di Mozilla).

registerChrome(chromeType, lpf, localeName + "global/");
registerChrome(chromeType, ppf, localeName + "global-platform/");
registerChrome(chromeType, rpf, regionName + "global-region/");

La lunga serie di righe simili a quelle qua sopra provvederanno ad aggiungere all’interno del locale code che stiamo creando, una voce per ciascun componente di cui forniamo una traduzione. Per ciascuno dei file chrome.rdf contenuto nei file jar dovrà corrispondere una linea simile a quelle sopra.

La prima riga rappresenta un componente presente nella parte non platform specific (it-IT.jar), la seconda un componente compreso in uno degli archivi platform specific (it-mac.jar, it-unix.jar, it-win.jar), ed la terza un componente contenuto nel pacchetto dei contenuti (o “regional pack” IT.jar).

alert("Installazione completata.n Per attivare il lang pack installato, dopo "+
" il riavvio dell'applicazione,nusare Edit | Preferences | Appearance e "+
" selezionare 'Italian (it-IT)'.nQuindi riavviare nuovamente Mozilla.");

Quest’ultimo è l’esempio di vari messaggi informativi che si possono lanciare all’utente durante o dopo l’installazione. In questo caso a fine installazione istruiamo l’utente su come attivare il lang pack appena istallato.

Mozilla accede ai contenuti dei file jar attraverso il protocollo chrome://. Perché i file di ciascun componente siano raggiungibile tramite il percorso predefinito, è necessario siano presenti delle informazioni (scritte sotto forma di file RDF) che associno al percorso dentro i file jar il percorso del componente nel protocollo chrome. È necessario in oltre che vengano incluse delle informazioni di versione per impedire problemi con pacchetti non aggiornati, che Mozilla Translator 4 non fornisce. Tali informazioni sono incluse nei file chrome.rdf all’interno di ciascun file jar.

Anche i file .jar non sono altro che comuni archivi PKzip la cui estensione è stata rinominata, per cui vale il discorso del loro archivio XPI contenitore.

L’approccio in genere più semplice per aggiornare tali file, è estrarre dagli archivi en-US.jar, en-mac.jar, en-mac.jar, en-mac.jar, chatzilla.jar (solo dalla cartella locale/ riguardante il lang pack), inspector.jar e venkman.jar della versione corrente di Mozilla, tutti i file chrome.rdf e sostituire il locale code da “en-US” a “it-IT”. Volendo eseguire un lavoro più accurato si potranno anche riempire i vari altri campi riguardanti l’autore, l’indirizzo dell’immagine di preview, ecc..

Un caso a parte è dato dal componente global-region/, il quale richiede nel proprio file chrome.rdf, la presenza della proprietà:

chrome:localeType="region"

per fare in modo che il pacchetto di contenuti sia riconosciuto come tale e visualizzato nella lista dei pacchetti di contenuti disponibili una volta installato il lang pack. In US.jar, sarà facile verificare la presenza di tale comportamento.

Un ultima nota va all’aggiunta di altri file “di contorno” al lang pack. Questi sono i file con le impostazioni predefinite selezionabili con la regione al momento della creazione di un nuovo profilo. Tali file andranno in defaults/profile/IT/ (per la regione Italia).

Altri file possono essere plugin di ricerca (in stile Apple Sherlock), che andranno in searchplugins/. Perché tali file vengano ricopiati all’installazione, con lo script utilizzato sopra, dovranno essere — con le relative cartelle — all’interno della cartella bin/ dell’archivio XPI.