#axum #htmx #request-headers #header #response-headers #guard #extractor

axum-htmx

为 axum 提供一套 htmx 提取器、响应器和请求保护器

7 个版本 (破坏性更新)

0.6.0 2024年6月24日
0.5.0 2023年12月3日
0.4.0 2023年10月24日
0.3.1 2023年8月16日
0.1.0 2023年7月22日

#132 in Web 编程

Download history 598/week @ 2024-05-04 656/week @ 2024-05-11 584/week @ 2024-05-18 542/week @ 2024-05-25 638/week @ 2024-06-01 710/week @ 2024-06-08 587/week @ 2024-06-15 932/week @ 2024-06-22 1005/week @ 2024-06-29 1279/week @ 2024-07-06 1405/week @ 2024-07-13 1397/week @ 2024-07-20 1121/week @ 2024-07-27 1199/week @ 2024-08-03 1308/week @ 2024-08-10 1125/week @ 2024-08-17

每月5,052次下载
prest 中使用

MIT/Apache

66KB
1K SLoC

axum-htmx


axum-htmx 是一个小型扩展库,为 htmx 标头在 axum 中提供提取器、响应器和请求保护器。

目录

入门

运行 cargo add axum-htmx 将库添加到您的项目中。

提取器

所有 htmx 请求头 都有一个支持的提取器。提取器是可靠的,意味着它们总是成功并且不会返回错误。在头不存在的情况下,提取器将返回 Nonefalse,这取决于预期的返回类型。

头部 提取器
HX-Boosted HxBoosted bool
HX-Current-URL HxCurrentUrl Option<axum::http::Uri>
HX-History-Restore-Request HxHistoryRestoreRequest bool
HX-Prompt HxPrompt Option<String>
HX-Request HxRequest bool
HX-Target HxTarget Option<String>
HX-Trigger-Name HxTriggerName Option<String>
HX-Trigger HxTrigger Option<String>

响应器

所有 htmx 响应头 都有一个支持的响应器。响应器是一个实现了 IntoResponseParts 的基本类型,允许您简单且安全地将 HX-* 头应用到任何响应中。

头部 响应器
HX-位置 HxLocation axum::http::Uri
HX--URL HxPushUrl axum::http::Uri
HX-重定向 HxRedirect axum::http::Uri
HX-刷新 HxRefresh bool
HX-替换-URL HxReplaceUrl axum::http::Uri
HX-重置 HxReswap axum_htmx::responders::SwapOption
HX-重定向 HxRetarget String
HX-重选 HxReselect String
HX-Trigger HxResponseTrigger axum_htmx::serde::HxEvent
HX-Trigger-之后-解决 HxResponseTrigger axum_htmx::serde::HxEvent
HX-Trigger-之后-交换 HxResponseTrigger axum_htmx::serde::HxEvent

可变响应器

此外,还有相应的缓存相关头部,您可能需要根据 htmx 头部将其添加到 GET 响应中。

例如,如果您的服务器在 HX-Request 头部缺失或为 false 时渲染完整的 HTML,而在 HX-Request: true 时只渲染 HTML 的一部分,您需要添加 Vary: HX-Request。这将导致缓存根据响应 URL 和 HX-Request 请求头的一个组合进行键控 - 而不是仅仅基于响应 URL。

有关详细信息,请参阅 缓存 htmx 文档部分

头部 响应器
Vary: HX-Request VaryHxRequest
Vary: HX-Target VaryHxTarget
Vary: HX-Trigger VaryHxTrigger
Vary: HX-Trigger-Name VaryHxTriggerName

请查看 自动缓存管理 部分,了解如何自动管理 Vary 头部。

自动缓存管理

需要功能 auto-vary

手动使用 Vary 响应器 会使代码变得脆弱,因为需要手动控制使用提取器与响应器之间的对应关系。

我们提供了一个 中间件 来解决这个问题,通过在相应提取器使用时自动添加 Vary 头部。例如,在提取 HxRequest 时,中间件会自动将 Vary: hx-request 头部添加到响应中。

请查看 示例

请求保护器

需要功能 guards

除了提取器之外,还有一个针对 HX-Request 头部的路由范围请求保护。默认情况下,它将不带该头部的任何请求重定向到 "/"。

需要注意的是,这 NOT 是认证保护器的替代品。用户可以简单地自己设置 HX-Request 头部。这只是为了方便防止用户在没有上下文的情况下收到部分响应。如果您需要保护端点,应使用合适的认证系统。

示例

示例:提取器

在此示例中,我们将查找 HX-Boosted 头部,该头部在将 hx-boost 属性应用到元素上时设置。在我们的情况下,我们将用它来确定我们发送什么类型的响应。

这何时有用?当使用模板引擎,如 minijinja 时,通常从 _base.html 模板扩展不同的模板。然而,htmx 通过发送部分响应来工作,因此扩展我们的 _base.html 将导致通过网络发送大量额外数据。

如果我们想要在页面之间切换,我们需要支持完整的模板响应和部分响应(因为页面可以直接访问或通过增强的锚点访问),因此我们查找 HX-Boosted 头部,并从 _partial.html 模板进行扩展。

use axum::response::IntoResponse;
use axum_htmx::HxBoosted;

async fn get_index(HxBoosted(boosted): HxBoosted) -> impl IntoResponse {
    if boosted {
        // Send a template extending from _partial.html
    } else {
        // Send a template extending from _base.html
    }
}

示例:响应器

我们可以使用 htmx 触发器 头部触发 DOM 上监听的所有事件。

use axum_htmx::HxResponseTrigger;

// When we load our page, we will trigger any event listeners for "my-event.
async fn index() -> (HxResponseTrigger, &'static str) {
    // Note: As HxResponseTrigger only implements `IntoResponseParts`, we must
    // return our trigger first here.
    (
        HxResponseTrigger::normal(["my-event", "second-event"]),
        "Hello, world!",
    )
}

htmx 还允许发送任意数据与事件一起,我们可以通过 serde 功能标志和 HxEvent 类型来使用这些数据。

use serde_json::json;

// Note that we are using `HxResponseTrigger` from the `axum_htmx::serde` module
// instead of the root module.
use axum_htmx::{HxEvent, HxResponseTrigger};

async fn index() -> (HxResponseTrigger, &'static str) {
    let event = HxEvent::new_with_data(
        "my-event",
        // May be any object that implements `serde::Serialize`
        json!({"level": "info", "message": {
            "title": "Hello, world!",
            "body": "This is a test message.",
        }}),
    )
    .unwrap();

    // Note: As HxResponseTrigger only implements `IntoResponseParts`, we must
    // return our trigger first here.
    (HxResponseTrigger::normal([event]), "Hello, world!")
}

示例:路由保护器

use axum::Router;
use axum_htmx::HxRequestGuardLayer;

fn router_one() -> Router {
    Router::new()
        // Redirects to "/" if the HX-Request header is not present
        .layer(HxRequestGuardLayer::default())
}

fn router_two() -> Router {
    Router::new()
        .layer(HxRequestGuardLayer::new("/redirect-to-this-route"))
}

功能标志

标志 默认值 描述 依赖项
自动变化 已禁用 一个中间件,用于解决 htmx 缓存问题 futurestokiotower
守卫 已禁用 添加请求守卫层。 towerfutures-corepin-project-lite
serde 已禁用 HxEventLocationOptions 添加 serde 支持 serdeserde_json

贡献

欢迎贡献!如果您有关于功能的想法或发现了错误,请告诉我。PR 欢迎接受,但如果不是小改动,请先提交问题,以便我们都在同一页面上。

测试

cargo +nightly test --all-features

许可证

axum-htmx 可以选择以下任一许可证

任选其一。

依赖项

~1.6–3.5MB
~70K SLoC