Android Tutorial [B4X] Localizator - Localize your B4X applications

Localizator is a cross platform solution for strings localization.

The strings are defined in an Excel workbook.

SS-2016-07-07_17.00.16.png


They are then converted to a SQLite database file with a B4J program:

SS-2016-07-07_17.21.20.png


The database file should be added to the Files tab of your application.

Localizator is a class. You need to add it to your B4A, B4i or B4J program. It loads the set of strings based on the device locale or based on the forced locale (Localizator.ForceLocale).
Each string is identified by a key. The key matching is case insensitive. If there is no match then the key itself is returned (the value passed to Localize method).

There are some helper methods to automate the tasks. The main one is LocalizeLayout. It will go over all the views and will replace the matched keys.

Values can include parameters. For example "Hello {1}!". LocalizeParams deals with such values:
B4X:
lblHello.Text = loc.LocalizeParams("Hello {1}!", Array(edtName.Text))
{1} will be replaced with the first parameter from the array.

Notes

- In B4A it is recommended to declare and initialize the Localizator from the starter service.
- The three examples attached are a bit more complicated as they allow the user to change the language.
In its simplest form you just need to initialize the localizator and call loc.LocalizeLayout.
- Languages two letters codes: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

upload_2016-7-7_17-13-53.png
upload_2016-7-7_17-14-9.png
upload_2016-7-7_17-28-25.png


The compiled executable jar of the B4J converter can be downloaded from: www.b4x.com/b4j/files/B4XLocalizator.jar
The source code is attached (depends on XLUtils).

B4A, B4i and B4J examples are also attached.

Localizator v1.01 is attached.

Automating the localizator: https://www.b4x.com/android/forum/t...our-b4x-applications.68751/page-3#post-548169

B4XPages example: https://www.b4x.com/android/forum/threads/localization-example-in-b4xpages-how.148649/post-942204
 

Attachments

  • B4J_LocalizatorExample.zip
    5.7 KB · Views: 1,526
  • ExcelWorkbook.zip
    7.1 KB · Views: 1,965
  • B4i_LocalizatorExample.zip
    6.1 KB · Views: 1,216
  • Localizator.bas
    4.4 KB · Views: 1,939
  • B4A_LocalizatorExample.zip
    11.6 KB · Views: 1,489
  • B4J_LocalizatorConverterSource.zip
    10 KB · Views: 714
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Automating the localizator

1. Add the xlsx file to the Files folder. This allows us to open the workbook directly from the IDE:

SS-2017-11-27_15.31.40.png


2. Updated command that works with Java 8+:
B4X:
#CustomBuildAction: folders ready, C:\Users\H\Downloads\B4XLocalizator.jar, ..\Files\strings.xlsx ..\Files\strings.db
 
Last edited:

leitor79

Active Member
Licensed User
Longtime User
Hi! Is there a way to indicate a default key if the current locale is not defined? Or should I use the key names as default locale?

Thank you very much for sharing this!
 

leitor79

Active Member
Licensed User
Longtime User
Hy Luca, Thank you for your answer.

I've read that, but as I have my keys already defined I'd like to find the other way.

I've looking at the class code then, and I've found that "us" being the default locale when the current locale is not defined is already done:

B4X:
Locale = FindLocale
    If sql.ExecQuerySingleResult2("SELECT count(*) FROM data WHERE lang = ?", Array As String(Locale)) = 0 Then
        Log($"Locale not found: ${Locale}. Switching to 'en'."$)
        Locale = "en"
    End If
    Log($"Device locale: ${Locale}"$)
    LoadStrings

Regards!
 

emexes

Expert
Licensed User
I would like to use it.
Could you give a reference?

Is it this one, that you would recommend?
View attachment 53254

edit:
Un-be-lie-va-ble. This is a huge timesaver.

I am a bit late to this party, but: I agree, this technique is brilliant. A project I worked on few years back, we used the GOOGLETRANSLATE function directly, and had three columns for each language:

eg, if column A is key, column B is original language, then for columns C,D,E for the first translated language:

- the first column was the translation eg =GOOGLETRANSLATE($B3,$B$1,C$1)
- the second column translated it back to the original language eg =GOOGLETRANSLATE(C3,C$1,$B$1)
- the third column was either the translation, if it was unchanged after being translated back to the original language, or blank
eg =IF(D3=$B3,C3,"")

and then for each language we'd sort by the last column and print the original and three translation columns for all the mangled items, and give it to the relevant language speaker (eg, my dad for German, my ex-wife for French, the Chinese lady at the lunch shop for Mandarin...) to check.

Then we'd enter the corrected translations into the language last column, and pull the required columns into another page and save that page for "compilation" for use by the program's localization routine.

I have a vague recollection of a routine called Translate012(PhraseKey, Quantity) that would find the required translation using PhraseKey, and then use that line or one of the next two, depending on the Quantity, so that you'd have messages like:

Translation file:
Line 35: "VehiclesAvailable", "No vehicle found"
Line 36: "", "One vehicle found"
Line 37: "", "$Q$ vehicles found"

Program output:
Translate012(VehiclesAvailable, 0) = "No vehicle found"
Translate012(VehiclesAvailable, 1) = "One vehicle found"
Translate012(VehiclesAvailable, 17) = "17 vehicles found"

and the three messages could be wildly different, eg:

Translation file:
Line 35: "VehiclesAvailable", "NO vehicle is available :-("
Line 36: "", Just one vehicle left, so be quick!!!"
Line 37: "", "Multiple vehicles are available (would you believe $Q$?)"

and some other variations of Translate routines that would substitute strings in at placemarkers, so that, for example, adjectives could go before nouns in English ("the $C$ car" = "the red car") and after nouns in French ("la voiture $C$" = "la voiture rouge"). The Chinese lady would um and ah a lot, but our Chinese customers were rapt, one went so far as to say it was easier to read and use than "real" Chinese software (at least, we think that's what he said ;-)
 

noeleon

Active Member
Licensed User
i just noticed the view texts with csbuilder value are converted to plain string. Is there a way to localize them too?
 

so27

Active Member
Licensed User
Longtime User
When I want to start the B4Xlocalizator, it is missing libraries. Where can I get these?

screenshot_01_04022021.png
 
Last edited:

Serge Bertet

Active Member
Licensed User
When using this class in a B4X Pages app,
this component :
after.jpg

turned into this :
before.jpg

the workaround is to add a line in the LocalizeLayout sub like this :
B4X:
Public Sub LocalizeLayout(PanelOrActivity As Panel)
    For Each v As View In PanelOrActivity.GetAllViewsRecursive
'        Log(GetType(v))
        If v Is Label Then 'this will catch all of Label subclasses which includes EditText, Button and others
            Dim lbl As Label = v
            If lbl.Text = "Made with " & Chr(0xF004) & " in B4X" Then Continue ' <== line added
            lbl.Text = Localize(lbl.Text)
        End If
        If v Is EditText Then
' etc...

For sure this will not solve the problem (if any) for B4J and/or B4I
 
Top