diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-08-15 01:25:56 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-08-25 18:17:09 -0400 |
commit | 6cf7c49f34eac8edd18012d41d1f49a149fb1f5a (patch) | |
tree | 1e2b911c730acd643baae7493d5e7f938c014e87 | |
parent | a4c6c6168405bb0441a40e4f6f4e86dfa46a76b2 (diff) | |
download | SMAPI-6cf7c49f34eac8edd18012d41d1f49a149fb1f5a.tar.gz SMAPI-6cf7c49f34eac8edd18012d41d1f49a149fb1f5a.tar.bz2 SMAPI-6cf7c49f34eac8edd18012d41d1f49a149fb1f5a.zip |
add GetInAllLocales to translation API
-rw-r--r-- | docs/release-notes.md | 1 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModHelpers/TranslationHelper.cs | 6 | ||||
-rw-r--r-- | src/SMAPI/Framework/Translator.cs | 65 | ||||
-rw-r--r-- | src/SMAPI/ITranslationHelper.cs | 7 |
4 files changed, 67 insertions, 12 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index 9e42a847..409c4bd5 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,6 +3,7 @@ # Release notes ## Upcoming release * For mod authors: + * Added `GetInAllLocales` method in translation API, to get a translation in every available locale. * Fixed rare `NullReferenceException` in SMAPI's error-handling. * Internal changes to prepare for upcoming releases. diff --git a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs index a88ca9c9..869664fe 100644 --- a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs @@ -55,6 +55,12 @@ namespace StardewModdingAPI.Framework.ModHelpers return this.Translator.Get(key, tokens); } + /// <inheritdoc /> + public IDictionary<string, Translation> GetInAllLocales(string key, bool withFallback = false) + { + return this.Translator.GetInAllLocales(key, withFallback); + } + /// <summary>Set the translations to use.</summary> /// <param name="translations">The translations to use.</param> internal TranslationHelper SetTranslations(IDictionary<string, IDictionary<string, string>> translations) diff --git a/src/SMAPI/Framework/Translator.cs b/src/SMAPI/Framework/Translator.cs index 11ec983b..4492b17f 100644 --- a/src/SMAPI/Framework/Translator.cs +++ b/src/SMAPI/Framework/Translator.cs @@ -46,18 +46,10 @@ namespace StardewModdingAPI.Framework this.LocaleEnum = localeEnum; this.ForLocale = new Dictionary<string, Translation>(StringComparer.OrdinalIgnoreCase); - foreach (string next in this.GetRelevantLocales(this.Locale)) + foreach (string key in this.GetAllKeysRaw()) { - // skip if locale not defined - if (!this.All.TryGetValue(next, out IDictionary<string, string> translations)) - continue; - - // add missing translations - foreach (var pair in translations) - { - if (!this.ForLocale.ContainsKey(pair.Key)) - this.ForLocale.Add(pair.Key, new Translation(this.Locale, pair.Key, pair.Value)); - } + string text = this.GetRaw(key, locale, withFallback: true); + this.ForLocale.Add(key, new Translation(this.Locale, key, text)); } } @@ -83,6 +75,25 @@ namespace StardewModdingAPI.Framework return this.Get(key).Tokens(tokens); } + /// <summary>Get a translation in every locale for which it's defined.</summary> + /// <param name="key">The translation key.</param> + /// <param name="withFallback">Whether to add duplicate translations for locale fallback. For example, if a translation is defined in <c>default.json</c> but not <c>fr.json</c>, setting this to true will add a <c>fr</c> entry which duplicates the default text.</param> + public IDictionary<string, Translation> GetInAllLocales(string key, bool withFallback) + { + IDictionary<string, Translation> translations = new Dictionary<string, Translation>(); + + foreach (var localeSet in this.All) + { + string locale = localeSet.Key; + string text = this.GetRaw(key, locale, withFallback); + + if (text != null) + translations[locale] = new Translation(locale, key, text); + } + + return translations; + } + /// <summary>Set the translations to use.</summary> /// <param name="translations">The translations to use.</param> internal Translator SetTranslations(IDictionary<string, IDictionary<string, string>> translations) @@ -102,6 +113,38 @@ namespace StardewModdingAPI.Framework /********* ** Private methods *********/ + /// <summary>Get all translation keys in the underlying translation data, ignoring the <see cref="ForLocale"/> cache.</summary> + private IEnumerable<string> GetAllKeysRaw() + { + return new HashSet<string>( + this.All.SelectMany(p => p.Value.Keys), + StringComparer.OrdinalIgnoreCase + ); + } + + /// <summary>Get a translation from the underlying translation data, ignoring the <see cref="ForLocale"/> cache.</summary> + /// <param name="key">The translation key.</param> + /// <param name="locale">The locale to get.</param> + /// <param name="withFallback">Whether to add duplicate translations for locale fallback. For example, if a translation is defined in <c>default.json</c> but not <c>fr.json</c>, setting this to true will add a <c>fr</c> entry which duplicates the default text.</param> + private string GetRaw(string key, string locale, bool withFallback) + { + foreach (string next in this.GetRelevantLocales(locale)) + { + string translation = null; + bool hasTranslation = + this.All.TryGetValue(next, out IDictionary<string, string> translations) + && translations.TryGetValue(key, out translation); + + if (hasTranslation) + return translation; + + if (!withFallback) + break; + } + + return null; + } + /// <summary>Get the locales which can provide translations for the given locale, in precedence order.</summary> /// <param name="locale">The locale for which to find valid locales.</param> private IEnumerable<string> GetRelevantLocales(string locale) diff --git a/src/SMAPI/ITranslationHelper.cs b/src/SMAPI/ITranslationHelper.cs index c4b72444..b30d9b14 100644 --- a/src/SMAPI/ITranslationHelper.cs +++ b/src/SMAPI/ITranslationHelper.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using StardewValley; namespace StardewModdingAPI @@ -30,5 +30,10 @@ namespace StardewModdingAPI /// <param name="key">The translation key.</param> /// <param name="tokens">An object containing token key/value pairs. This can be an anonymous object (like <c>new { value = 42, name = "Cranberries" }</c>), a dictionary, or a class instance.</param> Translation Get(string key, object tokens); + + /// <summary>Get a translation in every locale for which it's defined.</summary> + /// <param name="key">The translation key.</param> + /// <param name="withFallback">Whether to add duplicate translations for locale fallback. For example, if a translation is defined in <c>default.json</c> but not <c>fr.json</c>, setting this to true will add a <c>fr</c> entry which duplicates the default text.</param> + IDictionary<string, Translation> GetInAllLocales(string key, bool withFallback = false); } } |