Permite a plantillas cambiar atributos de <body>

This commit is contained in:
Manuel Cillero 2026-06-20 20:31:51 +02:00
parent d495c05b96
commit 26f1cda831
2 changed files with 30 additions and 15 deletions

View file

@ -3,7 +3,7 @@ use crate::core::component::{ChildOp, Component, MessageLevel, StatusMessage};
use crate::core::theme::all::DEFAULT_THEME;
use crate::core::theme::{ChildrenInRegions, DefaultRegion, RegionRef, TemplateRef, ThemeRef};
use crate::html::{Assets, Favicon, JavaScript, StyleSheet};
use crate::html::{Markup, RoutePath, html};
use crate::html::{Markup, Props, PropsOp, RoutePath, html};
use crate::locale::L10n;
use crate::locale::{LangId, LanguageIdentifier, RequestLocale};
use crate::web::HttpRequest;
@ -137,6 +137,10 @@ pub trait Contextual: LangId {
#[builder_fn]
fn with_assets(self, op: AssetsOp) -> Self;
/// Modifica identificador, clases CSS o atributos HTML del elemento `<body>`.
#[builder_fn]
fn with_body_props(self, op: PropsOp) -> Self;
/// Añade un componente o aplica una operación [`ChildOp`] en la región por defecto del
/// documento.
#[builder_fn]
@ -206,6 +210,9 @@ pub trait Contextual: LangId {
/// Devuelve los scripts JavaScript de los recursos del contexto.
fn javascripts(&self) -> &Assets<JavaScript>;
/// Devuelve identificador, clases CSS y atributos HTML del elemento `<body>`.
fn body_props(&self) -> &Props;
// **< Contextual HELPERS >*********************************************************************
/// Elimina un parámetro del contexto. Devuelve `true` si la clave existía y se eliminó.
@ -284,6 +291,7 @@ pub struct Context {
favicon : Option<Favicon>, // Favicon, si se ha definido.
stylesheets: Assets<StyleSheet>, // Hojas de estilo CSS.
javascripts: Assets<JavaScript>, // Scripts JavaScript.
body_props : Props, // Identificador, clases CSS y atributos del <body>.
regions : ChildrenInRegions, // Regiones de componentes para renderizar.
params : HashMap<&'static str, (Box<dyn Any>, &'static str)>, // Parámetros en ejecución.
id_counters: RefCell<HashMap<TypeId, usize>>, // RefCell permite mutar desde build_id(&self).
@ -312,6 +320,7 @@ impl Context {
favicon : None,
stylesheets: Assets::<StyleSheet>::new(),
javascripts: Assets::<JavaScript>::new(),
body_props : Props::default(),
regions : ChildrenInRegions::default(),
params : HashMap::default(),
id_counters: RefCell::new(HashMap::new()),
@ -521,6 +530,12 @@ impl Contextual for Context {
self
}
#[builder_fn]
fn with_body_props(mut self, op: PropsOp) -> Self {
self.body_props.alter_prop(op);
self
}
#[builder_fn]
fn with_child(mut self, op: impl Into<ChildOp>) -> Self {
self.regions
@ -570,6 +585,10 @@ impl Contextual for Context {
&self.javascripts
}
fn body_props(&self) -> &Props {
&self.body_props
}
// **< Contextual HELPERS >*********************************************************************
fn remove_param(&mut self, key: &'static str) -> bool {

View file

@ -89,7 +89,6 @@ pub struct Page {
description : Attr<L10n>,
metadata : Vec<(&'static str, &'static str)>,
properties : Vec<(&'static str, &'static str)>,
body_props : Props,
context : Context,
}
@ -105,7 +104,6 @@ impl Page {
description : Attr::<L10n>::default(),
metadata : Vec::default(),
properties : Vec::default(),
body_props : Props::default(),
context : Context::new(Some(request)),
}
}
@ -140,13 +138,6 @@ impl Page {
self
}
/// Modifica identificador, clases CSS o atributos HTML del elemento `<body>`.
#[builder_fn]
pub fn with_body_props(mut self, op: PropsOp) -> Self {
self.body_props.alter_prop(op);
self
}
// **< Page GETTERS >***************************************************************************
/// Devuelve el título traducido para el idioma de la página, si existe.
@ -169,11 +160,6 @@ impl Page {
&self.properties
}
/// Devuelve identificador, clases CSS y atributos HTML del elemento `<body>`.
pub fn body_props(&self) -> &Props {
&self.body_props
}
/// Devuelve una referencia mutable al [`Context`] de la página.
///
/// El [`Context`] actúa como intermediario para muchos métodos de `Page` (idioma, tema,
@ -305,6 +291,12 @@ impl Contextual for Page {
self
}
#[builder_fn]
fn with_body_props(mut self, op: PropsOp) -> Self {
self.context.alter_body_props(op);
self
}
#[builder_fn]
fn with_child(mut self, op: impl Into<ChildOp>) -> Self {
self.context
@ -348,6 +340,10 @@ impl Contextual for Page {
self.context.javascripts()
}
fn body_props(&self) -> &Props {
self.context.body_props()
}
// **< Contextual HELPERS >*********************************************************************
fn remove_param(&mut self, key: &'static str) -> bool {