#本地化 #axum

axum_l10n

为 Axum 提供本地化实用工具的包

13 个版本

0.3.1 2024 年 7 月 1 日
0.3.0 2024 年 6 月 12 日
0.2.8 2024 年 3 月 28 日
0.2.6 2024 年 2 月 22 日
0.1.1 2024 年 1 月 2 日

#41国际化(i18n)

Download history 29/week @ 2024-05-03 33/week @ 2024-05-10 59/week @ 2024-05-17 75/week @ 2024-05-24 74/week @ 2024-05-31 200/week @ 2024-06-07 115/week @ 2024-06-14 64/week @ 2024-06-21 257/week @ 2024-06-28 119/week @ 2024-07-05 67/week @ 2024-07-12 77/week @ 2024-07-19 62/week @ 2024-07-26 62/week @ 2024-08-02 51/week @ 2024-08-09 16/week @ 2024-08-16

214 每月下载量

MIT/Apache

36KB
716

关于此包

此包提供了一些用于与 Axum 一起使用的本地化工具。

基本用法

您可以使用此包从请求中提取 语言标识符(例如 en-US)。

如果模式设置为 RedirectMode::NoRedirect,则使用 Accept-Language 头部来查找用户首选的语言。如果模式设置为 RedirectMode::RedirectToFullLocaleSubPathRedirectMode::RedirectToLanguageSubPath,则用户将被重定向到基于其 Accept-Language 头部的子路径,如果不支持则重定向到默认语言。

use unic_langid::{langid, LanguageIdentifier};
use axum::Extension;

pub const ENGLISH: LanguageIdentifier = langid!("en");
pub const JAPANESE: LanguageIdentifier = langid!("ja");

let router = axum::Router::new()
      .route("/lists", get(|Extension(lang): Extension<LanguageIdentifier>|
        async move {
          Html(format!("Your language is: {}", lang.to_string()))
        }))
      .layer(axum_l10n::LanguageIdentifierExtractorLayer::new(
          ENGLISH,
          vec![ENGLISH, JAPANESE],
          axum_l10n::RedirectMode::NoRedirect,
      ));

对于 RedirectMode::RedirectToFullLocaleSubPathRedirectMode::RedirectToLanguageSubPath,您必须像 这里 所述的那样将此服务/中间件包装在 axum 应用程序的整个范围内。

当使用子路径重定向模式时,您可能希望排除一些文件夹进行重定向,如下所示

let l10n_middleware = axum_l10n::LanguageIdentifierExtractorLayer::new(
        JAPANESE,
        vec![JAPANESE, ENGLISH],
        axum_l10n::RedirectMode::RedirectToLanguageSubPath,
    )
    .excluded_paths(&["/api", "/assets", "/auth"]);

功能

fluent

启用 fluent 允许您使用 fluent Localizer 添加翻译包。

有关 fluent 和 rust 的详细信息,请参阅 fluent-rs

用法

use unic_langid::{langid, LanguageIdentifier};
use axum_l10n::Localizer;

pub const ENGLISH: LanguageIdentifier = langid!("en");
pub const JAPANESE: LanguageIdentifier = langid!("ja");
let mut localizer = Localizer::new();

localizer
    .add_bundle(JAPANESE, &["locales/ja/main.ftl", "locales/ja/login.ftl"])
    .unwrap();
localizer
    .add_bundle(ENGLISH, &["locales/en/main.ftl", "locales/en/login.ftl"])
    .unwrap();

let message = localizer.format_message(&ENGLISH, "test-key-a", None);

assert_eq!(Some(String::from("Hello World")), message);

tera

启用 tera 功能允许您在 tera 模板中使用 fluent 翻译。

有关 tera 的更多信息,请参阅 tera

用法

初始化

use tera::Tera;

let mut tera = Tera::new("src/views/templates/**/*").expect("tera parsing error");

let mut localizer = Localizer::new();

localizer
    .add_bundle(ENGLISH, &["locales/en/main.ftl", "locales/en/login.ftl"])
    .unwrap();

tera.register_function("fluent", localizer);

Axum 处理程序

#[derive(Clone)]
struct ViewRouterState {
    pool: mysql_async::Pool,
    tera: Arc<tera::Tera>,
}

async fn lists_view(
    State(state): State<ViewRouterState>,
    Extension(lang): Extension<LanguageIdentifier>,
) -> axum::response::Response {
    let lists: Vec<String> = List::paginate(&state.pool, claim.sub)
        .await.unwrap();

    let mut ctx = Context::new();
    ctx.insert("lists", &lists);
    ctx.insert("lang", &lang);

    let html = state.tera.render("lists.html", &ctx).unwrap();

    Html(html).into_response()
}

在 tera 模板中

<label for="family-id">{{ fluent(key="list-family", lang=lang) }}</label>
<select name="family-id" id="family-id">
  {% for family in families %}
  <option value="{{ family.family_id }}">{{ family.family_name }}</option>
  {% endfor %}
</select>

依赖项

~3–13MB
~147K SLoC