Difference between revisions of "Translations (SourceMod Scripting)"

From AlliedModders Wiki
Jump to: navigation, search
m
m (Update highlighting)
 
(16 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 +
__FORCETOC__
 
[[SourceMod]], like its AMX Mod X predecessor, contains a built-in Multi-Lingual Translation layer ("ML").  The ML system is one of the secondary SourceMod systems designed to make the platform as flexible as possible.  It fully supports UTF-8.
 
[[SourceMod]], like its AMX Mod X predecessor, contains a built-in Multi-Lingual Translation layer ("ML").  The ML system is one of the secondary SourceMod systems designed to make the platform as flexible as possible.  It fully supports UTF-8.
  
Line 19: Line 20:
 
<pre>"Phrases"
 
<pre>"Phrases"
 
{
 
{
"Welcome"
+
  "Welcome"
{
+
  {
"en" "Welcome to SourceMod"
+
    "en"   "Welcome to SourceMod"
"es" "Bienvenidos a SourceMod"
+
    "es"   "Bienvenidos a SourceMod"
}
+
  }
 
}</pre>
 
}</pre>
  
Line 29: Line 30:
 
<pre>"Phrases"
 
<pre>"Phrases"
 
{
 
{
"Pants"
+
  "Pants"
{
+
  {
"en" "pants"
+
    "en"   "pants"
"es" "pantalones"
+
    "es"   "pantalones"
}
+
  }
//INVALID EXAMPLE: "Bail's pants are on fire"
+
  //INVALID EXAMPLE: "Bail's pants are on fire"
"OnFire_plural"
+
  "OnFire_plural"
{
+
  {
"en" "%s's %s are on fire!"
+
    "en"   "%s's %s are on fire!"
"es" "¡Los %s de %s están en llamas!"
+
    "es"   "¡Los %s de %s están en llamas!"
}
+
  }
 
}</pre>
 
}</pre>
  
Line 45: Line 46:
 
<pre>"Phrases"
 
<pre>"Phrases"
 
{
 
{
//Example: "Bail's pants are on fire"
+
  //Example: "Bail's pants are on fire"
"OnFire_plural"
+
  "OnFire_plural"
{
+
  {
"#format" "{1:s},{2:s}"
+
    "#format" "{1:s},{2:s}"
"en" "{1}'s {2} are on fire!"
+
    "en"   "{1}'s {2} are on fire!"
"es" "¡Los {2} de {1} están en llamas"
+
    "es"   "¡Los {2} de {1} están en llamas"
}
+
  }
//Example: "Hello, Bail!"
+
  //Example: "Hello, Bail!"
"Hello"
+
  "Hello"
{
+
  {
"#format" "{1:s}"
+
    "#format" "{1:s}"
"en" "Hello, {1}"
+
    "en"   "Hello, {1}"
"es" "Hola, {1}"
+
    "es"   "Hola, {1}"
}
+
  }
 
}</pre>
 
}</pre>
  
Line 67: Line 68:
 
*'''s''': String display
 
*'''s''': String display
 
*'''c''': Character display (UTF-8 compatible)
 
*'''c''': Character display (UTF-8 compatible)
 +
*'''t''': include and translate another Phrases
  
Note that currently, the special "%T" format type is not allowed inside a language translation string.
+
Note that currently, the special "%T" format type is not allowed inside a language translation string. but you still can use %t inside the format string
  
 
=Usage in a Plugin=
 
=Usage in a Plugin=
Plugins have two main methods of translation strings from the ML system: Inline translation, which is built into all string formatting functions, and manual translation, which is used to manually format a phrase.
+
Plugins must call <tt>LoadTranslations</tt> on each translation file they wish to use.  Failure to do so will cause any translations to fail, even if another plugin loads the same file.  This is to help prevent phrase-clashes between plugins.
  
Plugins must call <tt>LoadDictionary</tt> on each translation file they wish to use.  Failure to do so will cause any translations to fail, even if another plugin loads the same file.  This is to help prevent phrase-clashes between plugins.
+
'''Note''': Language files are reloaded every mapchange or with the command '''sm_reload_translations'''. Even if the plugin gets reloaded, the translation file stays cached until next map.
 +
 
 +
'''Note''': <tt>FormatNativeString</tt> uses phrases from the calling plugin, not your plugin.
  
==Inline Translations==
 
 
Inline translation works in any [[Format Class Functions (SourceMod Scripting)|format-class]] of functions.  A new format specifier, '%T', is introduced, which instructs the format routine to insert a translated phrase.  Unlike all other format specifiers, this requires a minimum of two parameters:
 
Inline translation works in any [[Format Class Functions (SourceMod Scripting)|format-class]] of functions.  A new format specifier, '%T', is introduced, which instructs the format routine to insert a translated phrase.  Unlike all other format specifiers, this requires a minimum of two parameters:
 
*'''1st Parameter''': A string containing the phrase to be translated.
 
*'''1st Parameter''': A string containing the phrase to be translated.
Line 84: Line 87:
  
 
Examples of this are:
 
Examples of this are:
<pawn>new String:name[32], String:buffer[128];
+
<sourcepawn>char name[32], buffer[128];
 
GetClientName(client, name, sizeof(name));
 
GetClientName(client, name, sizeof(name));
PrintToPlayer(client, "[SourceMod] %T", "Hello", client, name);
+
PrintToChat(client, "[SourceMod] %T", "Hello", client, name);
Format(buffer, sizeof(buffer), "[SourceMod] %T", "Hello", LANG_SERVER, name);</pawn>
+
Format(buffer, sizeof(buffer), "[SourceMod] %T", "Hello", LANG_SERVER, name);</sourcepawn>
  
 
A breakdown of the format parameters:
 
A breakdown of the format parameters:
Line 95: Line 98:
  
 
Lastly, there is a second form of inline translation, using '%t'.  This is only allowed in functions which act directly on one or more clients.  It eliminates the second parameter, and uses the original client specified.  Example:
 
Lastly, there is a second form of inline translation, using '%t'.  This is only allowed in functions which act directly on one or more clients.  It eliminates the second parameter, and uses the original client specified.  Example:
<pawn>PrintToPlayer(client, "[SourceMod] %t", "Hello", name);</pawn>
+
<sourcepawn>PrintToChat(client, "[SourceMod] %t", "Hello", name);</sourcepawn>
 +
 
 +
As you can see from this example, we did not have to specify the client index more than once.  Thus, it is usually more convenient to use the limited '%t' version in functions such as <tt>PrintToChat</tt>.  However, in functions which are not "player directed," such as <tt>Format</tt> or <tt>PrintToServer</tt>, only '%T' can be used.
 +
 
 +
=Distributing Language Files=
 +
As of SourceMod 1.1, there is a new preferred method of shipping translations.  By default, the main translation file should only contain English phrases.  Additional translations are made in separate files, under a folder named after the ISO language code in <tt>languages.cfg</tt>.
 +
 
 +
For example, <tt>translations/stuff.phrases.txt</tt> might contain this:
 +
<pre>"Phrases"
 +
{
 +
  //Example: "Hello, Bail!"
 +
  "Hello"
 +
  {
 +
    "#format" "{1:s}"
 +
    "en"    "Hello, {1}"
 +
  }
 +
}</pre>
 +
 
 +
A user who translates this to Spanish would create <tt>translations/es/stuff.phrases.txt</tt>:
 +
<pre>"Phrases"
 +
{
 +
  //Example: "Hello, Bail!"
 +
  "Hello"
 +
  {
 +
    "es"    "Hola, {1}"
 +
  }
 +
}</pre>
 +
 
 +
This system makes maintaining and checking the validity of files much easier.
  
As you can see from this example, we did not have to specify the client index more than once.  Thus, it is usually more convenient to use the limited '%t' version in functions such as <tt>PrintToPlayer</tt>.  However, in functions which are not "player directed," such as <tt>Format</tt> or <tt>PrintToServer</tt>, only '%T' can be used.
 
  
==Manual Translations==
+
[[Category:SourceMod Scripting]]
If you do not wish to use inlined translation, you can also use natives that manually translate a string to a given buffer.  Documentation for these natives can be found in <tt>translation.inc</tt>.
 
*<tt>GetLanguageID()</tt>: Given a two letter language code, returns its internal ID.  English ("en") is always ID 0.  An empty string returns the server's language ID.
 
*<tt>GetLanguageCount()</tt>: Returns the number of languages in the translation cache.
 
*<tt>GetLanguageInfo()</tt>: Returns a language's name and code given its ID.
 
*<tt>Translate()</tt>: Translates a phrase given a language code, a translation file Handle (returned by <tt>LoadDictionary</tt>), and a phrase string.
 
*<tt>GetPlayerLanguage()</tt>: Returns the language ID a player is using.
 
  
[[Category:SourceMod Development]]
+
{{LanguageSwitch}}

Latest revision as of 17:43, 29 March 2020

SourceMod, like its AMX Mod X predecessor, contains a built-in Multi-Lingual Translation layer ("ML"). The ML system is one of the secondary SourceMod systems designed to make the platform as flexible as possible. It fully supports UTF-8.

Introduction

The SourceMod ML System is based off the following terms:

  • Languages: Preset languages defined in configs\languages.cfg. If a language is not in this file, it cannot be translated until it is added and the in-memory translation cache rebuilt.
  • Phrases/Translation Keys: Short, generic key phrases used to identify a set of translations. These reside in configuration files in the translations folder. These are called translation files.
  • Translations: A given text translation of a phrase for a given language. These reside in a translation file.

Note: Languages and Phrases are both case sensitive.

File Format

The ML Translation File format is in standard Valve configuration form. It is comprised of one master section, "Phrases," which contains any number of named sub-sections. Each sub-section defines one named Phrase, which cannot itself have sub-sections. It allows the following properties:

  • Key: "#format"
    • Value: Comma-delimited, ordered pairs of indexes and format strings.
  • Key: Two-letter language code.
    • Value: Language translation string.

Example:

"Phrases"
{
  "Welcome"
  {
    "en"    "Welcome to SourceMod"
    "es"    "Bienvenidos a SourceMod"
  }
}

In the above example, two translations are defined for the "Welcome" phrase - one for English, and one for Spanish. However, consider a phrase which needs certain words inserted, as in this contrived example:

"Phrases"
{
  "Pants"
  {
    "en"    "pants"
    "es"    "pantalones"
  }
  //INVALID EXAMPLE: "Bail's pants are on fire"
  "OnFire_plural"
  {
    "en"    "%s's %s are on fire!"
    "es"    "¡Los %s de %s están en llamas!"
  }
}

In the above example, the word orders have changed. English inserts the subject first, and the direct object second. Spanish associates ownership differently -- literally, the pants of Bail are on fire. This poses a problem for scripters, who always pass format parameters in one order. To solve this, the #format property was introduced. This pre-defines the order of format parameters. Example:

"Phrases"
{
  //Example: "Bail's pants are on fire"
  "OnFire_plural"
  {
    "#format" "{1:s},{2:s}"
    "en"    "{1}'s {2} are on fire!"
    "es"    "¡Los {2} de {1} están en llamas"
  }
  //Example: "Hello, Bail!"
  "Hello"
  {
    "#format" "{1:s}"
    "en"    "Hello, {1}"
    "es"    "Hola, {1}"
  }
}

The format string is comprised of comma delimited sections, each section enclosed in brackets. Each section has an index and a format specifier, which are separated with a colon. Format specifiers follow the general rules of formatting, however, only the following types are currently allowed:

  • d/i: Digits/Integer display
  • x: Hexadecimal display
  • f: Floating point display
  • s: String display
  • c: Character display (UTF-8 compatible)
  • t: include and translate another Phrases

Note that currently, the special "%T" format type is not allowed inside a language translation string. but you still can use %t inside the format string

Usage in a Plugin

Plugins must call LoadTranslations on each translation file they wish to use. Failure to do so will cause any translations to fail, even if another plugin loads the same file. This is to help prevent phrase-clashes between plugins.

Note: Language files are reloaded every mapchange or with the command sm_reload_translations. Even if the plugin gets reloaded, the translation file stays cached until next map.

Note: FormatNativeString uses phrases from the calling plugin, not your plugin.

Inline translation works in any format-class of functions. A new format specifier, '%T', is introduced, which instructs the format routine to insert a translated phrase. Unlike all other format specifiers, this requires a minimum of two parameters:

  • 1st Parameter: A string containing the phrase to be translated.
  • 2nd Parameter: One of the following:
    • The LANG_SERVER constant, which specifies a translation to the default language.
    • A player ID constant, which specifies a translation to the player's set language.
  • 3rd Parameter and higher: Inputs into the phrase's format specifiers, if necessary.

Examples of this are:

char name[32], buffer[128];
GetClientName(client, name, sizeof(name));
PrintToChat(client, "[SourceMod] %T", "Hello", client, name);
Format(buffer, sizeof(buffer), "[SourceMod] %T", "Hello", LANG_SERVER, name);

A breakdown of the format parameters:

  • "Hello": The phrase to translate.
  • client/LANG_SERVER: Who to translate the phrase to.
  • name: The "Hello" phrase requires one string, so this will appear in the translated phrase.

Lastly, there is a second form of inline translation, using '%t'. This is only allowed in functions which act directly on one or more clients. It eliminates the second parameter, and uses the original client specified. Example:

PrintToChat(client, "[SourceMod] %t", "Hello", name);

As you can see from this example, we did not have to specify the client index more than once. Thus, it is usually more convenient to use the limited '%t' version in functions such as PrintToChat. However, in functions which are not "player directed," such as Format or PrintToServer, only '%T' can be used.

Distributing Language Files

As of SourceMod 1.1, there is a new preferred method of shipping translations. By default, the main translation file should only contain English phrases. Additional translations are made in separate files, under a folder named after the ISO language code in languages.cfg.

For example, translations/stuff.phrases.txt might contain this:

"Phrases"
{
  //Example: "Hello, Bail!"
  "Hello"
  {
    "#format" "{1:s}"
    "en"    "Hello, {1}"
  }
}

A user who translates this to Spanish would create translations/es/stuff.phrases.txt:

"Phrases"
{
  //Example: "Hello, Bail!"
  "Hello"
  {
    "es"    "Hola, {1}"
  }
}

This system makes maintaining and checking the validity of files much easier.

Warning: This template (and by extension, language format) should not be used, any pages using it should be switched to Template:Languages

View this page in:  English  Russian  简体中文(Simplified Chinese)