Summary:
See also: Programs, FGLPROFILE
Localized Strings provide a means of writing applications in which the text of strings can be customized on site. This feature can be used to implement internationalization in your application, or to use site-specific text (for example, when business terms change based on territory).
This string localization feature does not define language identification. It is a simple way to define external resource files which the runtime system can search, in order to assign text to strings in the BDL application. The text is replaced at runtime in the p-code modules (42m), in the compiled form specification files (42f), and in any XML resource files loaded in the Abstract User Interface tree (4ad, 4st, 4tb, and so on).
By using a simple notation, you can identify the Localized Strings in the source code:
01
MAIN02
DISPLAY %"my text"03
END MAIN
The fglcomp and fglform compilers have been extended to support a new option to extract the Localized Strings. This way, the Localized Strings can be extracted into Source String Files.
From the original Source String File, you can create other files containing different text (for example, one file for each language you want to support).
You must use the fglmkstr tool to compile the source string files into a binary version. By convention, compiled string resource files must have the 42s extension.
By default, the compiled string files are loaded at runtime, according to the name of the program (42r). It is also possible to define global string files in the FGLPROFILE configuration file. See also: Using String Files at Runtime.
In 42m p-code modules, the Localized Strings are coded in our specific binary format. But, for XML files such as compiled form files (42f), the localized strings must be identified with a specific node, following the XML standards.
To support localized strings in XML files, any file loaded into the Abstract
User Interface tree is parsed to search for <LStr>
nodes.
The <LStr>
nodes define the same attributes as in the
parent node with
localized string identifiers, for example:
01
<Label text="Hello!" >02
<LStr text="label01" />03
</Label>
The runtime system automatically replaces corresponding attributes in the
parent node (text="Hello!"), with the localized text found in the
compiled string files, according to the string identifier (label01). After
interpretation, the <LStr>
nodes are removed from the XML
data.
%"sid"
LSTR(eid)
A Localized String can be used in the source code of program modules or form specification files to identify a text string that must be converted at runtime.
Static Localized Strings
A Localized String begins with a percent sign (%
), followed by the
name of the
string which will be used to
identify the text to be loaded. Since the name is a string, you can use any kind
of characters in the name, but it is recommended that you use a proper naming
convention. For example, you can specify a path by using several identifiers
separated by a dot, without any special characters such as space or tab:
01
MAIN02
DISPLAY %"common.helloworld"03
END MAIN
The string after the percent sign defines both the localized string identifier and the default text to be used for extraction, or the default text when no string resource files are provided at runtime.
You can use this notation in form specification files as well, at any place where a string literal can be used.
01
LAYOUT02
VBOX03
GROUP g1 (TEXT=%"group01")04
...
01
LAYOUT02
GRID03
{04
[lab01 |f001 ]05
{06
END07
END08
ATTRIBUTES09
LABEL lab01 : TEXT=%"myform.label01";10
EDIT f001 = FORMONLY.field01;11
END
Dynamic Localized Strings
The language provides a special operator to load a Localized String dynamically, using an expression as string identifier. The name of this operator is LSTR(), and the syntax is described above.
The following code example builds a Localized String identifier with an integer and loads the corresponding string with the LSTR() operator:
01
MAIN02
DEFINE n INTEGER03
LET n = 23404
DISPLAY LSTR("str"||n) -- loads string 'str234'05
END MAIN
See also: The SFMT() operator
By convention, the source files of Localized Strings have the .str extension.
You define a list of string identifiers, and the corresponding text, by using the following syntax:
"identifier" =
"string"
The fglmkstr compiler accepts the backslash "\" as the escape character, to define non-printable characters:
\l \n \r
\t \\
01
"id001" = "Some text"02
"this.is.a.path.for.a.very.long.string.identifier" = "Customer List"03
"special.characters.backslash" = "\\"04
"special.characters.newline" = "\n"
In order to extract Localized String from Source String
Files, use the fglcomp and fglform
compilers with the -m
option:
$ fglcomp -m mymodule.4gl
The compilers dumps all localized string to stdout. This output can be redirected to a file to generate the default Source String File with all the localized strings used in the 4gl file.
The Source String Files (.str) must be compiled to binary files (.42s) in order to be used at runtime.
To compile a Source String File, use the fglmkstr compiler:
$ fglmkstr filename.str
This tool generates a .42s file with the filename prefix.
The runtime system searches for
string files with the "42s
"
extension in the current directory and in the path list defined
in the DBPATH environment variable.
By default, the runtime system searches for a Compiled
String File having the same name prefix as the current "42r
"
program. For example, if you have a program named "customer.42r
", the runtime system will search
for the compiled string file "customer.42s
" when
the program is started.
You can specify a list of Compiled String Files with entries in the
FGLPROFILE
configuration file. The file name must be specified without a file extension. The runtime system searches
for a file with the "42s
"
extension in the current directory and in the path list defined
in the DBPATH environment variable.
List of resource files
To define the list of resource files to be used, specify the total number of files with:
fglrun.localization.file.count = integer
And for each file, define the filename (without the 42s extension), including an index number, with:
fglrun.localization.file.index.name = "filename"
Start index at 1.
Warning switches
If the text of a string is not found at runtime, the DVM can show a warning, for development purposes.
fglrun.localization.warnKeyNotFound = boolean
By default, this warning switch is disabled.
Compiled string resource files must be distributed with the program files in a directory specified in the DBPATH environment variable.
The Source String File "common.str" (a compiled version must be created):
01
"common.accept" = "OK"02
"common.cancel" = "Cancel"03
"common.quit" = "Quit"
The Source String File "actions.str" (a compiled version must be created):
01
"action.append" = "Append"02
"action.modify" = "Modify"03
"action.delete" = "Delete"
The Source String File "customer.str" (a compiled version must be created):
01
"customer.mainwindow.title" = "Customers"02
"customer.listwindow.title" = "Customer List"03
"customer.l_custnum" = "Number:"04
"customer.l_custname" = "Name:"05
"customer.c_custname" = "The customer name"06
"customer.g_data" = "Customer data"07
"customer.g_actions" = "Actions"08
"customer.qdelete" = "Are you sure you want to delete this customer?"
The FGLPROFILE configuration file parameters:
01
fglrun.localization.file.count = 202
fglrun.localization.file.1.name = "common"03
fglrun.localization.file.2.name = "actions"
Remark: The 'customer' string file does not have to to listed in FGLPROFILE since it is loaded as it has the same name as the program.
The form specification file "f1.per":
01
LAYOUT (TEXT=%"customer.mainwindow.title")02
GRID03
{04
<g g1 >05
[lab1 ] [f01 ]06
[lab2 ] [f02 ]07
08
<g g2 >09
[b1 ] [b2 ]10
11
}12
END13
END14
ATTRIBUTES15
LABEL lab1 : TEXT=%"customer.l_custnum";16
EDIT f01 = FORMONLY.custnum;17
LABEL lab2 : TEXT=%"customer.l_custname";18
EDIT f02 = FORMONLY.custname, COMMENT=%"customer.c_custname";19
BUTTON b1 : edit, TEXT=%"action.modify";20
BUTTON b2 : quit, TEXT=%"common.quit";21
GROUP g1 : TEXT=%"customer.g_data";22
GROUP g2 : TEXT=%"customer.g_actions";23
END
The program "customer.4gl" using the strings file:
01
MAIN02
DEFINE rec RECORD03
custnum INTEGER,04
custname CHAR(20)05
END RECORD06
OPEN WINDOW w1 WITH FORM "f1"07
MENU08
ON ACTION edit09
INPUT BY NAME rec.*10
ON ACTION quit11
EXIT MENU12
END MENU13
END MAIN