Localized constant with parameters

Hello everybody

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

What’s is the best way to do that?

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)

1 Like

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)

1 Like

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…

• Code:
string = ParamString(kStrDownloadFile, currentDownloadFile, maxDownloadFiles)

1 Like

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.

2 Likes

@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.