158 lines
4.5 KiB
Rust
158 lines
4.5 KiB
Rust
/*!
|
|
<div align="center">
|
|
|
|
<h1>PageTop HTMX</h1>
|
|
|
|
<p>Extensión para <strong>PageTop</strong> que integra <a href="https://htmx.org">HTMX</a> para enriquecer las páginas con interacciones dinámicas.</p>
|
|
|
|
[](https://docs.rs/pagetop-htmx)
|
|
[](https://crates.io/crates/pagetop-htmx)
|
|
[](https://crates.io/crates/pagetop-htmx)
|
|
[](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-htmx#licencia)
|
|
|
|
</div>
|
|
|
|
## Sobre PageTop
|
|
|
|
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
|
|
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
|
configurables, basadas en HTML, CSS y JavaScript.
|
|
|
|
## Guía rápida
|
|
|
|
**Añade la dependencia** a tu `Cargo.toml`:
|
|
|
|
```toml
|
|
[dependencies]
|
|
pagetop-htmx = { ... }
|
|
```
|
|
|
|
**Declara la extensión** en tu aplicación (o extensión que la requiera). Recuerda que el orden en
|
|
`dependencies()` determina la prioridad relativa frente a las otras extensiones:
|
|
|
|
```rust
|
|
use pagetop::prelude::*;
|
|
|
|
struct MyApp;
|
|
|
|
#[async_trait]
|
|
impl Extension for MyApp {
|
|
fn dependencies(&self) -> Vec<ExtensionRef> {
|
|
vec![
|
|
// ...
|
|
&pagetop_htmx::Htmx
|
|
// ...
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
A partir de ese momento, todas las páginas de la aplicación incluirán automáticamente el script de
|
|
HTMX 2. Puedes usar los atributos `hx-*` directamente en tus componentes o el código HTML generado:
|
|
|
|
```rust
|
|
use pagetop::prelude::*;
|
|
|
|
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|
Page::new(request)
|
|
.with_child(Html::with(|_| html! {
|
|
button hx-get="/api/hello" hx-target="#result" {
|
|
"Say hello"
|
|
}
|
|
div #result {}
|
|
}))
|
|
.render().await
|
|
}
|
|
```
|
|
|
|
Cuando los valores se construyen en tiempo de ejecución o quieres que una extensión aplique estos
|
|
atributos sin que el componente dependa de HTMX, usa `Props` junto con las constantes de `hx` en
|
|
lugar de escribirlos como literales en `html!`:
|
|
|
|
```rust
|
|
use pagetop::prelude::*;
|
|
use pagetop_htmx::prelude::*;
|
|
|
|
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|
let props = Props::new(hx::GET, "/api/hello")
|
|
.with_prop(PropsOp::set(hx::TARGET, "#result"));
|
|
|
|
Page::new(request)
|
|
.with_child(Html::with(move |_| html! {
|
|
button (props) { "Say hello" }
|
|
div #result {}
|
|
}))
|
|
.render().await
|
|
}
|
|
```
|
|
*/
|
|
|
|
use pagetop::prelude::*;
|
|
|
|
include_locales!(LOCALES_HTMX);
|
|
|
|
pub mod hx;
|
|
pub mod hx_table;
|
|
pub mod request;
|
|
pub mod response;
|
|
|
|
/// Prelude de `pagetop-htmx`.
|
|
pub mod prelude {
|
|
pub use crate::hx;
|
|
pub use crate::hx_table;
|
|
pub use crate::request::HtmxRequestExt;
|
|
pub use crate::response::HtmxResponse;
|
|
}
|
|
|
|
/// Integra HTMX 2 en cualquier aplicación PageTop.
|
|
///
|
|
/// Poner esta extensión en [`dependencies()`](pagetop::core::extension::Extension::dependencies)
|
|
/// hace que todas las páginas de la aplicación incluyan automáticamente el script de HTMX mediante
|
|
/// un atributo [`defer`](pagetop::html::JavaScript::defer). No es necesaria ninguna configuración
|
|
/// adicional.
|
|
///
|
|
/// # Ejemplo
|
|
///
|
|
/// ```rust,no_run
|
|
/// use pagetop::prelude::*;
|
|
///
|
|
/// struct MyApp;
|
|
///
|
|
/// #[async_trait]
|
|
/// impl Extension for MyApp {
|
|
/// fn dependencies(&self) -> Vec<ExtensionRef> {
|
|
/// vec![
|
|
/// // ...
|
|
/// &pagetop_htmx::Htmx
|
|
/// // ...
|
|
/// ]
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
pub struct Htmx;
|
|
|
|
#[async_trait]
|
|
impl Extension for Htmx {
|
|
fn name(&self) -> L10n {
|
|
L10n::t("extension_name", &LOCALES_HTMX)
|
|
}
|
|
|
|
fn description(&self) -> L10n {
|
|
L10n::t("extension_description", &LOCALES_HTMX)
|
|
}
|
|
|
|
fn actions(&self) -> Vec<ActionBox> {
|
|
actions![action::page::BeforeRenderBody::new(add_htmx_script)]
|
|
}
|
|
|
|
fn configure_router(&self, router: Router) -> Router {
|
|
serve_static_files!(router, [htmx] => "/htmx");
|
|
router
|
|
}
|
|
}
|
|
|
|
fn add_htmx_script(page: &mut Page) {
|
|
page.alter_assets(AssetsOp::AddJavaScript(
|
|
JavaScript::defer("/htmx/js/htmx.min.js").with_version("2.0.10"),
|
|
));
|
|
}
|