iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
1

今天要來介紹多國語系的處理,想要建立一個國際化網站,多國語系可以說是基本需求,那我們就來看如何在 Blazor 中實現吧!


除了數字與日期格式有原先 .NET 框架的文化特性外,其他都要自己來處理多國語系的範本,這也是理所當然的,除非機器翻譯的準確率接近完美,否則公司大可花錢請人翻譯,以免在公開網站出現奇葩內容。

那麼我們該如何在 Blazor wasm 中實現多國語系呢?很遺憾官方目前並沒有提供一份詳細的文件,但留了一個 Repository 來供我們參考,讓我們以pranavkm/LocSample的方式來當作多國語系的處理吧!

首先針對需要多國語系的元件建立資源檔,其檔案名稱如 {Component}.{Culture}.resxComponent 為使用此資源檔的元件名稱,需確保名稱與元件名稱一致,Culture 為文化特性的值,若不加則代表預設的資源檔。

因為 .resx 屬於 XML 格式的檔案,所以這邊就不貼 Code 了,建立 {Component.resx} 且擁有 Greetings 欄位其值為 你好!,並建立 {Component}.en.resx 且擁有 Greetings 欄位其值為 Hello!

Component 使用資源檔前,需要先從 Nuget 安裝 Microsoft.Extensions.Localization,我們需要透過其命名空間下的 IStringLocalizer<T> 物件來取得資源檔內容,安裝完畢後記得註冊服務 builder.Services.AddLocalization();,註冊時 AddLocalization 方法也提供 LocalizationOptions 來設定額外內容,雖然目前只有提供 ResourcesPath 來修改資源檔定位的相關路徑。

然後就可以在元件注入 IStringLocalizer<T> 來存取相關的資源檔,如:

@* Day27Sample.razor *@
@inject Microsoft.Extensions.Localization.IStringLocalizer<Day27Sample> Loc
<h1>@Loc["Greetings"]</h1>

為了提供使用者切換文化特性,需要建立一個選擇文化特性的元件:

@* CultureSelector.razor *@
@using  System.Globalization
@inject IJSRuntime JSRuntime
@inject NavigationManager Nav

<strong>Culture:</strong>
<select @bind="Culture">
    @foreach (var culture in supportedCultures)
    {
        <option value="@culture">@culture.DisplayName</option>
    }
</select>

@code
{
  CultureInfo[] supportedCultures = new[]
  {
    new CultureInfo("zh-TW"),
    new CultureInfo("en-US"),
  };

  CultureInfo Culture
  {
    get => CultureInfo.CurrentCulture;
    set
    {
      if (CultureInfo.CurrentCulture != value)
      {
        var js = (IJSInProcessRuntime)JSRuntime;
        js.InvokeVoid("blazorCulture.set", value.Name);
        Nav.NavigateTo(Nav.Uri, forceLoad: true);
      }
    }
  }
}

但因為注入後就會被初始化,所以我們一定要透過網頁重啟,來使文化特性在初始化時能以使用者選擇的文化特性,所以我們需要藉由 localStorage 來保存使用者修改文化特性時的值,並且在重新啟動時取得該值:

// Program.cs
var host = builder.Build();
var jsInterop = host.Services.GetRequiredService<IJSRuntime>();
var result = await jsInterop.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
  var culture = new CultureInfo(result);
  CultureInfo.DefaultThreadCurrentCulture = culture;
  CultureInfo.DefaultThreadCurrentUICulture = culture;
}

JS 內容為:

window.blazorCulture = {
    get: () => window.localStorage['BlazorCulture'],
    set: (value) => window.localStorage['BlazorCulture'] = value
};

這樣只要在合適的地方使用 CultureSelector 元件選擇文化特性,就能透過重新載入的方式使全站語系變更,且之後的每一次進入都可以看到相同的內容,除非使用者自行清除。


以上就是多國語系的處理方式,美中不足的是這套一定要使用 .resx 來當作資源檔,沒辦法使用 .json 來處理,但 Blazor 也算是個新興框架吧?相信未來會有更多的解決辦法!完整程式碼在範本程式碼 - day27

感謝大家的閱讀,我們明天見。

參考資料
ASP.NET Core Blazor 全球化和當地語系化
pranavkm/LocSample


上一篇
JWT 驗證魔術
下一篇
元件類別庫魔術
系列文
大內魔術 Blazor - 誰說前端一定要寫JS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言