Traducir al español aplicaciones en Mac (2)

Localizar (traducir) aplicaciones en macOS (parte 2)

Proyecto helloworld

Se parte de un proyecto muy sencillo de aplicación básica creada originalmente en inglés. Su interfaz consiste en una sola ventana que muestra un mensaje al pulsar un botón. El proyecto HelloWorld.xcodeproj inicial consta de un único archivo de interfaz MainMenu.xib sin opciones de localización y carece de archivo Localizable.strings.

Para traducir este programa seguiremos estos pasos:

  1. Generar un archivo Localizable.strings en el que se vuelquen las cadenas que contiene MainMenu.xib
  2. Que los archivos MainMenu.xib y Localizable.strings adquieran la propiedad localizable creando un nuevo idioma para la aplicación (Spanish)
  3. Traducir al español cada una de las cadenas en inglés que existen en Localizable.strings
  4. Traducir alguna otra cadena no presente en Localizable.strings
  5. Probar la aplicación, si todo ha ido bien debe arrancar en español al detectar que es el idioma del sistema operativo.

Localizable.strings

Hay varias formas de generar este archivo e incluso hay programas específicos para esta tarea, para cumplir la restricción de usar solamente software de macOS comentaré 2.

ibtool

La herramienta de línea de comandos ibtool (se instala junto con XCode) es capaz de extraer cadenas y también de integrar las cadenas traducidas dentro de archivos .nib. Su uso es bastante simple:

ibtool –generate-strings-file MainMenu.strings MainMenu.xib

genera un archivo MainMenu.strings con las cadenas de texto de MainMenu.xib.

El archivo .strings generado se puede abrir con los editores de texto habituales y tiene un formato similar a éste:

/* Class = "NSMenuItem"; title = "About HelloWorld"; ObjectID = "58"; */
  "58.title" = "About NewApplication";
/* Class = "NSMenuItem"; title = "Open..."; ObjectID = "72"; */
  "72.title" = "Open...";
/* Class = "NSMenuItem"; title = "Close"; ObjectID = "73"; */
  "73.title" = "Close";
/* Class = "NSMenuItem"; title = "Save"; ObjectID = "75"; */
  "75.title" = "Save";

Su esquema es una sucesión de cadenas de texto (en inglés por ahora) con un comentario que refiere al tipo del objeto junto con su nombre e identificador.

InterfaceBuilder

Desde XCode: al hacer doble clic en MainMenu.xib se abre InterfaceBuilder >> seleccionamos con el ratón la ventana principal (Window) >> menú Tools / Strings >> se muestra una ventana con la lista de cadenas encontradas.
Dentro de esta ventana Strings seleccionamos todos los valores >> copiar >> pegar en cualquier editor de texto donde aparecerán con el mismo formato que en el caso de ibtool. Hay que guardar el documento como texto plano y codificación UTF8 con el nombre MainMenu.strings.

De cualquiera de las 2 maneras se obtiene un archivo .strings cuyo nombre puede ser cambiado a Localizable.strings para guardarlo en la carpeta raíz del proyecto y agregarlo al proyecto desde el menú contextual de XCode sobre el nombre del proyecto >> Add >> Existing files >> configurando el diálogo que aparece igual que en la imagen:

En XCode >> botón derecho sobre cada uno de los archivos >> Get Info >> Make File Localizable >> Add Localization >> escribir Spanish como nombre de idioma >> Add >> cerrar Get Info.
El nombre de los archivos se cambia automáticamente a Localizable.strings (English) / Localizable.strings (Spanish) y MainMenu.xib (English) / MainMenu.xib (Spanish). Además se ha creado automáticamente en la raíz del proyecto una nueva carpeta llamada Spanish con los 2 archivos para el idioma español.

Traducir cadenas de texto

Abrimos con un editor de texto Localizable.strings (Spanish) y traducimos todas las cadenas como en este ejemplo teniendo cuidado de que la longitud de las cadenas no sea mucho más larga en la traducción para que encajen bien en cajas de texto, cuadros de diálogo, botones y demás elementos de la interfaz:

  /* Class = "NSMenuItem"; title = "About NewApplication"; ObjectID = "58"; */
  "58.title" = "Acerca de HelloWorld";
/* Class = "NSMenuItem"; title = "Open..."; ObjectID = "72"; */
  "72.title" = "Abrir...";
/* Class = "NSMenuItem"; title = "Close"; ObjectID = "73"; */
  "73.title" = "Cerrar";
/* Class = "NSMenuItem"; title = "Save"; ObjectID = "75"; */
  "75.title" = "Guardar";

Después hay que integrar las cadenas traducidas para que ventanas y menús queden bien traducidos. Se puede hacer con la herramienta ibtool de esta forma:

– primero se crea una copia del archivo MainMenu.xib (Spanish) (la copia puede llamarse de cualquier manera, en este ejemplo le llamaré MainMenu2.xib)

– después se usa ibtool

 ibtool --strings-file Localizable.strings --write MainMenu.xib MainMenu2.xib

que reemplaza cadenas desde Localizable.strings en el archivo MainMenu2.xib con el resultado final MainMenu.xib.

Se obtiene un archivo MainMenu.xib cuyos textos serán presentados al usuario en castellano de acuerdo a nuestra traducción. La sorpresa surge cuando probamos el programa y vemos que el texto que se muestra al pulsar el botón sigue apareciendo en inglés:

Cadenas de texto que no están en Localizable.strings

Si buscamos Hello, world!!! en Localizable.strings no lo encontraremos, por éso no está traducido todavía. La explicación es que ese texto se genera por código en el momento de la ejecución por lo que en la fase de diseño no existe en MainMenu.xib.
Esto sucede con frecuencia en los programas habituales que serán mucho más complejos que este HelloWorld tan sencillo. Hay que buscar Hello, world!!! en los archivos del proyecto, en alguno de ellos aparecerá como cadena de texto.

En este ejemplo es fácil ver que se encuentra en el archivo Foo.m en que se lee:

  - (IBAction)sayHello:(id)sender
  {
  NSString *message;
  message = @"Hello, world!!!";
  [textField setStringValue:message];
  }

Lo que quiere decir que la acción enviada por el botón Dime Hola es una cadena NSString con el literal «Hello, world!!!» cuyo valor se pasa al campo de texto para que sea mostrado.

Se nombró como condición requerida para que una cadena pueda ser localizada (traducida) que su tipo fuese NSLocalizedString pero aquí se trata del tipo NSString que no es localizable. Hemos de cambiar un tipo por otro pero NSLocalizedString tiene un formato que hay que respetar:

 NSLocalizedString(@"cadena original en inglés", @"comentario");

En este ejemplo concreto quedaría así (el comentario puede ser otro texto diferente a éste):

  NSLocalizedString(@"Hello, world!!!", @"Hello");

Y la instrucción completa quedaría de esta forma:

  - (IBAction)sayHello:(id)sender
  {
  NSString *message;
  message = NSLocalizedString(@"Hello, world!!!", @"Hello");
  [textField setStringValue:message];
  }

No es en Foo.m donde traduciremos el texto, es en Localizable.strings (Spanish) (puede ser al principio o al final o en cualquier otro punto) donde añadiremos la cadena original y la traducida de esta forma tan simple:
Texto original entre comillas + signo igual + texto traducido entre comillas + punto y coma.

Localizable.strings quedaría así:

  "Hello, world!!!" = "¡¡¡Hola, mundo!!!";
/* Class = "NSMenuItem"; title = "About NewApplication"; ObjectID = "58"; */
  "58.title" = "Acerca de HelloWorld";
/* Class = "NSMenuItem"; title = "Open..."; ObjectID = "72"; */
  "72.title" = "Abrir...";
/* Class = "NSMenuItem"; title = "Close"; ObjectID = "73"; */
  "73.title" = "Cerrar";
/* Class = "NSMenuItem"; title = "Save"; ObjectID = "75"; */
  "75.title" = "Guardar";

Si ahora probamos la aplicación vemos que el texto se genera como deseamos.

Comentario final

Esta sería una forma muy resumida de iniciarse en la traducción de aplicaciones en macOS.Por la organización general de las aplicaciones como paquetes con una estructura común según un estándar parece un proceso sencillo de comprender aunque para llevarlo a cabo en programas de más entidad hace falta tiempo y dedicación, piensa que muchos programas tienen varios archivos de interfaz y miles de cadenas de texto aptas para ser traducidas.

Como nota final, respeta siempre los acuerdos de licencia en este aspecto, si el programa es freeware podrás traducirlo sin problemas, en caso contrario conviene contactar con el programador y ofrecerle la ayuda para la traducción. Mi experiencia es que la mayoría de ellos lo agradecen claramente. De esta forma podemos ir extendiendo el español en el mundo informático.
Como esta es una tarea que me interesa bastante, he colaborado en la traducción de varios programas, algunos de ellos software libre como Sparkle.framework, VideoMonkey, BatchMod, Burn, FileUtilsCM, RCDefaultApp, Xee o MP3Gain Express pero también algunos de tipo comercial como VisualHub, RarMachine, etc.
Así que ¡anímate! y traduce aplicaciones al español.

<< Primera parte