🧑‍💻 Mejora funcionalidad del componente Html

- Amplía la documentación del componente.
- Aplica la nueva funcionalidad en la página de bienvenida usando el
  nuevo renderizado dinámico con contexto.
- Añade pruebas unitarias para el componente.
This commit is contained in:
Manuel Cillero 2025-08-02 20:26:39 +02:00
parent 3a3e3b810f
commit ef8d16f41f
7 changed files with 155 additions and 27 deletions

View file

@ -1,28 +1,76 @@
use crate::prelude::*;
/// Componente básico para renderizar directamente código HTML.
#[derive(AutoDefault)]
pub struct Html(Markup);
/// Componente básico para renderizar dinámicamente código HTML recibiendo el contexto.
///
/// Este componente permite generar contenido HTML arbitrario, usando la macro `html!` y accediendo
/// opcionalmente al contexto de renderizado.
///
/// # Ejemplo
///
/// ```rust
/// use pagetop::prelude::*;
///
/// let component = Html::with(|_| {
/// html! {
/// div class="example" {
/// p { "Hello from PageTop." }
/// }
/// }
/// });
/// ```
///
/// Para renderizar contenido que dependa del contexto, se puede acceder a él dentro del *closure*:
///
/// ```rust
/// use pagetop::prelude::*;
///
/// let component = Html::with(|cx| {
/// let user = cx.get_param::<String>("username").unwrap_or(String::from("visitor"));
/// html! {
/// h1 { "Hello, " (user) }
/// }
/// });
/// ```
pub struct Html(Box<dyn Fn(&mut Context) -> Markup + Send + Sync>);
impl Default for Html {
fn default() -> Self {
Html::with(|_| html! {})
}
}
impl ComponentTrait for Html {
fn new() -> Self {
Html::default()
}
fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup {
PrepareMarkup::With(html! { (self.0) })
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
PrepareMarkup::With((self.0)(cx))
}
}
impl Html {
/// Crear una instancia con el código HTML del argumento.
pub fn with(html: Markup) -> Self {
Html(html)
/// Crea una instancia que generará el `Markup`, con acceso opcional al contexto.
///
/// El método [`prepare_component`](crate::core::component::ComponentTrait::prepare_component)
/// delega el renderizado en la función proporcionada, que recibe una referencia mutable
/// al contexto de renderizado ([`Context`]).
pub fn with<F>(f: F) -> Self
where
F: Fn(&mut Context) -> Markup + Send + Sync + 'static,
{
Html(Box::new(f))
}
/// Modifica el código HTML de la instancia con el nuevo código del argumento.
pub fn alter_html(&mut self, html: Markup) -> &mut Self {
self.0 = html;
/// Sustituye la función que genera el `Markup`.
///
/// Permite a otras extensiones modificar la función de renderizado que se ejecutará cuando
/// [`prepare_component`](crate::core::component::ComponentTrait::prepare_component) invoque
/// esta instancia. La nueva función también recibe una referencia al contexto ([`Context`]).
pub fn alter_html<F>(&mut self, f: F) -> &mut Self
where
F: Fn(&mut Context) -> Markup + Send + Sync + 'static,
{
self.0 = Box::new(f);
self
}
}