Using message templates
Many applications use language-dependent text throughout to provide localized menu selections, warning and error message descriptions, and help text. Often, the display of language-dependent text requires the insertion of locale-dependent string arguments into a message template. The processing used to construct a composite message from various components can introduce unwanted language dependencies and can act as a barrier to localization. The following example shows a locale-specific way to construct a composite message:
displayWarningFor: userName operation: anOperation
"Display a warning message on the Transcript warning the user called
userName that the operation called anOperation cannot be performed."
show: 'Sorry, ', userName;
show: ' I cannot perform', anOperation;
show: '!'.
This technique is commonly used in the construction of messages displayed to users. This technique is a barrier to localization because it embeds language-specific semantics in the processing used to construct the message. Some languages might require that the contents of the userName field appear after the anOperation field, or that a punctuation mark other than an exclamation mark (!) be used to terminate the message. The approach illustrated in the preceding example cannot support these requirements and is not suitable for use in an internationalized application.
VA Smalltalk provides a mechanism for replacing tokens in a message template with variable arguments. A template string is a String or DBString containing constant text and token identifiers that are replaced with arguments specified by the developer. Token identifiers consist of a percent character (%) and a numeric field identifier in the range one to nine (1-9).
A template string is expanded based on arguments provided by the developer using the bindWith:, bindWith:with:, bindWith:with:with:, bindWith:with:with:with:, or bindWithArguments: methods. The numeric portion of the token identifier indicates which argument should replace the token when the template is expanded to create a composite message (for example, %1 corresponds to the first argument, %2 corresponds to the second argument, etc.).
There are also 2 special escape sequences. The double percent escape sequence ('%%') is replaced by a single percent chatacter in the composite message. The percent zero escape sequence ('%0') is replace by a platform line delimiter in the composite message.
A template string permits arguments to be printed selectively, and in arbitrary order as illustrated in the following table. Although arguments are provided in a fixed order, there is no restriction placed on their order of appearance in the template string. Arguments that are not referenced in the template string are ignored. Template string references to missing arguments are replaced by the escape sequence itself.
Table 50. Sample message templates and results
Sample template and arguments
Resultant message
'%1 %2 %3' bindWith: 'one' with: 'two' with: 'three'
'one two three'
'%3 %2 %1' bindWith: 'one' with: `two' with: 'three'
'three two one'
'%1 %2 %1' bindWith: 'one' with: 'two' with: 'three'
'one two one'
'An %1 of embedded text' bindWith: 'example'
'An example of embedded text'
'This is a percent sign %%.' bindWith: ''
'This is a percent sign %'
'Unused are %1.' bindWith: 'ignored' with: 'unused'
'Unused are ignored'
'Missing arguments are %2.' bindWith: 'errors'
'Missing arguments are %2.'
The following example shows the use of message templates to assist in internationalizing an application. It illustrates how the use of a message template avoids the language-specific dependencies exhibited by the previous example. Notice that languages that require the contents of the userName field to appear after the anOperation field, or different punctuation, can be supported simply by changing the template string. Normally, the template string would be externalized, thereby permitting the application to be localized without modification of source code.
displayWarningFor: userName operation: anOperation
"Display a warning message on the Transcript warning the user called
userName (a String) that the operation called anOperation
(a String) cannot be performed."
| template |
template := 'Sorry, %1, I cannot perform %2!'.
show: (template bindWith: userName with: anOperation).
This example is not fully internationalized because it contains a hard-coded reference to the template 'Sorry, %1 I cannot perform %2!'. Tools and techniques for removing hard coded references to strings are discussed in Removing hard-coded strings.
Last modified date: 10/08/2020