Translating Jukebox Jockey

I want to write a little about the language/translation support, how it works, where it is up to and, if you're interested in this feature, what feedback we like from you to help us get it all completed.

It's worth a quick mention here also that even though the primary aim of this feature is to provide the ability to translate to other languages, that is not its only use. For exmaple, we have one customer that I know of that is using this to change the wording on the "Request List" button to something that he believes is more meaningful to his customers (bars, clubs etc).

As mentioned in my BETA announcement, we don't have any language translations available at the moment. I have thought about running them through Google Translate, and as I test run I did it and it appears to work, however since I only know English (and some would question how well I know that :-) ) I have no way of verifying if the translations make sense or are in context. So, if this is something that you are interested in then we would really appreciate your help in getting this stuff sorted out so that Jukebox Jockey is more accessible to both our users and yours.

To get started, make sure you have downloaded the BETA and have it installed on your system. If you haven't done that already, make sure to follow the instructions on my blog post and start/stop JJ then change the ini file setting:

[Settings]
...
LanguageFilesEnabled=1

Now start up Jukebox Jockey and go to the configuration screen and expand General>Language. This will be empty, click Export. Now enter a name for your translation, an obvious name would be the language you want to translate to, but something like TEST is fine also. This will create a new file named "lng_[yourname].dic" in JJ's Plugins\LanguagePacks folder. The files are plain text files, so you can simple open it in notepad or your favorite text editor (I use Notepad++ myself).

The file itself is not complex, it is a list of Name=Value (Name/Value pairs). The "Name" being the part that identifies the piece of text, this should NOT be changed, the "Value" is what will be displayed so this is what needs to be modifed (translated). It's one thing to open the file and change some text, but how do you know which piece of text you are changing? Well hopefully I have named everything reasonably well, and that will hopefully mean that it's quite obvious from the name, although you will probably want to have Jukebox Jockey open at the same time as your language file so that if it's not clear what you are changing then you can navigate to that place and have look at what's there. You can also reload your language file, so see your changes as you go.

So how do the Names work. Well there are a few kinds of Objects that display text and there are a few kinds of Objects that can be the "parent" of something that can display text. For example a Window probably doesn't have its own text, but it will have Buttons, Checkboxes and Labels that do. So the names typically have a dot "." separating Parent from Child. For example there is an entry "frmJJMain.btnShowRequestlist". frmJJMain is the main Jukebox Jockey window and btnShowRequestList is the "Request List" button. Unfortunately just now I have realised that some things could have been slightly better named so that they would group better for this translation stuff, but I am sure it will work out fine.

The first "parent" part of the name will be one of the following kinds of objects:
- Window: (for example frmJJMain, that main Jukebox Jockey window, typically starting "frm")
- configuration frame: one of that sections of the config screen. Typically ending in "cfg" like "MenuCfg", unfortunately now I wish they started with "cfg".
- command: those things that you can assign to users or add to the more options Pop Up menus.
- CommandCategory: this is a heading (category) for commands, that helps to arrange the commands in list where you can pick them
- configCategory: this is a heading (category) in the config screen
- configEntry: this is the name given to a settings page in the config screen
- frame: this is like a prebuilt sections that forms a part of the main JJ Window. (eg the Player area, playlist editor, view tester)

Where there is a second "parent" part in the name (ie a name has more than one dot ".") then that second level parent will almost always be a frame as described above. Sometimes I reuse these prebuilt seconds in different places, so a child (eg a button) may have the same name. The child part of the name (the bit after the final dot) is the name of the object that actually displays the text. It could be one of the following kinds of objects:
- button: prefixed "btn"
- check box: prefixed "cb"
- label: prefixed "lbl". A label is just an element on the screen that can display text, but you don't typically interact with it.
- group box: prefixed "gb". A group box typically combines a label and a border line around an area on the screen.
- the name of something that isn't a visible screen element: for commands, command categories, config entries and config categories
- dialog caption or text: For example we have "frmJJMain.ConfirmTracksClearCap" and "frmJJMain.ConfirmTracksClearMsg". When a "dialog box" is displayed it typically contains a window title (at the top of the window) and a message (in the contents of the window)
- dynamically modified text: some of the text needs to be updates in code, for example "Tracks: 1, Duration: 0h 23m" for the request list information. Or something more complicated like the random play status information (frmJJMain.RPText) which has 7 entries so that we can intelligent provide information depending on the state of Random Play.

Now I will talk about what is displayed and how that is sometimes modified depending on the contents of the "Value" part of the entry in the language file.

1. HTML styling - most parts of JJ support pseudo HTML styling for text. Generally you don't need to worry about using it, because the font settings for the skins take care of most of it, but occasionally it is used when we need to highlight something, or simply to shrink some text to make it fit. For example the Scan buttons on the "CollCfg" (Media Collection Configuration screen) use <font size="8"> so that we can have some small text on them to make them display more information. The main use of the HTML styling though is the use of <BR> to send the rest of the text to a new line. While the <BR> will probably work everywhere, it is mostly used on Buttons and in Mesage Dialog windows.

2. Dynamic Modified Text - this isn't used too often, but it is important to know how it works. This enables JJ to substitute text into a customized label so that it can dynamically represent the state of some part of Jukebox Jockey. For example this entry:

frameQueue.ListCaption=<main.infotitle>Tracks: <main.info>%d, <main.infotitle>Duration: <main.info>%s

This is the entry that controls the "Request List Details". <main.infotitle> and <main.info> represent the font styles to use (as configure in the Skins>Fonts area) but what we're interested in here is the "%d" and the "%s". %d represents a number and %s represents a text string. In this case it means that Jukebox Jockey is going to substitue %d with the number of tracks that are curently in the request list, and %s with a formatted string showing the duration of the request list (eg "0h 23m"). If you don't have the %d and %s in there, then the substitutions won't happen.

Because this is our first attempt at releasing this kind of feature I am sure there will be bugs and flaws that we need to resolve and if you are working on a translation yourself, please don't hesitate to ask if you get stuck on something, or something just doesn't seem to make sense. I do want o highlight one such flaw now.

While most of the text is available in the export file that is created by starting JJ and running an export (as outlined above), there are some things are the translation system doesn't know about until it has been displayed on screen for the first time in a given session of JJ. Typically that's the message dialog windows. So their captions and messages aren't available in an export if you run that export at straight after starting Jukebox Jockey. Now there are workarounds for this and I will evetually come up with a better way. So to ensure that you can translate a message dialog you need to first get JJ to display that dialog on the screen. For example, add a track to the request list and then click the Request List Clear button to display the Request List Clear dialog, now you can run an export that includes those messages. Once your export includes the messages there is no need to go through that process again. Your export also exports what is currently loaded, not JJ's defaults, so if you load a German language file and run an export, then you will be exporting a copy of the German language file, and it should be safe to simply export over the top of the one you already have (if you've done a lot of work though it would be worthile saving a copy, just in case).

Another way to get the entries into the file is to manually enter them, but of course you need to know what they are. This is my next job, to sift through everything and come up with this list and make it available to anyone that wants to use it.

Other limitations are that some skin elements have text on them (namely "Add Selected" and "Add All") to change that text means modifying the skin images. Menu Buttons and Views have English text inside them and the this language file stuff has no effect on it. You may also need a custom keyboard for your language. We do have a couple available now in our default installer.

Copyright 2015 Jukebox Jockey, LLC