< 返回版块

songday 发表于 2022-02-15 15:31

Tags:Yew,前端,i18n,国际化,博客

Yew 本身没有并提供国际化(i18n)功能的,我们会用到另外一个项目:fluent

Project Fluent​
projectfluent.org/

这个是一个Mozilla UI显示国际化的一个项目,其已经被应用于Firefox等项目中。

配置国际化文本很简单,就是一个文本文件对应一个语言

在文本文件里,添加如下配置,就可以在程序里使用了:

# 类似key-value键值对

# Simple things are simple.
hello-user = Hello, {$userName}!

# Complex things are possible.
shared-photos =
    {$userName} {$photoCount ->
        [one] added a new photo
       *[other] added {$photoCount} new photos
    } to {$userGender ->
        [male] his stream
        [female] her stream
       *[other] their stream
    }.

(在它的官网上,可以看到动态效果)

如何使用上述国际语言文件,fluent提供了很多包,包括: 1.Javascript 2.Python 3.Rust 4.以及React

其中Rustcrate是:

https://crates.io/crates/fluent​

下面,我们开始逐步介绍,如何在Yew里使用

第一步,准备多语言文件:

zh-CN.txten-US.txt

具体内容可以参看:
https://github.com/songday/blog-rs/blob/main/frontend/resource/i18n/zh-CN.txt
https://github.com/songday/blog-rs/blob/main/frontend/resource/i18n/en-US.txt

第二步,创建一个读取国际化文件的方法

// 入参有两个:accept_language是用户当前使用的语言,message_ids是获取国际化文本的key数组
// 返回是一个Map,key和value对应国际化配置的key-value
pub fn get<'a, 'b>(
    accept_language: &'a str,
    message_ids: Vec<&'static str>,
) -> Result<HashMap<&'static str, String>, ()> {
    let (locale, resource) = match accept_language {
        "en-US" => (accept_language, EN_US_TEXT),
        _ => ("zh-CN", ZH_CN_TEXT), // 默认使用中文
    };
    let ftl_string = resource.to_owned();
    let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string.");

    let lang_id = locale.parse().expect("Parsing failed.");
    let mut bundle = FluentBundle::new(vec![lang_id]);
    bundle
        .add_resource(&res)
        .expect("Failed to add FTL resources to the bundle.");

    let mut result = HashMap::with_capacity(message_ids.len());
    let mut errors = vec![];
    for message_id in message_ids {
        let msg = bundle.get_message(message_id).expect("Message doesn't exist.");
        let pattern = msg.value().expect("Message has no value.");
        let value = bundle.format_pattern(&pattern, None, &mut errors);
        errors.clear();
        result.insert(message_id, value.to_string());
    }
    Ok(result)
}

详细的可以看:
https://github.com/songday/blog-rs/blob/main/frontend/src/i18n.rs

有了这个方法,我们就可以在Yew里使用了。

第三步,应用到yew

Component里,调用上面的get方法:

// 批量获取
let messages = i18n::get(
    &user_language(),
    vec!["back", "edit", "delete", "deletion_confirm", "cancel"],
)
.unwrap();

然后进行输出:

<span>{ messages.get("back").unwrap() }</span>

至此,仅需要3步,就完成了i18n的集成。

最终效果可以去项目看截图

写在最后:

以上的显示代码,已经应用在: https://github.com/songday/blog-rs​

blog-rs是一个用Rust写的,包含前后端的开源项目。

后端是用的Warp+SQLx实现的,前端用的是Yew最新版(0.19.3)

数据库用的是SQLite

它的特点有:

1.仅有一个跨平台的执行文件(无其它依赖,数据库在第一次启动会自动初始化) 2.编辑器支持Markdown 3.可以导出到Hugo


Ext Link: https://github.com/songday/blog-rs

评论区

写评论

还没有评论

1 共 0 条评论, 1 页