Difference between revisions of "Message Tables"

From The Foundry MODO SDK wiki
Jump to: navigation, search
(Created page with "Scripts and plug-ins need to be able to communicate with the user in a variety of languages. This makes hard-coding strings in your application unwise, a...")
 
Line 1: Line 1:
 
[[Scripting|Scripts]] and [[SDK|plug-ins]] need to be able to communicate with the user in a variety of languages. This makes hard-coding strings in your application unwise, as you then need to manually edit your code whenever you want to add a new localization.
 
[[Scripting|Scripts]] and [[SDK|plug-ins]] need to be able to communicate with the user in a variety of languages. This makes hard-coding strings in your application unwise, as you then need to manually edit your code whenever you want to add a new localization.
  
To avoid this issue, ''modo'' uses '''message tables''', and makes these available to scripts and plug-ins. These are stored in [[Config Files|config files]]; you can find many examples in the ''modo'' ''resrc'' directory (all the files starting with ''msg'' contain message tables).
+
To avoid this issue, ''modo'' uses '''message tables''', and makes these available to scripts and plug-ins. These are stored in [[:Category:Config|config files]]; you can find many examples in the ''modo'' ''resrc'' directory (all the files starting with ''msg'' contain message tables).
  
 
== Config Format ==
 
== Config Format ==

Revision as of 21:08, 27 February 2012

Scripts and plug-ins need to be able to communicate with the user in a variety of languages. This makes hard-coding strings in your application unwise, as you then need to manually edit your code whenever you want to add a new localization.

To avoid this issue, modo uses message tables, and makes these available to scripts and plug-ins. These are stored in config files; you can find many examples in the modo resrc directory (all the files starting with msg contain message tables).

Config Format

To use message tables in your script, you first need to create a message table config. Here is a simple example.

<?xml version="1.0"?>
<configuration>
    <atom type="Messages">

         <hash type="Table" key="myMessages.en_US">
             <hash type="T" key="HelloUser">Hello %1!</hash>
             <hash type="T" key="Goodbye">Bye!</hash>
         </hash>

    </atom>
</configuration>

Tables

Tables are where messages reside, and provide a mapping from internal message IDs to human-readable strings. Previously the message IDs could only be integers, but now they can be any string.

A message table's key is the name of the table, followed by a period and a language code. In the example above, the table myMessages is followed by .en_US to indicate US english. The list of possible language codes are standardized using the ISO-639 language string followed by an optional ISO-3166 country code, which allows en_UK to spell "color" as "colour", for example. If the localization requested cannot be found, the system will default to en_US when performing lookups.

The table itself contains a number of "T"-type hashes, with a string identifying the message as its key. The value contains the translated string to present to the user.

Substitutions

Messages support substitution strings, or arguments. These take the form of %1, %2, etc.. They can be in any order within the message. These are replaced at runtime with strings representing whatever information you feel appropriate.

Special Characters

Messages are standard text strings, but should be restricted to fairly standard characters. Some special XML-friendly character codes are also defined. Note that other XML character codes will not work.

XML Code Character Description
&lt; < Less Than
&gt; > Greater Than
& & Ampersand
' ' Apostrophe

Some parts of the application also support inserting new line characters in the form of the \ and n characters (that's "\n", not ASCII 10). These will automatically be replaced with a new line in the message. One example of a system that supports this is the dialog commands.

Dictionaries

Dictionaries are somewhat legacy, but are still supported. A dictionary creates a mapping between internal strings that you use directly in your script, and the old integer message IDs used for message lookup. This is no longer necessary, as 'T' table entries can use dictionary keys as message IDs as above. When used, the dictionary and table must have the same name, although the dictionary doesn't include the language code.

In this example, you can see that the dictionary includes multiple "E"-type hashes. The key of those hashes is the internal name, while the value is the numeric ID that it maps to in the table. It can also be used to map string keys, if for some reason you wanted a message with two different keys.

<?xml version="1.0"?>
<configuration>
    <atom type="Messages">

         <hash type="Dictionary" key="myMessages">
             <hash type="E" key="HelloUser">1</hash>
             <hash type="E" key="Goodbye">2</hash>
         </hash>

         <hash type="Table" key="myMessages.en_US">
             <hash type="T" key="1">Hello %1!</hash>
             <hash type="T" key="2">Bye!</hash>
         </hash>

    </atom>
</configuration>

Using Message Tables

Once you have created a message table, you can drop its config into your kit or your user directory so that modo can find it. You can use these tables in many places that you can type in user strings that would be stored in the config, such as the names of forms or controls. To do so, you use the format @table@dict@ or @table@@id@ Either mode should work for either a dictionary lookup or a message ID these days.

To use the messages from within a script, you can use the ']]ScriptQuery: messageservice|messageservice]] ScriptQuery interface. For example to obtain the value of the message with ID "Goodbye" in our test table through msgfind, you could enter the following query:

query messageservice msgfind ? @myMessages@Goodbye@

This automatically finds the message that best matches the language code, which in our case returns the string "Bye!".

To get the "HelloUser" message, we'd use:

query messageservice msgfind ? @myMessages@HelloUser@

This returns the string "Hello %1!". That’s neat, but really we want to replace that %1 with something more useful. For that we use msgsub:

query messageservice msgsub ? "Bob"

This now returns the string "Hello Bob!". The %1 in the message we last found with msgfind was replaced with the string "Bob" by msgsub. You can keep calling msgsub for each successive argument in the message, each time getting back a more complete message until there are no more substitutions left to make.

If you just want to do this all in one call, you can use msgcompose:

query messageservice msgcompose ? {@myMessages@@HelloUser@ {Bob}}

msgcompose takes a table/dict or table/id pair followed by an argument list. Each argument is wrapped in curly braces, thus allowing quotes and other curly braces to easily be embedded in the string.

You can use these functions to provide human-readable, localized strings to your users instead of making them deal with whatever spoken language you happen to have coded you script in.

More Information