1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! HTTP routing with `define_plugin_routes!`.
//!
//! # Registering routes (`routes.rs`)
//!
//! Lariv routes map URL path patterns to async Axum handlers. Declare them in the plugin's
//! `routes.rs` using [`define_plugin_routes!`](crate::define_plugin_routes):
//!
//! ```ignore
//! use lariv_rs::define_plugin_routes;
//! use super::handlers;
//!
//! define_plugin_routes! {
//! plugin: MyPluginTag;
//! routes: [
//! // Standard app-pane GET (full page or HTMX partial)
//! get ListRouteTag, "/items", handlers::list;
//!
//! // POST with modal response
//! post CreatePostRouteTag, "/items/create", handlers::create_post, modal;
//!
//! // GET with HTMX fragment swap into a table region
//! get ListRouteTag, "/items", handlers::list, fragment(ItemTableKey);
//!
//! // Bare handler — you choose the response type
//! get LogoutRouteTag, "/logout", bare handlers::logout, redirect;
//! post DownloadRouteTag, "/export", bare handlers::download, file;
//! ]
//! }
//! ```
//!
//! # Route line syntax
//!
//! ```text
//! {get|post} RouteTag, "path/{param}", [bare] handler::fn [, response] [, param name: Type] ;
//! ```
//!
//! - **`bare`** — skip the default view wrapper; required when specifying `file`, `redirect`,
//! `raw`, or custom `fragment` responses.
//! - **Response kinds** — `modal`, `fragment(SwapKey)`, `file`, `redirect`, `generation`, `raw`.
//! Default for GET/POST app routes is app-pane rendering.
//! - **Path params** — `{id}` → `i64`, `{slug}` → `String`, `{*tail}` → `Vec<String>`.
//! Override with `param id: i64`.
//!
//! # Generated items
//!
//! For each route the macro creates:
//!
//! - `RouteTag` struct — typed URL builder with `PATH`, `new(…)`, `.path()`, `.url()`
//! - Response marker traits — `AppPaneGet`, `FragmentGet`, `ModalPost`, etc.
//! - `Hook: RouteRegistrar<…>` — prepends routes during plugin install
//!
//! At mount time, later-installed plugins win on duplicate `(path, method)` —
//! so a public-site plugin installed after dashboard can own `/`.
//!
//! Use route tags in templates instead of hard-coded paths:
//!
//! ```ignore
//! use super::routes::ItemDetailRouteTag;
//!
//! html! {
//! a href=(ItemDetailRouteTag::new(item.id).url()) { (item.name) }
//! }
//! ```
//!
//! # Typed query strings
//!
//! [`RouteQueryBuilder`](crate::http::route_tag::RouteQueryBuilder) helpers attach filters
//! to list URLs (sort, page, search):
//!
//! ```ignore
//! ItemListRouteTag::new()
//! .with_query(&[("sort", "name"), ("page", "2")])
//! .url()
//! ```
//!
//! # Handler signature
//!
//! Non-bare handlers receive template/slot context via the default wrapper. Bare handlers
//! are plain Axum functions — see [`super::handlers`].