feat: Implement URL-based culture detection, localization cache busting, and enable full Blazor WASM globalization data.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<ActivatorContent>
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1" Class="mr-2 cursor-pointer">
|
||||
<MudText Typo="Typo.button" Style="font-family: var(--font-heading);">
|
||||
@(CultureInfo.CurrentCulture.Name.StartsWith("vi") ? "VI" : "EN")
|
||||
@GetCurrentLabel()
|
||||
</MudText>
|
||||
<MudIcon Icon="@Icons.Material.Rounded.Language" Size="Size.Small" />
|
||||
</MudStack>
|
||||
@@ -27,13 +27,24 @@
|
||||
</MudMenu>
|
||||
|
||||
@code {
|
||||
private string GetCurrentLabel()
|
||||
{
|
||||
var uri = new Uri(Navigation.Uri);
|
||||
var path = uri.PathAndQuery;
|
||||
|
||||
// Simple heuristic: if path starts with /vi-VN or /vi, show VI. Default EN.
|
||||
if (path.StartsWith("/vi", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "VI";
|
||||
}
|
||||
return "EN";
|
||||
}
|
||||
|
||||
private void SwitchLanguage(string targetCulture)
|
||||
{
|
||||
var uri = new Uri(Navigation.Uri);
|
||||
var path = uri.PathAndQuery;
|
||||
|
||||
// Simple logic to replace or prepend culture segment
|
||||
// Check if path starts with a supported culture
|
||||
|
||||
var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
string newPath;
|
||||
@@ -42,13 +53,11 @@
|
||||
segments[0].Equals("vi", StringComparison.OrdinalIgnoreCase) ||
|
||||
segments[0].Equals("en", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
// Replace first segment
|
||||
segments[0] = targetCulture;
|
||||
newPath = "/" + string.Join('/', segments);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prepend
|
||||
if (path == "/") path = "";
|
||||
newPath = $"/{targetCulture}{path}";
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class LocalizationCache
|
||||
if (cultureName == "vi") cultureName = "vi-VN";
|
||||
if (cultureName == "en") cultureName = "en-US";
|
||||
|
||||
var loaded = await _httpClient.GetFromJsonAsync<Dictionary<string, string>>($"/locales/{cultureName}.json");
|
||||
var loaded = await _httpClient.GetFromJsonAsync<Dictionary<string, string>>($"/locales/{cultureName}.json?v={DateTime.Now.Ticks}");
|
||||
if (loaded != null)
|
||||
{
|
||||
_strings = loaded;
|
||||
|
||||
@@ -27,8 +27,26 @@ builder.Services.AddSingleton<IStringLocalizerFactory, JsonStringLocalizerFactor
|
||||
// Build the host
|
||||
var host = builder.Build();
|
||||
|
||||
// Initialize Localization Cache
|
||||
// Initialize Localization Cache
|
||||
var cache = host.Services.GetRequiredService<LocalizationCache>();
|
||||
await cache.LoadAsync(CultureInfo.CurrentCulture);
|
||||
|
||||
// Detect culture from BaseAddress (which is set by <base href> from Server)
|
||||
var baseAddress = builder.HostEnvironment.BaseAddress;
|
||||
var culture = new CultureInfo("en-US"); // Default
|
||||
|
||||
if (baseAddress.Contains("/vi-VN/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
culture = new CultureInfo("vi-VN");
|
||||
}
|
||||
else if (baseAddress.Contains("/vi/", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
culture = new CultureInfo("vi-VN");
|
||||
}
|
||||
|
||||
CultureInfo.DefaultThreadCurrentCulture = culture;
|
||||
CultureInfo.DefaultThreadCurrentUICulture = culture;
|
||||
|
||||
await cache.LoadAsync(culture);
|
||||
|
||||
await host.RunAsync();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
|
||||
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user