Localization

Aperture Plugin: Integrating Localized Data Part 2

cocoasmall
Now the strings in my code and my image are localized into French as well and English, I can move on to the strings in the interface. So far the French nib is just a copy of The English nib, created when I made the French nib localization. I used nibtool to extract the strings before translation, and I use nibtool again to put the translated strings back.

To do this I fire up Terminal, cd to the French.lproj folder and use the following command line:

nibtool -w new.nib -d file.strings Random_Wok.nib

This creates a new nib file with the English strings replaced by French ones. I use the Finder to replace the old nib with the new one and I am done. Now my resources look like this:
rwok344
But if I run the plug-in in French, some of the strings no longer fit:
rwok345
This is unfortunately typical for English. With its huge vocabulary, English can take up as little as 50% of the space of other languages. So my nice tight interface needs adjusting.

And there is a problem with subversion. After checking all of this in I find that my repository does not contain the French files and the NoImage.tiff file is in both the localized and the main folder:
rwok346
To fix this I do two subversion things: svn delete the extra TIFF and svn add the folder and its contents. Svnx could do the delete, but not the add. After a fair amount of trying things that did not consistently work, I eventually went to the command line, did a svn add of the French.lproj folder, then quit and relaunched Xcode, then finally did a commit. That worked and now everything is synchronized.

I fix the layout with IB, but don't neaten it up yet. That's because I want to run it past my translator again to make sure nothing weird has happened that I won't spot. Once the translator has OKed it, I'll peek the pixels and straighten everything.

And then there is the "Images Selected" binding. I have this set up with two display patterns, one for the number of images and one for the pluralization string. For French I have to put the second string in twice since both words gain an "s" in the plural:
rwok347
When I come to add German, this will break. The German strings are "Bild ausgewählt" and "Bilder ausgewählt". There is an "er" added in the plural, not an "s". Japanese is easy: no plurals exist in the language. A better solution is to put both singular and plural strings in the strings file and do all of this in code.

The other parts of this series can be found via the Cocoa page.
|

Aperture Plugin: Integrating Localized Data Part 1

cocoasmall
Now my translators have sent back localized versions of Localizable.strings, file.strings, and images that I sent to them, I can integrate them into my project. Here is how my project is organized right now:
rwok330
To localize the NoImage.tiff image, I select NoImage.tiff and get Info, then click on Make File Localizable:
rwok335
This changes the image into a group and shows the targets that it is associated with:
rwok336
The Resources have been rearranged like this:
rwok337
Clicking on the General tab shows the languages that the image is localized for:
rwok338
I'm going to add French, so I click Add Localization and select French. The French image created by Xcode is just a copy of the English image at this stage:
rwok339
To get my French image in, I change its name from PasDimage.tiff to NoImage.tiff so that the code will be able to access it with the same file name and replace the current image in the French.lprog folder via the Finder. Xcode has a handy contextual menu item called Reveal File In Finder to help with this.

To Localize the strings I do the same sequence, this time putting my English Localizable.strings into the English localization as well as the French Localizable.strings file into the French localization.

I localize the nib file too, creating the localization, but just leaving it as a duplicate of the English for now. I want to see how Random Wok works in French with what I have to far. Only a few things will be French at this stage: the progress message and the missing thumbnail image will show me that things are working correctly. But how to run in French?

I go to the International preference pane and move French to the top:
rwok340
Now when I run Aperture it will be French.

But when I do, I find that the NoImage image is not there. And when I run it in English it is not there either. The problem is this code:
rwok341
I get the TIFF file using a path that does not take into account the localization folders (English, French). So the initWithContentsOfFile method fails and returns nil. The fix is to use -pathForResource:ofType:inDirectory with a nil directory name:
rwok342
And now the image shows up correctly when I run in French or English:
rwok343
Next is fixing the interface strings.

The other parts of this series can be found via the Cocoa page.
|

Aperture Plugin: Instructions To Localizers

When I sent the materials to my localizers I included a lot of information and some detailed instructions. The idea was to preempt any questions, delays, and mistakes. I put all the localizable files into a folder and ZIPped it for sending. Included in that package were the localized string files from Aperture itself. In that way the translators could see how Apple had expressed the terminology and maintain consistency.

The first item in the instructions was a series of screen shots of the plug-in. Several were needed to show the basic interface plus the pop-up menus popped up. The screen shots give the strings context and make it possible for localizers to work with the plug-in even if they cannot run it.

Here are the instructions I provided:

Enclosures
Enclosed is a ZIP file with a 
Localizable.strings file that was created by the genstrings utility. It contains all the strings that are localized in the application code. Also included is a file.strings file that has all the strings from the nib (user interface) and a TIFF image.

There is a folder for each language enclosed that contains a copy of the strings file used by Aperture. You can use this as a reference to see how Apple has translated things like Version Name. This will help consistency. 


What To Do
You will need to use an editor that can handle UTF-16 encoding. TextWrangler can do this as can many others. Apple recommends this simple editor:

ftp://ftp.apple.com/developer/Tool_Chest/Localization_Tools/ADViewer_2.1.dmg

Edit the text in the strings files to make the second string the translation. For example if I were doing a British English translation:

/* NSMenuItem : (oid:278) */
"Period" = "
Period";

becomes:

/* NSMenuItem : (oid:278) */
"Period" = "
Full stop";

Do not alter the comments or the other strings in the files. Be aware of the semicolon at the end of each line.

The Localizable.strings file is a slightly different format with the comment and the first string telling you what the string is used for:

/* Continue renaming after failure */
"rename-error-continue" = "Continue";

This helps distinguish some subtle differences in meaning or tense that may not be conveyed by English.

The strings may include substitutions. These are identified by a leading %. For example:

"%@
のコピー %d";

The substitutions should be left alone and just the text translated. Notice that some strings have numbers prefixing the substituted arguments. The numbers define the order of the substitutions in the first string:

/* Message in alert dialog when something fails */
"%@ Error! %@ failed!" = "%2$@ blah blim, %1$@ bloo!";

The translated message above reverses the arguments, as may be needed in some languages.

You can enter characters directly into the second string and can use Unicode by prefixing with \U. For example \U0020 is a unicode space.

In addition translations are needed for:

"
No Image"
This appears in the table (as a graphic) when no thumbnail image is available for display. I will create a graphic for each language unless you want to do that. I have enclosed the graphic I currently use.

Please do translate "Random Wok". If you can!

One part of the interface has a plural that is used if more than one image is present: "3 images selected", but "1 image selected". Please provide both the singular and plural translations for this phrase. I handle the pluralizing in code, and depending on the language will have to change the way I do this.

What To Deliver
The files you deliver (Localizable.strings, file.strings, and a file containing the translation for No Image and the two forms of Images Selected) must be encoded
UTF-16. Please ZIP the files together so they don't get mangled by email systems.

For technical background information see Apple's documentation:
http://developer.apple.com/documentation/MacOSX/Conceptual/BPInternational/index.html

Specifically this page:
http://developer.apple.com/documentation/MacOSX/Conceptual/BPInternational/Articles/
NotesForLocalizers.html#//apple_ref/doc/uid/20000044


What Happens Next
I will take your strings files and put them into the project. For those that live in the nib, I duplicate the nib file and then will adjust the layout so that things fit. It is likely, English being such a terse language, that things will have to move somewhat. That is OK, but finding translations of similar size would be most helpful.

I will send you a beta of the plugin when it is ready so you can check that is still OK. Your comments on the beta as well as what I have done with your strings will be welcome.

There were actually some problems. I had mistakenly left a macro in my source files that contained strings that were nothing to do with my plug-in, so that was translated unnecessarily. Despite my efforts with the screen shots, not all of the meaning was clear and I had to answer some questions about some words. One of the ZIP files came back empty for unknown reasons. I also realized that the way I have implemented the pluralization of the number images selected -- providing a method to add the pluralising string "s" -- is unlikely to work in all languages. So I will need to change that.

The name itself, Random Wok turns out to be hard to translate. A Wok is literally a Chinese Pot in Japanese. So I opted for the more phonetic Randamu Wokku ランダム・ウオック. And the phrase No Image is seven characters that I am supposed to keep on one line inside a small button. So I had to request a different meaning for that.
|

Aperture Plugin: Preparing For Localization

cocoasmall
Random Wok 1.0 is currently not localized: the only language it supports is English. Before I release the 1.1 version I am going to add translations for the languages that Aperture supports: French, German, and Japanese. This requires extra files in the plugin's bundle that provide the language information.

To prepare, I replace all the messages and strings that are generated by the program and are human-readable with macros that retrieve the localized version. Code like this:
rwok240
is replaced by code like this:
rwok241
I use the NSLocalizedStringWithDefaultValue macro because it allows me to provide a key (exporting-images in this case) that is not the same as the string Exporting Images.... It also supports use of a specific bundle. I need that because Random Wok is a plugin and otherwise Aperture's main bundle would be used.

Once I have replaced all the strings in my code with macros, I use the terminal to run the genstrings utility on all the source files in my project:
rwok321
I get this entry in the text file Localizable.strings created by genstrings for the exporting-images string above:
rwok242
To provide for other languages the Localizable.strings file is duplicated and the string on the right replaced by the translation. When the plugin is run, the correct language files in the bundle are accessed and the key used in the code (exporting-images) matched with the entry in the file. Since the file is encoded UTF-16, the right hand string can contain ASCII and any unicode characters.

There are two other sources of strings that I need to worry about for localization in my plugin. First, the nib file contains all the strings used in the interface and it is currently English-only. To fix that I will need a new nib file for each language and will probably have to adjust the placement of some interface elements due to the size of the new strings. Second, I have an image that is displayed when there is no thumbnail available that says "No Image". That will have to be replaced with a new image for each language.

Apple provides a tool for helping with the translation of nibs called nibtool. Nibtool used with the -L option extracts all the strings from a nib file and sends them to stdout. The Random Wok nib file generates entries like these:
rwok325
As before, a translation replaces the right hand string. Nibtool is used again to replace the strings in copies of the nib file with the translated versions.

The other parts of this series can be found via the Cocoa page.
|

Aperture Plugin: Translations Needed

rwok21
My next release of Random Wok will be localized. Since Aperture supports English, French, German, and Japanese my plugin cannot successfully support any more languages than those.

Are there any readers interested in volunteering their language skills to this task? There are probably less than 20 translations needed in all, maybe 150 words total. I will provide plain text files for translation: there is no need to have XCode or any development tools.
|
The Bagelturf site welcomes Donations of any size