diff --git a/Cargo.lock b/Cargo.lock
index 4bdeaa6..35989ca 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -117,6 +117,23 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "axum-htmx"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d16a4be621f96b959fc829e4cbf02fd79ffb8427525002af31a9e2979599fbb7"
+dependencies = [
+ "axum-core",
+ "futures",
+ "futures-core",
+ "http",
+ "pin-project-lite",
+ "serde",
+ "serde_json",
+ "tokio",
+ "tower",
+]
+
[[package]]
name = "axum-macros"
version = "0.5.0"
@@ -250,6 +267,7 @@ name = "compendium"
version = "0.1.0"
dependencies = [
"axum",
+ "axum-htmx",
"axum-sqlx-tx",
"chrono",
"minijinja",
@@ -481,6 +499,20 @@ dependencies = [
"libc",
]
+[[package]]
+name = "futures"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
[[package]]
name = "futures-channel"
version = "0.3.31"
diff --git a/Cargo.toml b/Cargo.toml
index 6565179..3867079 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
axum = { version = "0.8.1", features = ["macros"] }
+axum-htmx = { version = "0.7.0", features = ["auto-vary", "serde", "guards"] }
axum-sqlx-tx = "0.10.0"
chrono = { version = "0.4.39", features = ["serde"] }
minijinja = { version = "2.7.0", features = ["loader"] }
diff --git a/frontend/templates/base.html b/frontend/templates/base.html
index 108110e..d5b63a4 100644
--- a/frontend/templates/base.html
+++ b/frontend/templates/base.html
@@ -1,10 +1,11 @@
+
-
+
{% block title %}Axum web service!{% endblock %}
diff --git a/frontend/templates/index.html b/frontend/templates/index.html
index 824925a..c7591f0 100644
--- a/frontend/templates/index.html
+++ b/frontend/templates/index.html
@@ -1,26 +1,34 @@
{% extends "base.html" %}
{% block content %}
-
-
-
- | Database |
- Version |
- Database Name |
- Current User |
- Current Timestamp |
-
-
-
- {% for row in rows %}
-
- | {{ row.database }} |
- {{ row.version }} |
- {{ row.current_database }} |
- {{ row.current_user }} |
- {{ row.current_timestamp }} |
-
- {% endfor %}
-
-
+
+
+
+
+
+
+ {% block htmx %}
+
+
+
+ | Database |
+ Version |
+ Database Name |
+ Current User |
+ Current Timestamp |
+
+
+
+ {% for row in rows %}
+
+ | {{ row.database }} |
+ {{ row.version }} |
+ {{ row.current_database }} |
+ {{ row.current_user }} |
+ {{ row.current_timestamp }} |
+
+ {% endfor %}
+
+
+ {% endblock htmx %}
{% endblock content %}
diff --git a/src/main.rs b/src/main.rs
index 80c905b..824067f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,7 @@
#![allow(unused)]
#![allow(dead_code)]
+use axum_htmx::AutoVaryLayer;
use compendium::{router, AppState, Error, Link, Result, Tx};
use minijinja::{Environment, Value};
use sqlx::postgres::PgPoolOptions;
@@ -78,6 +79,7 @@ async fn main() -> Result<()> {
let app = router::new()
.layer(TraceLayer::new_for_http().on_request(()))
.layer(tx_layer)
+ .layer(AutoVaryLayer)
.with_state(AppState::new(tmpl_env, tx_state));
// Add hot reload only on dev mode
diff --git a/src/router.rs b/src/router.rs
index 02fb279..9fd870f 100644
--- a/src/router.rs
+++ b/src/router.rs
@@ -1,4 +1,5 @@
use axum::{extract::State, response::Html, routing::get, Router};
+use axum_htmx::HxRequest;
use chrono::Utc;
use minijinja::context;
use serde::Serialize;
@@ -22,7 +23,11 @@ struct ExampleRow {
pub current_timestamp: chrono::DateTime,
}
-async fn handler_home(State(state): State, mut tx: Tx) -> ResultTemplate {
+async fn handler_home(
+ State(state): State,
+ HxRequest(hx_request): HxRequest,
+ mut tx: Tx,
+) -> ResultTemplate {
let template = state.tmpl_env.get_template("index.html")?;
let rows = sqlx::query_as::<_, ExampleRow>("select 'Postgres' as database, setting as version, current_database(), current_user, current_timestamp from pg_settings where name = 'server_version'")
@@ -31,7 +36,13 @@ async fn handler_home(State(state): State, mut tx: Tx) -> ResultTempla
println!("{:?}", rows);
- let content = template.render(context!(rows => rows))?;
+ let content = if hx_request {
+ template
+ .eval_to_state(context!(rows => rows))?
+ .render_block("htmx")?
+ } else {
+ template.render(context!(rows => rows))?
+ };
Ok(Html(content))
}