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
其中Rust
的crate
是:
https://crates.io/crates/fluent
下面,我们开始逐步介绍,如何在Yew
里使用
第一步,准备多语言文件:
zh-CN.txt
和 en-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
评论区
写评论还没有评论