I18n Guide for developers

While there is no official guide available one may name the i18n properties in a random way. This will make it nearly impossible to translate the i18n file without looking closely at the application. So I did create this ‘Proposal to make language files more easy to translate’.

http://sourceforge.net/projects/popeye is a tool to work with i18n files, especially if you don’t have an IDE and want to translate an i18n file this may be useful for you.

### I don't like these as nobody knows where they may be used
### So one will need to translate strings some more times, but this seems
### to be the better price to pay than using random shortcuts
# generic.label-username=&Username # generic.label-password=&Password
# generic.button.ok=&Ok | &Ok
# generic.button.close=&Close | &Schliessen
# generic.button.cancel=&Cancel | &Abbrechen
### A window with Close and Cancel would contain 2x &C ### Also very bad
# button.browse = &Browse...
# button.browse2 = B&rowse...
# button.browse3 = Br&owse... ### One can anyhow use these, without ampersand
# generic.button.ok=Ok
# generic.button.close=Close
# generic.button.cancel=Cancel ### Add a "Clearspace" keywords list as a comment to the head of the file,
### so one knows which strings must be translated very often
# Translate these words first - they are used very often
# Keywords=Username, Account, Password, Ok, Cancel, Close, Name, Room, Conference, ... ### RMB=right mouse button ### naming - trying to follow these rules
### a dot (".") is used as a seperator to create a tree structure,
### unnecessary dots must be avoided
# OBJECT=(label|button|checkbox|status)-STRING ................. e.g.: button-quit
# POPUP=(RMB-|LMB-|MMB-|)popupmenu(-STRING|) ................... e.g.: RMB-popupmenu-room
# windowname.(windowtitle|maintext|text|modaltitle)=foobar ..... e.g.: spark.windowtitle=Spark
# windowname(.(tab|group)-STRING)*.(title|OBJECT)(.POPUP.OBJECT)?=foobar ....... the complex one (;
#                                                                        ....... examples see below
# windowname.menu.STRING(.STRING)=foobar ....................... e.g.: spark.menu.help.about=&About
# windowname.icon-STRING.tooltip=STRING ........................ e.g.: spark.icon-aim.tooltip=AIM
# windowname.trayicon.POPUP.OBJECT=foobar ...................... e.g.: spark.trayicon.RMB-popupmenu.button-close=Quit ### keep the change log in SVN and not in this file ### start of i18n file
# Keywords=Username, Account, Password, Ok, Cancel, Close, Name, Room, Conference, ... login.windowtitle=Spark
login.label-username=&Username
login.label-password=&Password
login.label-server=&Server
login.checkbox-savepassword=Sa&ve Password
login.checkbox-autologin=&Auto Login
login.button-quit=&Quit
login.button-accounts=A&ccounts
login.button-advanced=A&dvanced
login.button-login=&Login
login.status-auth=Authenticating
login.status-conn=Connecting - Please wait ...
login-accounts.windowtitle=Create New Account
login-accounts.maintext=Account Registration
login-accounts.text=Register a new account to chat
login-accounts.label-username=&Username
login-accounts.label-password=&Password
login-accounts.label-confirmpassword=Confirm Passw&ord
login-accounts.label-server=&Server
login-accounts.button-createaccount=C&reate Account
login-accounts.button-close=Close
login-advanced.windowtitle=Preference Window
login-advanced.maintext=Advanced Connection Preferences
login-advanced.text=
login-advanced.tab-general.title=General
login-advanced.tab-general.checkbox-autodiscover=&Automatically discover host and port
login-advanced.tab-general.group-connection.title=Connection
login-advanced.tab-general.group-connection.label-host=&Host
login-advanced.tab-general.group-connection.label-port=&Port
login-advanced.tab-general.label-resource=&Resource
login-advanced.tab-general.label-responsetimeout=Response &Timeout
login-advanced.tab-general.checkbox-oldsll=&Use old SSL port method
login-advanced.tab-proxy.title=Proxy
login-advanced.tab-proxy.use=Use proxy &server
login-advanced.tab-proxy.label-protocol=P&rotocol
login-advanced.tab-proxy.protocol-dropdown.socks=SOCKS
login-advanced.tab-proxy.protocol-dropdown.http=HTTP
login-advanced.tab-proxy.label-host=&Host
login-advanced.tab-proxy.label-port=Por&t
login-advanced.tab-proxy.label-username=&Username
login-advanced.tab-proxy.label-password=&Password
login-advanced.button-ok=&Ok
login-advanced.button-cancel=&Cancel
login-advanced.button-usedefault=Use &Default #spark.windowtitle=Spark
spark.menu.spark=&Spark
spark.menu.spark.status=&Status (open a sub menu here to select the status, e.g. Alt+S,S, spark.menu.spark.preferences=&Preferences
spark.menu.spark.changeprofile=&Change Profile
spark.menu.spark.plugins=Pl&ugins
spark.menu.spark.logout=Log out
spark.menu.spark.logoutstatus=Log out with reason
spark.menu.contacts=&Contacts
spark.menu.contacts.add=&Add contact
...
spark.menu.help.about=&About
spark-preferences.windowtitle=Preferences
spark-preferences.tab-chat.title=Chat
spark-preferences.tab-chat.maintext=Generic Chat Settings
spark-preferences.tab-chat.text=
spark-preferences.tab-chat.group-generic.title=Generic Information
spark-preferences.tab-chat.group-generic.newpassword=Enter new password
spark-preferences.tab-chat.group-generic.confirmnewpassword=Confirm new password
spark-preferences.tab-chat.group-chatwindow.title=Chat Window Information
spark-preferences.tab-chat.group-chatwindow.checkbox-showtime=Show time in chat window
spark-preferences.tab-chat.group-chatwindow.checkbox-spellcecker=Use spell checker
spark-preferences.tab-login.title=Login Settings
...
spark-preferences.tab-notifications.checkbox-updatebeta=Check for beta updates
spark-preferences.button-close=Save and Close
spark-addcontact.windowtitle=Add new contact
spark-addcontact.maintext=Add new contact
spark-addcontact.text=Add user to roster
spark-addcontact.label-username=&Username
spark-addcontact.label-displayname=&Visible user name
spark-addcontact.label-group=&Group
spark-addcontact.button-new=&New
spark-addcontact.button-add=&Add
spark-addcontact.button-cancel=&Cancel
spark-addcontact-newgroup.modaltitle=New Roster Group
spark-addcontact-newgroup.label-name=&Enter name of new group
spark-addcontact-newgroup.button-ok=&Ok
spark-addcontact-newgroup.button-cancel=&Cancel
...
spark.icon-addcontact.tooltip=Add contact
spark.icon-aim.tooltip=AIM
spark.icon-aim.RMB-popupmenu.button-register=
spark.icon-aim.RMB-popupmenu.button-login=
spark.icon-aim.RMB-popupmenu.checkbox-autologin=
spark.popupmenu-status.button-availabale=Available
spark.tab-contacts.
spark.tab-contacts.RMB-popupmenu-group.button-addcontact=Add Contact
...
spark.tab-contacts.RMB-popupmenu-buddy.button-startchat=Start Chat
...
spark.tab-conferences.
spark.tab-conferences.label-addservice=Add conference service
spark.tab-conferences.RMB-popupmenu-service.
spark.tab-conferences.RMB-popupmenu-room.
...
#spark.trayicon.tooltip=[Spark sets this for you]
spark.trayicon.RMB-popupmenu.button-quit=&Quit
...

special characters

Special characters can be escaped using their hexadecimal unicode number. If you don’t want to use the translator tool for just a few chars, enter them directly. E.g. the german ‘umlaute’:

ä = \u00e4

ö = \u00f6

ü = \u00fc

Ä = \u00c4

Ö = \u00d6

Ü = \u00dc

ß = \u00df

replacements

Use strings like this:

yourplugin.message=This message was send on at to all users of this server.

String curdate = "31.08.2007";
String curtime = "09:00 am";
int usercount = 42;
String message = LocaleUtils.getLocalizedString("yourplugin.message", "yourplugin", Arrays.asList(curdate,curtime,usercount));