mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-28 16:08:38 +00:00
Add translation support to website, read user's language from settings
This commit is contained in:
parent
bfec7d788e
commit
3e18d79fa5
8 changed files with 103 additions and 33 deletions
|
@ -15,15 +15,12 @@ public static class LocalizationManager
|
||||||
Console.WriteLine($"Attempting to load '{key}' for '{language}'");
|
Console.WriteLine($"Attempting to load '{key}' for '{language}'");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string resourceBasename;
|
string resourceBasename = $"{namespaceStr}.{translationArea.ToString()}";
|
||||||
if (language == defaultLang)
|
|
||||||
{
|
// We don't have an en-US .resx, so if we aren't using en-US then we need to add the appropriate language.
|
||||||
resourceBasename = $"{namespaceStr}.{translationArea.ToString()}";
|
// Otherwise, keep it to the normal .resx file
|
||||||
}
|
// e.g. BaseLayout.resx as opposed to BaseLayout.lang-da-DK.resx.
|
||||||
else
|
if (language != defaultLang) resourceBasename += $".lang-{language}";
|
||||||
{
|
|
||||||
resourceBasename = $"{namespaceStr}.{translationArea.ToString()}.lang-{language}";
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceManager resourceManager = new(resourceBasename, Assembly.GetExecutingAssembly());
|
ResourceManager resourceManager = new(resourceBasename, Assembly.GetExecutingAssembly());
|
||||||
|
|
||||||
|
@ -39,12 +36,12 @@ public static class LocalizationManager
|
||||||
return localizedString;
|
return localizedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<string> GetAvailableLanguages(TranslationAreas translationArea)
|
// This is a bit scuffed, but it will work for what I need it to do.
|
||||||
|
public static IEnumerable<string> GetAvailableLanguages()
|
||||||
{
|
{
|
||||||
string area = translationArea.ToString();
|
string area = TranslationAreas.BaseLayout.ToString();
|
||||||
|
|
||||||
// scuffed but it will work for now
|
List<string> languages = Assembly.GetExecutingAssembly()
|
||||||
List<string> langs = 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)).Substring(area.Length + 1))
|
||||||
|
@ -53,8 +50,8 @@ public static class LocalizationManager
|
||||||
.Where(r => r != "resources")
|
.Where(r => r != "resources")
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
langs.Add(defaultLang);
|
languages.Add(defaultLang);
|
||||||
|
|
||||||
return langs;
|
return languages;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@ public static class Program
|
||||||
|
|
||||||
Console.Write('\n');
|
Console.Write('\n');
|
||||||
|
|
||||||
foreach (string language in LocalizationManager.GetAvailableLanguages(TranslationAreas.BaseLayout))
|
foreach (string language in LocalizationManager.GetAvailableLanguages())
|
||||||
{
|
{
|
||||||
Console.WriteLine(LocalizationManager.GetLocalizedString(TranslationAreas.BaseLayout, language, "header_home"));
|
Console.WriteLine(LocalizationManager.GetLocalizedString(TranslationAreas.BaseLayout, language, "header_home"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace LBPUnion.ProjectLighthouse.Localization.StringLists;
|
||||||
|
|
||||||
|
public static class BaseLayoutStrings
|
||||||
|
{
|
||||||
|
public static readonly TranslatableString HeaderHome = create("header_home");
|
||||||
|
public static readonly TranslatableString HeaderUsers = create("header_users");
|
||||||
|
public static readonly TranslatableString HeaderPhotos = create("header_photos");
|
||||||
|
public static readonly TranslatableString HeaderSlots = create("header_slots");
|
||||||
|
|
||||||
|
private static TranslatableString create(string key) => new(TranslationAreas.BaseLayout, key);
|
||||||
|
}
|
21
ProjectLighthouse.Localization/TranslatableString.cs
Normal file
21
ProjectLighthouse.Localization/TranslatableString.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
namespace LBPUnion.ProjectLighthouse.Localization;
|
||||||
|
|
||||||
|
public class TranslatableString
|
||||||
|
{
|
||||||
|
public TranslatableString(TranslationAreas area, string key)
|
||||||
|
{
|
||||||
|
this.Key = key;
|
||||||
|
this.Area = area;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Key { get; init; }
|
||||||
|
public TranslationAreas Area { get; init; }
|
||||||
|
|
||||||
|
public string Translate(string language) => LocalizationManager.GetLocalizedString(this.Area, language, this.Key);
|
||||||
|
|
||||||
|
[Obsolete("Do not translate by using ToString. Use TranslatableString.Translate().", true)]
|
||||||
|
public override string ToString() => "NOT TRANSLATED CORRECTLY!";
|
||||||
|
|
||||||
|
[Obsolete("Do not translate by using ToString. Use TranslatableString.Translate().", true)]
|
||||||
|
public static implicit operator string(TranslatableString _) => "NOT TRANSLATED CORRECTLY!";
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
@using LBPUnion.ProjectLighthouse.Helpers
|
@using LBPUnion.ProjectLighthouse.Helpers
|
||||||
@using LBPUnion.ProjectLighthouse.Helpers.Extensions
|
@using LBPUnion.ProjectLighthouse.Helpers.Extensions
|
||||||
|
@using LBPUnion.ProjectLighthouse.Localization
|
||||||
@using LBPUnion.ProjectLighthouse.Types
|
@using LBPUnion.ProjectLighthouse.Types
|
||||||
@using LBPUnion.ProjectLighthouse.Types.Settings
|
@using LBPUnion.ProjectLighthouse.Types.Settings
|
||||||
@model LBPUnion.ProjectLighthouse.Pages.Layouts.BaseLayout
|
@model LBPUnion.ProjectLighthouse.Pages.Layouts.BaseLayout
|
||||||
|
@ -7,21 +8,21 @@
|
||||||
@{
|
@{
|
||||||
if (Model!.User == null)
|
if (Model!.User == null)
|
||||||
{
|
{
|
||||||
Model.NavigationItemsRight.Add(new PageNavigationItem("Login / Register", "/login", "sign in"));
|
Model.NavigationItemsRight.Add(new PageNavigationItem(new TranslatableString(TranslationAreas.BaseLayout, "Login / Register"), "/login", "sign in"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ServerSettings.Instance.UseExternalAuth)
|
if (ServerSettings.Instance.UseExternalAuth)
|
||||||
{
|
{
|
||||||
Model.NavigationItems.Add(new PageNavigationItem("Authentication", "/authentication", "key"));
|
Model.NavigationItems.Add(new PageNavigationItem(new TranslatableString(TranslationAreas.BaseLayout, "Authentication"), "/authentication", "key"));
|
||||||
}
|
}
|
||||||
Model.NavigationItemsRight.Add(new PageNavigationItem("Profile", "/user/" + Model.User.UserId, "user alternate"));
|
Model.NavigationItemsRight.Add(new PageNavigationItem(new TranslatableString(TranslationAreas.BaseLayout, "Profile"), "/user/" + Model.User.UserId, "user alternate"));
|
||||||
|
|
||||||
@if (Model.User.IsAdmin)
|
@if (Model.User.IsAdmin)
|
||||||
{
|
{
|
||||||
Model.NavigationItemsRight.Add(new PageNavigationItem("Admin Panel", "/admin", "cogs"));
|
Model.NavigationItemsRight.Add(new PageNavigationItem(new TranslatableString(TranslationAreas.BaseLayout, "Admin Panel"), "/admin", "cogs"));
|
||||||
}
|
}
|
||||||
Model.NavigationItemsRight.Add(new PageNavigationItem("Log out", "/logout", "user alternate slash")); // should always be last
|
Model.NavigationItemsRight.Add(new PageNavigationItem(new TranslatableString(TranslationAreas.BaseLayout, "Log out"), "/logout", "user alternate slash")); // should always be last
|
||||||
}
|
}
|
||||||
|
|
||||||
Model.IsMobile = Model.Request.IsMobile();
|
Model.IsMobile = Model.Request.IsMobile();
|
||||||
|
@ -93,7 +94,7 @@
|
||||||
|
|
||||||
@if (!Model.IsMobile)
|
@if (!Model.IsMobile)
|
||||||
{
|
{
|
||||||
@navigationItem.Name
|
@Model.Translate(navigationItem.Name)
|
||||||
}
|
}
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
|
@ -108,7 +109,7 @@
|
||||||
|
|
||||||
@if (!Model.IsMobile)
|
@if (!Model.IsMobile)
|
||||||
{
|
{
|
||||||
@navigationItem.Name
|
@Model.Translate(navigationItem.Name)
|
||||||
}
|
}
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using LBPUnion.ProjectLighthouse.Localization;
|
||||||
|
using LBPUnion.ProjectLighthouse.Localization.StringLists;
|
||||||
using LBPUnion.ProjectLighthouse.Types;
|
using LBPUnion.ProjectLighthouse.Types;
|
||||||
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
namespace LBPUnion.ProjectLighthouse.Pages.Layouts;
|
namespace LBPUnion.ProjectLighthouse.Pages.Layouts;
|
||||||
|
|
||||||
public class BaseLayout : PageModel
|
public class BaseLayout : PageModel
|
||||||
{
|
{
|
||||||
|
|
||||||
public readonly Database Database;
|
public readonly Database Database;
|
||||||
|
|
||||||
public readonly List<PageNavigationItem> NavigationItems = new()
|
public readonly List<PageNavigationItem> NavigationItems = new();
|
||||||
{
|
|
||||||
new PageNavigationItem("Home", "/", "home"),
|
|
||||||
new PageNavigationItem("Users", "/users/0", "user friends"),
|
|
||||||
new PageNavigationItem("Photos", "/photos/0", "camera"),
|
|
||||||
new PageNavigationItem("Levels", "/slots/0", "certificate"),
|
|
||||||
};
|
|
||||||
|
|
||||||
public readonly List<PageNavigationItem> NavigationItemsRight = new();
|
public readonly List<PageNavigationItem> NavigationItemsRight = new();
|
||||||
public string Description = string.Empty;
|
public string Description = string.Empty;
|
||||||
|
@ -31,6 +28,11 @@ public class BaseLayout : PageModel
|
||||||
public BaseLayout(Database database)
|
public BaseLayout(Database database)
|
||||||
{
|
{
|
||||||
this.Database = database;
|
this.Database = database;
|
||||||
|
|
||||||
|
this.NavigationItems.Add(new PageNavigationItem(BaseLayoutStrings.HeaderHome, "/", "home"));
|
||||||
|
this.NavigationItems.Add(new PageNavigationItem(BaseLayoutStrings.HeaderUsers, "/users/0", "user friends"));
|
||||||
|
this.NavigationItems.Add(new PageNavigationItem(BaseLayoutStrings.HeaderPhotos, "/photos/0", "camera"));
|
||||||
|
this.NavigationItems.Add(new PageNavigationItem(BaseLayoutStrings.HeaderSlots, "/slots/0", "certificate"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public new User? User {
|
public new User? User {
|
||||||
|
@ -41,4 +43,20 @@ public class BaseLayout : PageModel
|
||||||
}
|
}
|
||||||
set => this.user = value;
|
set => this.user = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Translate(TranslatableString translatableString)
|
||||||
|
{
|
||||||
|
string lang;
|
||||||
|
IRequestCultureFeature? requestCulture = Request.HttpContext.Features.Get<IRequestCultureFeature>();
|
||||||
|
|
||||||
|
if (requestCulture == null) lang = "en-UD"; // TODO: change to en-US when i can verify this is working
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lang = requestCulture.RequestCulture.UICulture.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(lang);
|
||||||
|
|
||||||
|
return translatableString.Translate(lang);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Kettu;
|
using Kettu;
|
||||||
using LBPUnion.ProjectLighthouse.Helpers;
|
using LBPUnion.ProjectLighthouse.Helpers;
|
||||||
|
using LBPUnion.ProjectLighthouse.Localization;
|
||||||
using LBPUnion.ProjectLighthouse.Logging;
|
using LBPUnion.ProjectLighthouse.Logging;
|
||||||
using LBPUnion.ProjectLighthouse.Serialization;
|
using LBPUnion.ProjectLighthouse.Serialization;
|
||||||
using LBPUnion.ProjectLighthouse.Types;
|
using LBPUnion.ProjectLighthouse.Types;
|
||||||
|
@ -12,6 +16,7 @@ using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
@ -85,6 +90,19 @@ public class Startup
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
services.Configure<RequestLocalizationOptions>
|
||||||
|
(
|
||||||
|
config =>
|
||||||
|
{
|
||||||
|
List<CultureInfo> languages = LocalizationManager.GetAvailableLanguages().Select(l => new CultureInfo(l)).ToList();
|
||||||
|
|
||||||
|
config.DefaultRequestCulture = new RequestCulture(new CultureInfo("en-US"));
|
||||||
|
|
||||||
|
config.SupportedCultures = languages;
|
||||||
|
config.SupportedUICultures = languages;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
services.AddSingleton<IHostLifetime, DebugWarmupLifetime>();
|
services.AddSingleton<IHostLifetime, DebugWarmupLifetime>();
|
||||||
#else
|
#else
|
||||||
|
@ -123,6 +141,8 @@ public class Startup
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
app.UseRequestLocalization();
|
||||||
|
|
||||||
// Logs every request and the response to it
|
// Logs every request and the response to it
|
||||||
// Example: "200, 13ms: GET /LITTLEBIGPLANETPS3_XML/news"
|
// Example: "200, 13ms: GET /LITTLEBIGPLANETPS3_XML/news"
|
||||||
// Example: "404, 127ms: GET /asdasd?query=osucookiezi727ppbluezenithtopplayhdhr"
|
// Example: "404, 127ms: GET /asdasd?query=osucookiezi727ppbluezenithtopplayhdhr"
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
|
using LBPUnion.ProjectLighthouse.Localization;
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
namespace LBPUnion.ProjectLighthouse.Types;
|
namespace LBPUnion.ProjectLighthouse.Types;
|
||||||
|
|
||||||
public class PageNavigationItem
|
public class PageNavigationItem
|
||||||
{
|
{
|
||||||
public PageNavigationItem(string name, string url, string? icon = null)
|
public PageNavigationItem(TranslatableString name, string url, string? icon = null)
|
||||||
{
|
{
|
||||||
this.Name = name;
|
this.Name = name;
|
||||||
this.Url = url;
|
this.Url = url;
|
||||||
this.Icon = icon;
|
this.Icon = icon;
|
||||||
}
|
}
|
||||||
public string Name { get; set; }
|
public TranslatableString Name { get; set; }
|
||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
public string? Icon { get; set; }
|
public string? Icon { get; set; }
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue