From a2fe2114cdf04e5c5f95bb148528429515fcb7d9 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sun, 23 Nov 2025 14:35:38 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20(theme):=20Refactoriza=20r?= =?UTF-8?q?enderizado=20de=20temas=20base?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/pagetop-aliner/src/lib.rs | 8 +++- extensions/pagetop-bootsier/src/lib.rs | 12 +++++- src/base/component/intro.rs | 18 ++++----- src/base/theme/basic.rs | 6 ++- src/core/component/children.rs | 13 +++++++ src/core/theme/definition.rs | 54 +++++++++++++------------- static/css/basic.css | 9 +++-- static/css/intro.css | 6 +-- 8 files changed, 79 insertions(+), 47 deletions(-) diff --git a/extensions/pagetop-aliner/src/lib.rs b/extensions/pagetop-aliner/src/lib.rs index 4ae4121e..5e915578 100644 --- a/extensions/pagetop-aliner/src/lib.rs +++ b/extensions/pagetop-aliner/src/lib.rs @@ -104,12 +104,16 @@ impl Extension for Aliner { } impl Theme for Aliner { - fn after_render_page_body(&self, page: &mut Page) { + fn before_render_page_body(&self, page: &mut Page) { page.alter_param("include_basic_assets", true) .alter_assets(ContextOp::AddStyleSheet( StyleSheet::from("/aliner/css/styles.css") .with_version(env!("CARGO_PKG_VERSION")) .with_weight(-90), - )); + )) + .alter_child_in( + Region::FOOTER, + ChildOp::AddIfEmpty(Child::with(PoweredBy::new())), + ); } } diff --git a/extensions/pagetop-bootsier/src/lib.rs b/extensions/pagetop-bootsier/src/lib.rs index 0bf94f47..fb9b7206 100644 --- a/extensions/pagetop-bootsier/src/lib.rs +++ b/extensions/pagetop-bootsier/src/lib.rs @@ -117,7 +117,7 @@ impl Extension for Bootsier { } impl Theme for Bootsier { - fn after_render_page_body(&self, page: &mut Page) { + fn before_render_page_body(&self, page: &mut Page) { page.alter_assets(ContextOp::AddStyleSheet( StyleSheet::from("/bootsier/bs/bootstrap.min.css") .with_version(BOOTSTRAP_VERSION) @@ -129,4 +129,14 @@ impl Theme for Bootsier { .with_weight(-90), )); } + + fn render_page_body(&self, page: &mut Page) -> Markup { + theme::Container::new() + .with_id("container-wrapper") + .with_width(theme::container::Width::FluidMax( + config::SETTINGS.bootsier.max_width, + )) + .add_child(Template::named(page.template())) + .render(page.context()) + } } diff --git a/src/base/component/intro.rs b/src/base/component/intro.rs index 052f9c60..5de7349a 100644 --- a/src/base/component/intro.rs +++ b/src/base/component/intro.rs @@ -17,17 +17,17 @@ pub enum IntroOpening { Custom, } -/// Componente para presentar PageTop (como [`Welcome`](crate::base::extension::Welcome)), o mostrar -/// introducciones. +/// Componente para divulgar PageTop (como hace [`Welcome`](crate::base::extension::Welcome)), o +/// mostrar presentaciones. /// -/// Usa la imagen de PageTop para presentar contenidos con: +/// Usa la imagen de PageTop para mostrar: /// -/// - Una **imagen decorativa** (el *monster* de PageTop) antecediendo al contenido. -/// - Una vista destacada con **título + eslogan**. +/// - Una **figura decorativa** (que incluye el *monster* de PageTop) antecediendo al contenido. +/// - Una vista destacada del **título** de la página con un **eslogan** de presentación. /// - Un **botón opcional** de llamada a la acción con texto y enlace configurables. -/// - El **área de textos** con *badges* predefinidos (en modo [`IntroOpening::PageTop`]) y bloques -/// ([`Block`](crate::base::component::Block)) para crear párrafos vistosos de texto. Aunque -/// admite todo tipo de componentes. +/// - Un **área para la presentación de contenidos**, con *badges* informativos de PageTop (si se +/// opta por [`IntroOpening::PageTop`]) y bloques ([`Block`](crate::base::component::Block)) de +/// contenido libre para crear párrafos vistosos de texto. Aunque admite todo tipo de componentes. /// /// ### Ejemplos /// @@ -51,7 +51,7 @@ pub enum IntroOpening { /// ))); /// ``` /// -/// **Sin botón + modo *Custom* (sin *badges* predefinidos)** +/// **Sin botón y en modo *Custom* (sin *badges* predefinidos)** /// /// ```rust /// # use pagetop::prelude::*; diff --git a/src/base/theme/basic.rs b/src/base/theme/basic.rs index eb2274f6..63ebe7a3 100644 --- a/src/base/theme/basic.rs +++ b/src/base/theme/basic.rs @@ -12,6 +12,10 @@ impl Extension for Basic { impl Theme for Basic { fn before_render_page_body(&self, page: &mut Page) { - page.alter_param("include_basic_assets", true); + page.alter_param("include_basic_assets", true) + .alter_child_in( + Region::FOOTER, + ChildOp::AddIfEmpty(Child::with(PoweredBy::new())), + ); } } diff --git a/src/core/component/children.rs b/src/core/component/children.rs index b3670433..15a6de22 100644 --- a/src/core/component/children.rs +++ b/src/core/component/children.rs @@ -172,6 +172,7 @@ impl Typed { /// Operaciones para componentes hijo [`Child`] en una lista [`Children`]. pub enum ChildOp { Add(Child), + AddIfEmpty(Child), AddMany(Vec), InsertAfterId(&'static str, Child), InsertBeforeId(&'static str, Child), @@ -185,6 +186,7 @@ pub enum ChildOp { /// Operaciones con un componente hijo tipado [`Typed`] en una lista [`Children`]. pub enum TypedOp { Add(Typed), + AddIfEmpty(Typed), AddMany(Vec>), InsertAfterId(&'static str, Typed), InsertBeforeId(&'static str, Typed), @@ -230,6 +232,7 @@ impl Children { pub fn with_child(mut self, op: ChildOp) -> Self { match op { ChildOp::Add(any) => self.add(any), + ChildOp::AddIfEmpty(any) => self.add_if_empty(any), ChildOp::AddMany(many) => self.add_many(many), ChildOp::InsertAfterId(id, any) => self.insert_after_id(id, any), ChildOp::InsertBeforeId(id, any) => self.insert_before_id(id, any), @@ -246,6 +249,7 @@ impl Children { pub fn with_typed(mut self, op: TypedOp) -> Self { match op { TypedOp::Add(typed) => self.add(typed.into()), + TypedOp::AddIfEmpty(typed) => self.add_if_empty(typed.into()), TypedOp::AddMany(many) => self.add_many(many.into_iter().map(Typed::::into)), TypedOp::InsertAfterId(id, typed) => self.insert_after_id(id, typed.into()), TypedOp::InsertBeforeId(id, typed) => self.insert_before_id(id, typed.into()), @@ -266,6 +270,15 @@ impl Children { self } + /// Añade un componente hijo en la lista sólo si está vacía. + #[inline] + pub fn add_if_empty(&mut self, child: Child) -> &mut Self { + if self.0.is_empty() { + self.0.push(child); + } + self + } + // **< Children GETTERS >*********************************************************************** /// Devuelve el número de componentes hijo de la lista. diff --git a/src/core/theme/definition.rs b/src/core/theme/definition.rs index de11d1ba..dda58b18 100644 --- a/src/core/theme/definition.rs +++ b/src/core/theme/definition.rs @@ -83,12 +83,33 @@ pub trait Theme: Extension + Send + Sync { /// - Realizar *tracing* o recopilar métricas. /// - Aplicar ajustes finales al estado de la página antes de producir el `` o la /// respuesta final. - /// - /// La implementación por defecto añade una serie de hojas de estilo básicas (`normalize.css`, - /// `root.css`, `basic.css`) cuando el parámetro `include_basic_assets` de la página está - /// activado. #[allow(unused_variables)] - fn after_render_page_body(&self, page: &mut Page) { + fn after_render_page_body(&self, page: &mut Page) {} + + /// Renderiza el contenido del `` de la página. + /// + /// Aunque en una página el `` se encuentra antes del ``, internamente se renderiza + /// después para contar con los ajustes que hayan ido acumulando los componentes. Por ejemplo, + /// permitiría añadir un archivo de iconos sólo si se ha incluido un icono en la página. + /// + /// Por defecto incluye: + /// + /// - La codificación (`charset="utf-8"`). + /// - El título, usando el título de la página si existe y, en caso contrario, sólo el nombre de + /// la aplicación. + /// - La descripción (``), si está definida. + /// - La etiqueta `viewport` básica para diseño adaptable. + /// - Los metadatos (`name`/`content`) y propiedades (`property`/`content`) declarados en la + /// página. + /// - Los *assets* registrados en el contexto de la página. Si el parámetro + /// `include_basic_assets` está activado, añade de serie las siguientes hojas de estilo + /// básicas: `normalize.css`, `root.css`, `basic.css`, útiles para temas sencillos o de uso + /// general. + /// + /// Los temas pueden sobrescribir este método para añadir etiquetas adicionales (por ejemplo, + /// *favicons* personalizados, manifest, etiquetas de analítica, etc.). + #[inline] + fn render_page_head(&self, page: &mut Page) -> Markup { if page.param_or("include_basic_assets", false) { let pkg_version = env!("CARGO_PKG_VERSION"); @@ -108,29 +129,6 @@ pub trait Theme: Extension + Send + Sync { .with_weight(-99), )); } - } - - /// Renderiza el contenido del `` de la página. - /// - /// Aunque en una página el `` se encuentra antes del ``, internamente se renderiza - /// después para contar con los ajustes que hayan ido acumulando los componentes. Por ejemplo, - /// permitiría añadir un archivo de iconos sólo si se ha incluido un icono en la página. - /// - /// Por defecto incluye: - /// - /// - La codificación (`charset="utf-8"`). - /// - El título, usando el título de la página si existe y, en caso contrario, sólo el nombre de - /// la aplicación. - /// - La descripción (``), si está definida. - /// - La etiqueta `viewport` básica para diseño adaptable. - /// - Los metadatos (`name`/`content`) y propiedades (`property`/`content`) declarados en la - /// página. - /// - Todos los *assets* registrados en el contexto de la página. - /// - /// Los temas pueden sobrescribir este método para añadir etiquetas adicionales (por ejemplo, - /// *favicons* personalizados, manifest, etiquetas de analítica, etc.). - #[inline] - fn render_page_head(&self, page: &mut Page) -> Markup { let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no"; html! { meta charset="utf-8"; diff --git a/static/css/basic.css b/static/css/basic.css index 058e1736..f87e6fdc 100644 --- a/static/css/basic.css +++ b/static/css/basic.css @@ -14,8 +14,11 @@ body { -webkit-tap-highlight-color: transparent; } -/* Page layout */ +/* + * Region Footer + */ -.region--footer { - padding-bottom: 2rem; +.region-footer { + padding: .75rem 0 3rem; + text-align: center; } diff --git a/static/css/intro.css b/static/css/intro.css index dbc72252..9c47c5c4 100644 --- a/static/css/intro.css +++ b/static/css/intro.css @@ -50,7 +50,7 @@ } /* - * Header + * Intro Header */ .intro-header { @@ -125,7 +125,7 @@ } /* - * Content + * Intro Content */ .intro-content { @@ -445,7 +445,7 @@ } /* - * Footer + * Intro Footer */ .intro-footer {