♻️ (pagetop): Separa handle_component() en 2 métodos

`Theme::handle_component()` se divide en `setup_component()` (síncrono,
muta por tipo con la macro homónima) y `render_component()` (async,
decide el renderizado con su propia macro). Aplica mismo criterio que ya
separa `Component::setup()` de `prepare()`.
This commit is contained in:
Manuel Cillero 2026-09-06 13:07:01 +02:00
parent 1e2d171805
commit 28f1eee391
15 changed files with 185 additions and 170 deletions

View file

@ -7,7 +7,7 @@ use crate::registry;
/// Construye el [`Nav`] en cada petición a partir de [`registry::admin_menu()`], ya filtrado por
/// el usuario de la petición actual. Pensado para que un tema lo registre en su propia región de
/// navegación (p. ej. `pagetop-bootsier` lo añade a su sidebar) e intercepte `Nav`/`nav::Item` en
/// [`Theme::handle_component()`](pagetop::core::theme::Theme::handle_component) si quiere darle un
/// [`Theme::render_component()`](pagetop::core::theme::Theme::render_component) si quiere darle un
/// aspecto propio; sin intercepción, se renderiza con el marcado por defecto de [`Nav`].
///
/// Sólo se renderiza en páginas creadas con

View file

@ -276,7 +276,7 @@ pub fn global() -> &'static AdminRegistry {
/// Pensado para que un tema lo use como navegación de `CoreTemplates::Admin` (p. ej. un sidebar) --
/// ver [`crate::component::AdminMenu`]. `pagetop-admin` no impone ningún marcado propio: el
/// [`Nav`] resultante se renderiza con su aspecto por defecto salvo que el tema lo intercepte en
/// [`Theme::handle_component()`](pagetop::core::theme::Theme::handle_component).
/// [`Theme::render_component()`](pagetop::core::theme::Theme::render_component).
pub fn admin_menu(cx: &Context) -> Nav {
let reg = global();
let current_path = cx.request().map(|r| r.path()).unwrap_or("");

View file

@ -129,11 +129,7 @@ impl Theme for Bootsier {
theme::BootsierColors::from(intent).as_str()
}
async fn handle_component(
&self,
component: &mut dyn Component,
cx: &mut Context,
) -> Option<Result<Markup, ComponentError>> {
fn setup_component(&self, component: &mut dyn Component, _cx: &mut Context) {
setup_component!(component, {
Badge => |c| theme::bs::badge::setup(c),
Brand => |c| theme::bs::brand::setup(c),
@ -148,7 +144,13 @@ impl Theme for Bootsier {
form::select::Field => |c| theme::bs::form::select::setup(c),
form::Textarea => |c| theme::bs::form::textarea::setup(c),
});
}
async fn render_component(
&self,
component: &dyn Component,
cx: &mut Context,
) -> Option<Result<Markup, ComponentError>> {
render_component!(component, {
layout::Region => |c| theme::bs::layout::region::render(c, cx).await?,
layout::Template => |c| theme::bs::layout::template::render(c, cx).await?,

View file

@ -17,7 +17,7 @@
//! la shell completa de AdminLTE 4 (barra superior + barra lateral + área de contenido), que se
//! activa creando la página con [`Page::admin()`](pagetop::response::Page::admin) en lugar de
//! [`Page::new()`](pagetop::response::Page::new). No define sus propias variantes de plantilla:
//! intercepta el componente `Template` en `handle_component()` (ver `bs::layout`).
//! intercepta el componente `Template` en `render_component()` (ver `bs::layout`).
//!
//! ```rust,no_run
//! use pagetop::prelude::*;

View file

@ -9,7 +9,7 @@ pub enum BootsierRegions {
/// Los componentes registrados aquí se renderizan directamente dentro del
/// `<ul class="sidebar-menu">`, sin el `<div>` envolvente que añade
/// [`Region`](pagetop::base::component::layout::Region) por defecto --
/// [`Bootsier`](crate::Bootsier) intercepta este componente en `handle_component()` para
/// [`Bootsier`](crate::Bootsier) intercepta este componente en `render_component()` para
/// renderizarlo así. Los elementos esperados son
/// [`bs::sidebar::Item`](crate::theme::bs::sidebar::Item) y
/// [`bs::sidebar::Section`](crate::theme::bs::sidebar::Section).

View file

@ -17,7 +17,7 @@ use crate::tree::{MenuKey, MenuNode, TreeOptions, build_tree, try_resolve_menu_u
/// </nav>
/// ```
///
/// Los temas pueden sobreescribir el render con `handle_component()`, tanto de `MenuBlock` como,
/// Los temas pueden sobreescribir el render con `render_component()`, tanto de `MenuBlock` como,
/// más generalmente, de [`Nav`]/[`nav::Item`]/[`Dropdown`]/[`dropdown::Item`]. `pagetop-bootsier`
/// ya intercepta `Dropdown` así (ver `theme::bs::dropdown`), y por tanto también los que cuelguen
/// de un `nav::Item::dropdown()`; `MenuBlock`, `Nav` y `Navbar` siguen sin interceptarse: Bootsier