HOWTO: Localize Fire.app by Alessandro Ranellucci Version 1.3.1 (14th April 2005) 1. INTRODUCTION This documents describes best practices for localizing Fire.app. The process itself is quite easy, but requires some extra effort to understand which are the best tools and how to work without spending too much time. For the latest version of this document, e-mail the author or post to the fire-localization list on Sourceforge.net. When you decide to help the project with your language localization, the first thing you should do is to inform the project community: so post a brief presentation to the fire-localization list. 2. REQUIREMENTS The Apple DevTools for MacOS X (Make sure you aren't using August 2002 edition, since a bug was discovered that caused corruption in .nib files when using nibtool.) 3. START LOCALIZING If you're starting from scratch, just download the latest release version of Fire and localize it. We'll discuss below how to keep your localization updated for next releases. There are many ways you can localize the package; we'll discuss each of them. 3.1. Using AppleGlot AppleGlot is a free tool developed by Apple Computer, which allows incremental localization. It is freely downloadable from their website, along with ADViewer, a nice editor that you will use in the process: http://developer.apple.com/intl/localization/tools.html Important things to avoid problems: Make sure to use AppleGlot 3.1. Open Terminal, go to the directory containing Fire.app and do "chmod -R +w Fire.app". Make sure you aren't using non-ASCII directory names as AppleGlot has trouble working on paths containing spaces and non-English characters. To get started with AppleGlot, follow these steps: - Create a folder anywhere on your HD (let's say ~/FireLoc/). - Launch AppleGlot. - Go to "Tools-->Create Empty Environment" and then choose your ~/FireLoc/ folder; this will create several folders in there. - Place a copy of the latest Fire.app into the ~/FireLoc/_NewBase/ folder. - If you're updating a localization, put latest localized release into each of the following folders: ~/FireLoc/_OldBase/ ~/FireLoc/_OldLoc/ - Quit AppleGlot, and then reopen it. - If it doesn't automatically open the ~/FireLoc/ environment, go to "File-->Open" and choose that folder. You'll see a table with check box on the far left. - Click on the check box (it may not visually check it, but internally it does). - Go to "Actions-->Set Target and Base Locales". - Choose your language in the Target menu, and click OK. - Go to "Actions-->Initial Pass". - Open the file in ~/FireLoc/_WorkGlossaries/ from within your favourite text editor (BBEdit is fine, but you're strongly encouraged to use ADViewer; see above) - also, you must preceed all " chars with a backslash (so you must write \") - Go through the document, and put inside each tag the translation of the string you see in . - Once you've finished, go to "Actions-->Final pass" in AppleGlot to merge everything into a new package that you'll find in ~/FireLoc/_NewLoc/. When issueing the "Initial Pass" command, only untranslated strings will be put in ~/FireLoc/_WorkGlossaries/. If you want to modify a string that you've altrady translated, look for it in ~/FireLoc/_ApplicationDictionaries/. One last note. Do not JUST use AppleGlot. Many GUI elements need to be adjusted to fit their new text. So, once you've done with AppleGlot, feel free to use Interface Builder to open .nib files and work on sizes. 3.2. Using Interface Builder (manually) You can just open each .nib file with Interface Builder and translate strings manually; then use your text editor to open .strings files. Please note that .strings files use UTF-16 encoding (also known as "Unicode"). While this method is very easy for the first localization session, it's not very comfortable for updates. You have to make sure about what has changed since last release, by asking other localizers and developers, or by checking modification dates. Why not use AppleGlot so? 3.3. Using nibtrans.sh and tinyglot.pl nibtrans.sh is a little shell script written by Manfred Lippert , that uses the nibtool command to extract text strings from .nib files and puts them in a text file whose name ends with .strings. Then you can translate strings in text files, and run again nibtrans.sh to merge them in the original .nib files. tinyglot.pl is a Perl script written by me, that compares two .strings or .plist files (the unlocalized one that comes from latest build and the localized one that comes from latest public release) and then merges their strings into a new file. New strings, that have no translation, are put at the end of the file so that it's easy to complete them. These tools can be freely downloaded here: http://www.mani.de/nibtrans.sh.gz http://alex.primafila.net/tinyglot/ 3.4. Using PowerGlot or Mushroom PowerGlot is a commercial software that is very similiar to AppleGlot, but much more stable compared to that. Read the manual that comes along with the distribution. http://www.powerglot.com Note that as of 2.0.2 version there seem to be issues with generation of .strings files, that get corrupted. Because of this, I suggest to use tinyglot.pl for .strings files (see above at 3.3.). Mushroom is a $30 shareware tool that works on Project Builder files and has some nice features such as incoherence report. 4. FINAL STEPS 4.1. Localizing preference pane titles Add an InfoPlist.strings file in each prefPane bundle (in your language directory), and put into it a string with a key of CFBundleName. Remember to use UTF-16. Example. The file in Fire.app/Contents/PreferencePanes/Appearance.prefPane/Contents/ Resources/it.lproj/InfoPlist.strings will contain the following line: "CFBundleName" = "Ambiente"; When updating, remember to copy these two files from English.lproj to .lproj: MVPreferencePaneGroups.plist MVPreferencePaneGroups.strings (it has a few strings to localize) 4.2. Localizing param text "%@" In some cases there are messages which have two or more parameter words like "%@". For example, the US message "%@ of %@ files are selected." is the same as "%1$@ of %2$@files are selected.". If the localized message takes different order for the parameter words, you will need to change the parameter words, and replace them, like "There is %2$@ files, and you select %1$@ files.". BE SURE TO NUMBER EACH ITEM WHEN YOU MOVE THEM. Failure to number your Param items correctly may result in a crash. 4.3. Testing your localization Yes, it would be good to test your localization before releasing it. If you find some strings that seem to be untranslatable (perhaps because they're hard-coded in the sources), feel free to post to the fire-localization list so that developers can check and do a fix. 4.4. Uploading the package to the tracker Before uploading your work, you should strip from the package all files that are not related to your language. There are two ways to to this. The first one is to open Terminal and type these commands: cd Fire.app find -d . \! -path '*it.lproj*' \! -type d -exec tcsh -c 'rm "{}"' \; find -d . -type d -exec tcsh -c 'rmdir "{}"' \; Of course, "it.lproj" must be changed to match your language. The second way is to use a simple tool I've developed, that you can freely download from here: http://alex.primafila.net/PackageStripper/ Then, after having put Fire.app into a .dmg or .tar.gz or .sit package (PackageStripper does so automatically), you can go to the SourceForge.net tracker and upload it. Specify language and version in the summary. http://sourceforge.net/tracker/index.php?group_id=33772&atid=522417 5. KEEPING LOCALIZATION UPDATED A few weeks before each release, the developers will post a "localization freeze build" that localizers use to update their localization. When all languages have been submitted to the tracker, everything is committed into the CVS and the software is released. 6. ACKNOWLEDGEMENTS A big thank to all Fire developers for providing such a useful software. Also, thanks to Matthew "Guifa" Stuckwisch for helping me at the first steps and for providing the first AppleGlot HowTo (from which I took many things for this document), and to Heimir Freyr for the trick explained in 4.2.