Localization guidelines — Interface strings in modules
Scope: managed applications, mobile applications, and ordinary applications.
1. When configuration modules contain strings utilized in the user interface (user messages, form labels, command names, tooltips, etc.), ensure that these strings can be localized.
To do so, employ the NStr function instead of using string literals directly. Any other approach is not allowed.
Incorrect:
ShowMessageBox(, "To run the operation, install the file system extension.");
Correct:
ShowMessageBox (, NStr("en='To run the operation, install the file system extension.'"));
Make sure that the NStr function is used correctly.
Incorrect:
MessageText = "en='To run the operation, install the file system extension.'";
ShowMessageBox(, NStr(MessageText));
Correct:
MessageText = NStr("en='To run the operation, install the file system extension.'");
ShowMessageBox(, MessageText);
2. For complex strings with parts that depend on specific conditions, use logically complete and whole phrases or sentences. Employ the StrTemplate function or a similar one to replace placeholders in the string with parameters provided in the function.
This is important because parameters can be positioned differently in a sentence in different languages, which would require changing the source code to reorder string segments. It can also be challenging to correctly translate separate mismatching parts of a sentence.
Incorrect:
ShortageMessage = "There is a shortage of " + GoodsName + " in warehouse " + WarehouseName + ".";
Correct:
MessageText = NStr("en = 'There is a shortage of %1 in warehouse %2.'");
ShortageMessage = StrTemplate(MessageText, GoodsName, WarehouseName);
Avoid breaking a complete sentence into logically incomplete parts by using placeholders. Instead, provide multiple strings with all required options.
Incorrect:
NStr("en = '%1 user ""%2"" in group ""%3""?'") // Where %1 can take "Include", "Copy", or "Remove".
Correct:
NStr("en = 'Include user ""%2"" in group ""%3""?'")
NStr("en = 'Copy user ""%2"" to group ""%3""?'")
NStr("en = 'Remove user ""%2"" from group ""%3""?'")
The following practices are allowed:
- Composing texts from multiple sentences, with each sentence enclosed in NStr and translated separately.
- Using a colon at the end of a sentence. For example, NStr("en = 'Cannot create the catalog. Reason:'").
Placeholders with names, which are similar to variables, can only be used in two formats: [Parameter] and %Parameter%. In this case, "Parameter" must comply with the Naming variables standard.
Correct:
ShortageMessage = NStr("en='There is a shortage of %Goods% in warehouse %Warehouse%.'")
ShortageMessage = StrReplace(ShortageMessage, "%Goods%", GoodsName);
ShortageMessage = StrReplace(ShortageMessage, "%Warehouse%", WarehouseName);
3. In configurations that embed Standard Subsystems Library, for complex formatted strings, use the FormattedString function of the StringFunctions or StringFunctionsClient common modules instead of the FormattedString object.
Incorrect:
Text = New Array;
Text.Add(NStr("en = 'It is recommended that you back up the infobase'"));
Text.Add(" ");
Text.Add(New FormattedString(NStr("en = 'before deleting the extension.'"), StyleFonts.BoldFont);
WarningText = New FormattedString(Text);
Correct:
WarningText = StringFunctionsClient.FormattedString(NStr("en = 'It is recommended that you back up the infobase<b>before deleting the extension</b>.'");
4. In the NStr function, each string is enclosed in single quotes. This convention is necessary because double quotes are frequently used in string literals and is also required by the platform's mechanism for editing strings in different languages.
Incorrect:
ShowMessageBox(, NStr("en=Variable of the ""String"" type"));
ShowMessageBox(, NStr("en=""Variable of the ""String"" type"""));
Correct:
ShowMessageBox(, NStr("en='Variable of the ""String"" type'"));
5. Metadata object names and internal identifiers used in the code must not appear in the user interface, user messages, or reference information. Instead, use synonyms (presentations) of metadata objects and presentations of internal identifiers.
It is recommended that you get synonyms directly from the metadata using the Presentation function. This will ensure their consistent translation throughout the application.
Incorrect:
ErrorMessage = NStr("en='Negative balance detected in the CompanyGoods register.'");
Correct:
ErrorMessage = StrTemplate(NStr("en='Negative balance detected in the %1 register.'"), Metadata.AccumulationRegisters.CompanyGoods.Presentation());
Or a shortened version:
ErrorMessage = StrTemplate(NStr("en='Negative balance detected in the %1 register.'"), Metadata.AccumulationRegisters.CompanyGoods);
5.1. This rule does not apply to messages and interfaces intended for developers and integrators, where output of metadata object names and internal identifiers is reasonable. When outputting procedure and function names, use their full names along with the name of a common module or manager module.
Incorrect:
ErrorMessage = NStr("en = 'Error in the HasRole function of the AccessManagement module.'");
Correct:
FunctionName = "AccessManagement.HasRole";
ErrorMessage = StrTemplate(NStr("en = 'Error in the %1 function.'"), FunctionName);
Example for a manager module:
FunctionName = "Documents.ExpenseReport.AdaptedRegisterRecordsRequestText";
ErrorMessage = StrTemplate(NStr("en = 'To correct document register records, call the %1 function.'"), FunctionName);
To display metadata object names, get them directly from the metadata using the FullName function. This will eliminate potential translation errors.
Incorrect:
ErrorMessage = NStr("en ='Incorrect deployment of the subsystem in the CompanyGoods register.'");
Correct:
ErrorMessage = StrTemplate(NStr("en ='Incorrect deployment of the subsystem in the %1 register.'"), Metadata.AccumulationRegisters.CompanyGoods.FullName());
6. When using the NumberInWords, PeriodPresentation, and StringWithNumber functions, avoid specifying the "L=" parameter in the format string.
Incorrect:
AmountInWords = NumberInWords(2341.56, "L = en_EN; DE = True", NStr("en='dollar,dollars,cent,cents,2'"));
Correct:
AmountInWords = NumberInWords(2341.56, "DE = True", NStr("en='dollar,dollars,cent,cents,2'"));
7. To compose a long message, such as a log of user actions, consider concatenating strings instead of substituting them in a template string. Non-language characters (often line breaks) at the beginning and end of lines must be placed in separate string literals.
Incorrect:
MessageText = NStr("en = 'Cannot save the document file. Reason:
| '") |
+ ErrorInfo;
Correct:
MessageText = NStr("en = 'Cannot save the document file. Reason:'")
+ Chars.LF + ErrorInfo;
This approach reduces the risk of missing trailing spaces or making translation mistakes, as translators typically see only a summary table of strings without context.
8. When calling the ShowQueryBox method and specifying dialog box buttons in the Buttons parameter:
- Use the DialogReturnCode system enumeration whenever possible.
- If an enumeration does not contain the required button, define its presentation using the NStr function along with a button value.
Incorrect:
Buttons = New ValueList;
Buttons.Add("Disable");
Buttons.Add("No");
ShowQueryBox(..., Buttons);
Correct:
Buttons = New ValueList;
Buttons.Add("Disable", NStr("en='Disable'"));
Buttons.Add(DialogReturnCode.No);
ShowQueryBox(..., Buttons);
See also: