I’m looking for good practices in app localization. Of course I use dynamic constant for that. Now I’m looking to add parameters in my localization code for example:
us/uk constant : “Are you sure you want to delete % rows in %?”
french constant: “Etes-vous sur de vouloir supprimer % élément dans % ?”
In my code I want to replace the % by an int and the % by a string
For now I use %1 and %2 in my constants and apply a String replace
I use “¿%” and I do something like : MyDialogBox(MyLocalizeString.Nthfield("¿%", 1) + MyVariable + MyLocalizeString.Nthfield("¿%", 2)
I do not use string.replace. I’m suppose to know how many ¿% I have in my localized string. It’s true that if a guy localize my string and the sentence invert the two variables, it will be wrong. MyDialogBox(MyLocalizeString.Nthfield("¿%", 1) + MyVariable1 + MyLocalizeString.Nthfield("¿%", 2) + MyVariable2 + MyLocalizeString.Nthfield("¿%", 3)
My method is taken from Mac OS classic (before Mac OS X). I do like this:
“Do you want to save changes to “^0” before ^1?”
And then: MyString=MyString.Replace("^0",DocumentName).Replace("^1",if(AppQuitting,CstQuitting,CstClosing))
With more variables, this can then be used in a loop:
Var MyReplacements() as string=Array(DocumentName,CstOperation,CstAdditionnalString)
Var Question as string=“Do you want to save changes to “^0” before ^1, considering ^2?”
for i as integer=0 to MyReplacements.LastIndex
Question=Question.ReplaceAll("^"+i.ToString,MyReplacements(i))
next i
(written here from scratch, so there might be syntax errors)
I basically do the same as Arnaud using a ParamString method I created a very long time ago.
Protected Function ParamString(pSourceString As String, ParamArray pParams As String) as String
Dim itemCount As Int32
Dim theParam As String
itemCount = 0
For Each theParam In pParams
pSourceString = ReplaceAll(pSourceString, "^" + Str(itemCount), theParam)
itemCount = itemCount + 1
Next
Return pSourceString
End Function
Example:
• Constant kStrDownloadFile:
Downloading File ^0 Of ^1…
I regularly work with 25 different translators and have some experience with localized constants.
The best way is the way that suits you and doesn’t lead to translation errors, which will happen eventually.
Using %1 and %2 is a good way but doesn’t give any context to the translator.
Using multiple identical “¿%” is a very bad solution because many languages will swap the order of variables/words, even in European languages.
I usually have these placeholders in my localized constants:
%1 replaced with a number
%2 replaced with a number greater than 1
%S replaced with a string / word
%1S, %2S… if replaced with several strings
%@ replaced with the application name (my apps have different names in Arabic, Hebrew, Chinese, Japanese…)
%URL
%D replaced with a date
In my apps I also have a CheckTranslation method that cycles through each language and important constants.
If will check each String constant that has a placeholder.
It will check selected Strings for line breaks…
When it comes to providing the translator with the files to translate, I used to send them the Lingua App and xojo_locale file
Unfortunately Lingua is too limited for professional translators.
Nowadays I export the xojo_locale file to Tab delimited, import it in Google Spreadsheets and add several columns to the spreadsheet:
my comment
translator questions
screenshot for context (only if necessary)
example with placeholders replaced in context
It takes more time to prepare, import, export but my translators find it much easier and efficient.
@Jeremie_L : Lingua is really not good. I’ve got a version of Open Lingua from Thomas Tempelmann with Deepl integration at Some Xojo code . For myself I made Excel import and export because csv is annoying.