When you localize
the text for an application, you create an inventory of text strings in one language, then establish a convention for substituting translated versions of these messages in another language when the application locale is different.
Caché supports the following process for localizing strings:
Developers include localizable strings within their code. Within a CSP application, the easiest approach is to use class-based development
and to use one of the $$$Text
macros. In the place of a hardcoded literal string, include an instance of the $$$Text
macro (or a related macro), providing values for the macro arguments as follows:
The domain to which this string belongs (localization is easier to manage when the strings are grouped into domains)
The language code of the default string
For example, instead of this:
set hello=$$$Text("Hello world","sampledomain","en-us")
When the code is compiled, the compiler generates entries in the message dictionary for each unique instance of the $$$Text
macro (and its related macros).
The message dictionary is a global and so can be easily viewed (for example) in the Management Portal. Caché provides class methods to help with common tasks.
When development is complete, release engineers export the message dictionary for that domain or for all domains.
The result is one or more XML message files that contain the text strings in the original language.
Release engineers send these files to translators, requesting translated versions.
Release engineers import the translated XML message files into the same namespace from which the original was exported.
Translated and original texts coexist in the message dictionary.
At runtime, the application chooses which text to display based on the browser default language.
Each of these macros takes three arguments
: the default string, the domain to which this string belongs, and the language code of the default string. When code is compiled, the compiler generates entries in the message dictionary for each unique set of values of the arguments.
returned by $$$Text
may be assigned to a variable, which you can use to represent the message in subsequent calls. For example:
Set tmsg = $$$TextJS("Error saving production")
Or, you can simply insert a $$$Text
macro anywhere you need a string:
&js<alert('#($$$TextJS("Error saving production"))#: #($ZCVT($ZE,"O","JS"))#');>
Non-empty string. text
must be a literal string. It cannot be the value of a CSP runtime expression enclosed in #()# syntax. The format used for text
The string actualText
may consist of any of the following items, separately or in combination:
If provided, the textId
is used as the message ID. If @textId@
is not specified, the system generates a new textId
by calculating the 32bit CRC (Cyclic Redundancy Check) of this text. If the textId
is specified and a message already exists with this ID, the existing message is checked to see if it has the same text as actualText
. If not, an error is reported.
||(Optional) String specifying the domain for the new message. If not specified, domain defaults to the value of the DOMAIN class parameter at compile time and %response.Domain at runtime.
code specifying the language. Caché converts this string to all-lowercase. If not specified, language
defaults as follows:
The first time a message is added to a domain by $$$Text
is used whether the language argument is specified or not. Subsequent $$$Text
macros for the same domain add messages with the same language as the first added message.
If the message text contains arguments (%1
var prompt = '#($$$TextHTML("Remove user %1 from this Role?"))#';
prompt = prompt.replace(/%1/g,member.userName);
The easiest way to display a localized string at runtime is to use one of the $$$Text
macros as described earlier in this chapter.
This topic explains other ways to retrieve message text from the message dictionary at runtime. If the message text contains arguments (%1
) you must also specify the corresponding substitution text before displaying the text on the page.
method GetText(language As %String = "",
domain As %String = "",
id As %String,
default As %String,
args...) returns %String
||(Optional) A string specifying the domain for the message. If not specified, domain defaults to %response.Domain.
||(Optional) An RFC1766 code specifying the language. Caché converts this string to all-lowercase. If not specified, language defaults to the value of %response.Language, which automatically takes its runtime value from the browser settings.
||The message ID.
||The string to use if the message identified by language, domain, and id is not found.
|arg1, arg2, and so on
||Substitution text for the message arguments. All of these are optional, so you can use %response.GetText() even if the message has no arguments.
ClassMethod FormatText(text As %String, args...) As %String
These macros enable you to substitute text for message arguments. You can use them when you already have the message text from the message dictionary:
Set language = ##class(%MessageDictionary).MatchLanguage(languages,domain,flag)
This finds the best language match to a language in the list of languages for the specified domain. The method uses HTTP 1.1 matching rules (RFC2616
). The list of languages is a comma-separated list of RFC1766
format language names. Each language in the list may
be given an associated quality value which represents an estimate of the user’s preference for the languages specified by the list of languages. The quality value defaults to q=1
The language quality factor assigned to a supported language tag is the quality value of the longest language in the list that matches the language-tag. The language that is returned is the supported language that has been assigned the highest quality factor.
flag (system) is an optional flag indicating whether system or application messages are to be matched.