Line 146: |
Line 146: |
| foreach (GameLocation location in this.Helper.Multiplayer.GetActiveLocations()) | | foreach (GameLocation location in this.Helper.Multiplayer.GetActiveLocations()) |
| </source> | | </source> |
− |
| |
− | ===Translation===
| |
− | The translation API lets you translate your mod into the player's current language, accounting for locale fallback automatically (e.g. if a translation isn't available in <tt>pt-BR.json</tt>, SMAPI will check <tt>pt.json</tt> and <tt>default.json</tt>). Translations can be a simple string, or they can include tokens to inject values into the translation.
| |
− |
| |
− | <dl>
| |
− | <dt>File structure</dt>
| |
− | <dd>SMAPI reads translations from JSON files in a structure like this:
| |
− | <pre>
| |
− | YourMod/
| |
− | i18n/
| |
− | default.json
| |
− | es.json
| |
− | pt.json
| |
− | manifest.json
| |
− | YourMod.dll
| |
− | </pre>
| |
− |
| |
− | The <tt>default.json</tt> file should contain a flat key→value lookup with your default text. Each key is case-insensitive, and can contain alphanumeric, underscore, hyphen, and dot characters. Feel free to add JavaScript comments to organise or document your translations. For example:
| |
− | <source lang="javascript">
| |
− | {
| |
− | // example translations
| |
− | "item-type.label": "Item type",
| |
− | "item-type.fruit-tree": "{{fruitName}} tree",
| |
− | }
| |
− | </source>
| |
− |
| |
− | You can then add translation files for each language you want to support, by copying the <tt>default.json</tt> file and translating its values. Each translation file should have one of these file names:
| |
− |
| |
− | {| class="wikitable"
| |
− | |-
| |
− | ! Language
| |
− | ! File name
| |
− | |-
| |
− | | Chinese
| |
− | | <tt>zh.json</tt>
| |
− | |-
| |
− | | German
| |
− | | <tt>de.json</tt>
| |
− | |-
| |
− | | Japanese
| |
− | | <tt>ja.json</tt>
| |
− | |-
| |
− | | Portuguese
| |
− | | <tt>pt.json</tt>
| |
− | |-
| |
− | | Russian
| |
− | | <tt>ru.json</tt>
| |
− | |-
| |
− | | Spanish
| |
− | | <tt>es.json</tt>
| |
− | |}</dd>
| |
− |
| |
− | <dt>Reading translations</dt>
| |
− | <dd>Once your i18n files are set up, you can read translations for the current locale:
| |
− | <source lang="c#">
| |
− | // read a simple translation
| |
− | string label = helper.Translation.Get("item-type.label");
| |
− |
| |
− | // read a translation which uses tokens (accepts an anonymous object, dictionary, or model)
| |
− | string text = helper.Translation.Get("item-type.fruit-tree", new { fruitName = "apple" });
| |
− | </source>
| |
− |
| |
− | The <tt>helper.Translate(…)</tt> method returns a fluent interface — you can keep calling methods on its return value to customise the translation. (See IntelliSense for a description of the available methods.) To get the text, simply assign it to a string:
| |
− | <source lang="c#">
| |
− | // use fluent chain
| |
− | string text = helper.Translate(key).Tokens(tokens).Tokens(moreTokens).Assert();
| |
− | </source>
| |
− |
| |
− | If your code has a lot of translation calls, you can make it less verbose by aliasing the translation helper:
| |
− | <source lang="c#">
| |
− | var i18n = helper.Translation;
| |
− |
| |
− | i18n.Get("item-type.fruit-tree", new { fruitName = i18n.Get("apple") });
| |
− | </source></dd>
| |
− |
| |
− | <dt>Tips for translators</dt>
| |
− | <dd>
| |
− | * Save i18n files with UTF-8 encoding to avoid broken symbols in-game.
| |
− | * Type <code>reload_i18n</code> into the SMAPI console and hit enter to reload translations without exiting the game. (If a mod internally cached a translation, it may not be updated.)
| |
− | </dd>
| |
− | </dl>
| |