Make website work with languages without an associated CultureInfo
Some checks failed
Continuous Integration / Build & Test (push) Has been cancelled

This commit is contained in:
Slendy 2025-01-05 13:58:21 -06:00
commit 12b31ca92f
No known key found for this signature in database
GPG key ID: 7288D68361B91428
3 changed files with 53 additions and 25 deletions

View file

@ -1,4 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Resources; using System.Resources;
@ -16,7 +17,7 @@ public static class LocalizationManager
language = mapLanguageBack(language); language = mapLanguageBack(language);
#if DEBUG #if DEBUG
Console.WriteLine($"Attempting to load '{key}' for '{language}'"); Console.WriteLine($@"Attempting to load '{key}' for '{language}'");
#endif #endif
string resourceBasename = $"{namespaceStr}.{translationArea.ToString()}"; string resourceBasename = $"{namespaceStr}.{translationArea.ToString()}";
@ -84,28 +85,51 @@ public static class LocalizationManager
}; };
/// <summary> /// <summary>
/// Some languages crowdin uses have names that differ from the ones that ASP.NET expects. This function converts the names. /// Returns a Crowdin friendly language code from an ASP.NET language code
/// </summary> /// </summary>
/// <param name="language">The language to convert to ASP.NET names</param> /// <param name="language">The ASP.NET language code</param>
/// <returns>The name of the language that ASP.NET expects.</returns> /// <returns>The Crowdin friendly language code</returns>
public static string MapLanguage(string language) private static string mapLanguageBack(string language)
{ => languageMappings.FirstOrDefault(kv => kv.Value == language, KeyValuePair.Create(language, "")).Key;
foreach ((string? key, string? value) in languageMappings)
{
if (key == language) return value;
}
return language; private static string getLanguageDisplay(string langCode)
{
return langCode switch
{
"en-PT" => "Pirate Speak (The Seven Seas)",
"en-UD" => "English (Upside Down)",
"zh-CN" => "Simplified Chinese",
"zh-TW" => "Traditional Chinese",
"ingsoc" => "Newspeak",
"toki" => "Toki Pona",
_ => langCode,
};
} }
private static string mapLanguageBack(string language) public static string GetLanguageName(string langCode)
{ {
foreach ((string? key, string? value) in languageMappings) string mappedLanguage = getLanguageDisplay(langCode);
if(mappedLanguage == langCode && TryGetCultureInfo(langCode, out CultureInfo? info))
{ {
if (value == language) return key; return info!.DisplayName;
} }
return mappedLanguage;
}
return language; public static bool TryGetCultureInfo(string name, out CultureInfo? culture)
{
try
{
culture = new CultureInfo(name);
return true;
}
catch
{
culture = null;
return false;
}
} }
// This is a bit scuffed, but it will work for what I need it to do. // This is a bit scuffed, but it will work for what I need it to do.
@ -116,7 +140,7 @@ public static class LocalizationManager
List<string> languages = Assembly.GetExecutingAssembly() List<string> languages = Assembly.GetExecutingAssembly()
.GetManifestResourceNames() .GetManifestResourceNames()
.Where(r => r.StartsWith($"{namespaceStr}.{area}")) .Where(r => r.StartsWith($"{namespaceStr}.{area}"))
.Select(r => r.Substring(r.IndexOf(area), r.Length - r.IndexOf(area)).Substring(area.Length + 1)) .Select(r => r.Substring(r.IndexOf(area), r.Length - r.IndexOf(area))[(area.Length + 1)..])
.Select(r => r.Replace(".resources", string.Empty)) // Remove .resources .Select(r => r.Replace(".resources", string.Empty)) // Remove .resources
.Select(r => r.Replace("lang-", string.Empty)) // Remove 'lang-' prefix from languages .Select(r => r.Replace("lang-", string.Empty)) // Remove 'lang-' prefix from languages
.Where(r => r != "resources") .Where(r => r != "resources")

View file

@ -97,14 +97,7 @@ function onSubmit(e){
{ {
selected = " selected=\"selected\""; selected = " selected=\"selected\"";
} }
string langName = new CultureInfo(lang).DisplayName; string langName = LocalizationManager.GetLanguageName(lang);
langName = lang switch
{
"en-PT" => "Pirate Speak (The Seven Seas)",
"zh-CN" => "Simplified Chinese",
"zh-TW" => "Traditional Chinese",
_ => langName,
};
<option value="@lang"@selected>@langName</option> <option value="@lang"@selected>@langName</option>
} }
</select> </select>

View file

@ -5,11 +5,13 @@ using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories; using LBPUnion.ProjectLighthouse.Configuration.ConfigurationCategories;
using LBPUnion.ProjectLighthouse.Database; using LBPUnion.ProjectLighthouse.Database;
using LBPUnion.ProjectLighthouse.Localization; using LBPUnion.ProjectLighthouse.Localization;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Mail; using LBPUnion.ProjectLighthouse.Mail;
using LBPUnion.ProjectLighthouse.Middlewares; using LBPUnion.ProjectLighthouse.Middlewares;
using LBPUnion.ProjectLighthouse.Servers.Website.Captcha; using LBPUnion.ProjectLighthouse.Servers.Website.Captcha;
using LBPUnion.ProjectLighthouse.Servers.Website.Middlewares; using LBPUnion.ProjectLighthouse.Servers.Website.Middlewares;
using LBPUnion.ProjectLighthouse.Services; using LBPUnion.ProjectLighthouse.Services;
using LBPUnion.ProjectLighthouse.Types.Logging;
using LBPUnion.ProjectLighthouse.Types.Mail; using LBPUnion.ProjectLighthouse.Types.Mail;
using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
@ -81,7 +83,16 @@ public class WebsiteStartup
services.Configure<RequestLocalizationOptions>(config => services.Configure<RequestLocalizationOptions>(config =>
{ {
List<CultureInfo> languages = LocalizationManager.GetAvailableLanguages().Select(l => new CultureInfo(LocalizationManager.MapLanguage(l))).ToList(); List<CultureInfo> languages = LocalizationManager.GetAvailableLanguages()
.Select(l =>
{
LocalizationManager.TryGetCultureInfo(l, out CultureInfo? culture);
if(culture == null) Logger.Debug($"Failed to generate culture info for language {l}", LogArea.Startup);
return culture;
})
.Where(c => c != null)
.ToList()!;
config.DefaultRequestCulture = new RequestCulture(new CultureInfo("en")); config.DefaultRequestCulture = new RequestCulture(new CultureInfo("en"));