masastack / MASA.Blazor

Blazor UI component library based on Material Design. Support Blazor Server, Blazor WebAssembly and MAUI Blazor.
https://docs.masastack.com/blazor/getting-started/installation
MIT License
1.12k stars 151 forks source link

How to use i18n in MAUI Blazor #758

Closed Yu-Core closed 1 year ago

Yu-Core commented 1 year ago

在MAUI Blazor中怎么使用i18n

capdiem commented 1 year ago

@15168440402 take a look

doddgu commented 1 year ago

我印象中 MAUI Blazor 中的行为跟wasm是一样的。按照wasm的流程即可。

Yu-Core commented 1 year ago

image

doddgu commented 1 year ago

AddI18nForWasmAsync("").Result 不要用await

wuweilaiya commented 1 year ago

@doddgu @capdiem @Yu-Core Maui中读取本地静态文件的方式可能和普通的服务不一样,我本地调试看看如何在Maui中支持i18n

wuweilaiya commented 1 year ago

@Yu-Core image 在maui中可以使用AddI18n重载方法设置多语言

doddgu commented 1 year ago

这个issue先关闭。如果仍然有问题可以reopen

Yu-Core commented 1 year ago

@doddgu @capdiem @15168440402 感谢帮助,现在有办法了。 仿照AddI18nForWasmAsync()和AddI18nForServer(),写了一个扩展方法,并且在如图的位置添加相关文件

public static class I18nExtend
    {
        public static IBlazorComponentBuilder AddI18nForMauiBlazor(this IBlazorComponentBuilder builder, string localesDirectoryApi)
        {
            string supportedCulturesApi = Path.Combine(localesDirectoryApi, "supportedCultures.json");
            bool existsCultures =  FileSystem.AppPackageFileExistsAsync(supportedCulturesApi).Result;
            if (!existsCultures)
            {
                throw new Exception("Can't find path:" + supportedCulturesApi);
            }

            using Stream streamCultures =  FileSystem.OpenAppPackageFileAsync(supportedCulturesApi).Result;
            using StreamReader readerCultures = new StreamReader(streamCultures);
            string contents = readerCultures.ReadToEnd();
            string[] cultures = JsonSerializer.Deserialize<string[]>(contents) ?? throw new Exception("Failed to read supportedCultures json file data!"); ;
            List<(string culture, Dictionary<string, string>)> locales = new List<(string, Dictionary<string, string>)>();
            string[] array = cultures;
            foreach (string culture in array)
            {
                string cultureApi = Path.Combine(localesDirectoryApi, culture + ".json");
                bool existsCulture =  FileSystem.AppPackageFileExistsAsync(cultureApi).Result;
                if (!existsCulture)
                {
                    throw new Exception("Can't find path:" + cultureApi);
                }

                using Stream stream =  FileSystem.OpenAppPackageFileAsync(cultureApi).Result;
                using StreamReader reader = new StreamReader(stream);
                Dictionary<string, string> map = I18nReader.Read(reader.ReadToEnd());
                locales.Add((culture, map));
            }

            (string culture, Dictionary<string, string>)[] localesArray = locales.ToArray();
            I18nServiceCollectionExtensions.AddI18n(builder, localesArray);
            return builder;
        }
    }

2022-12-18_151510

2022-12-18_151615

https://user-images.githubusercontent.com/96511239/209728280-f590c2c0-fdc1-44c0-8389-57a294c6176c.mp4

Demo在这里

doddgu commented 1 year ago

@15168440402 可以考虑加一个mauiblazor

Yu-Core commented 1 year ago

再次阅读了Blazor官网文档,发现MAUI读取静态文件的方法可以在wwwroot下使用,所以做了一些修改

public static class I18nExtend
    {
        public static IBlazorComponentBuilder AddI18nForMauiBlazor(this IBlazorComponentBuilder builder, string localesDirectoryApi)
        {
            string supportedCulturesApi = localesDirectoryApi + "/supportedCultures.json";
            bool existsCultures = FileSystem.AppPackageFileExistsAsync(supportedCulturesApi).Result;
            if (!existsCultures)
            {
                throw new Exception("Can't find path:" + supportedCulturesApi);
            }

            using Stream streamCultures = FileSystem.OpenAppPackageFileAsync(supportedCulturesApi).Result;
            using StreamReader readerCultures = new(streamCultures);
            string contents = readerCultures.ReadToEnd();
            string[] cultures = JsonSerializer.Deserialize<string[]>(contents) ?? throw new Exception("Failed to read supportedCultures json file data!"); ;
            List<(string culture, Dictionary<string, string>)> locales = new();
            string[] array = cultures;
            foreach (string culture in array)
            {
                string cultureApi = localesDirectoryApi + "/" + culture + ".json";
                bool existsCulture = FileSystem.AppPackageFileExistsAsync(cultureApi).Result;
                if (!existsCulture)
                {
                    throw new Exception("Can't find path:" + cultureApi);
                }

                using Stream stream = FileSystem.OpenAppPackageFileAsync(cultureApi).Result;
                using StreamReader reader = new(stream);
                Dictionary<string, string> map = I18nReader.Read(reader.ReadToEnd());
                locales.Add((culture, map));
            }

            (string culture, Dictionary<string, string>)[] localesArray = locales.ToArray();
            I18nServiceCollectionExtensions.AddI18n(builder, localesArray);
            return builder;
        }
    }

image image

之前存放的位置也是可以用的,即Resources/Raw下存放i18n,MauiProgram.cs中添加builder.Services.AddMasaBlazor().AddI18nForMauiBlazor("i18n");

简单的测试了一下,.net6和.net7都是可以用的

示例也更新了

这个似乎无法提交pr,FileSystem.OpenAppPackageFileAsync是MAUI命名空间下。

doddgu commented 1 year ago

You can pr for this.