♻️ [theme] Refactoriza renderizado de temas base
This commit is contained in:
parent
0449acfdf4
commit
8f661e98e5
8 changed files with 79 additions and 47 deletions
|
|
@ -104,12 +104,16 @@ impl Extension for Aliner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Theme 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)
|
page.alter_param("include_basic_assets", true)
|
||||||
.alter_assets(ContextOp::AddStyleSheet(
|
.alter_assets(ContextOp::AddStyleSheet(
|
||||||
StyleSheet::from("/aliner/css/styles.css")
|
StyleSheet::from("/aliner/css/styles.css")
|
||||||
.with_version(env!("CARGO_PKG_VERSION"))
|
.with_version(env!("CARGO_PKG_VERSION"))
|
||||||
.with_weight(-90),
|
.with_weight(-90),
|
||||||
));
|
))
|
||||||
|
.alter_child_in(
|
||||||
|
Region::FOOTER,
|
||||||
|
ChildOp::AddIfEmpty(Child::with(PoweredBy::new())),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ impl Extension for Bootsier {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Theme 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(
|
page.alter_assets(ContextOp::AddStyleSheet(
|
||||||
StyleSheet::from("/bootsier/bs/bootstrap.min.css")
|
StyleSheet::from("/bootsier/bs/bootstrap.min.css")
|
||||||
.with_version(BOOTSTRAP_VERSION)
|
.with_version(BOOTSTRAP_VERSION)
|
||||||
|
|
@ -129,4 +129,14 @@ impl Theme for Bootsier {
|
||||||
.with_weight(-90),
|
.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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,17 @@ pub enum IntroOpening {
|
||||||
Custom,
|
Custom,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Componente para presentar PageTop (como [`Welcome`](crate::base::extension::Welcome)), o mostrar
|
/// Componente para divulgar PageTop (como hace [`Welcome`](crate::base::extension::Welcome)), o
|
||||||
/// introducciones.
|
/// 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 **figura decorativa** (que incluye el *monster* de PageTop) antecediendo al contenido.
|
||||||
/// - Una vista destacada con **título + eslogan**.
|
/// - 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.
|
/// - 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
|
/// - Un **área para la presentación de contenidos**, con *badges* informativos de PageTop (si se
|
||||||
/// ([`Block`](crate::base::component::Block)) para crear párrafos vistosos de texto. Aunque
|
/// opta por [`IntroOpening::PageTop`]) y bloques ([`Block`](crate::base::component::Block)) de
|
||||||
/// admite todo tipo de componentes.
|
/// contenido libre para crear párrafos vistosos de texto. Aunque admite todo tipo de componentes.
|
||||||
///
|
///
|
||||||
/// ### Ejemplos
|
/// ### 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
|
/// ```rust
|
||||||
/// # use pagetop::prelude::*;
|
/// # use pagetop::prelude::*;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@ impl Extension for Basic {
|
||||||
|
|
||||||
impl Theme for Basic {
|
impl Theme for Basic {
|
||||||
fn before_render_page_body(&self, page: &mut Page) {
|
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())),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,7 @@ impl<C: Component> Typed<C> {
|
||||||
/// Operaciones para componentes hijo [`Child`] en una lista [`Children`].
|
/// Operaciones para componentes hijo [`Child`] en una lista [`Children`].
|
||||||
pub enum ChildOp {
|
pub enum ChildOp {
|
||||||
Add(Child),
|
Add(Child),
|
||||||
|
AddIfEmpty(Child),
|
||||||
AddMany(Vec<Child>),
|
AddMany(Vec<Child>),
|
||||||
InsertAfterId(&'static str, Child),
|
InsertAfterId(&'static str, Child),
|
||||||
InsertBeforeId(&'static str, Child),
|
InsertBeforeId(&'static str, Child),
|
||||||
|
|
@ -185,6 +186,7 @@ pub enum ChildOp {
|
||||||
/// Operaciones con un componente hijo tipado [`Typed<C>`] en una lista [`Children`].
|
/// Operaciones con un componente hijo tipado [`Typed<C>`] en una lista [`Children`].
|
||||||
pub enum TypedOp<C: Component> {
|
pub enum TypedOp<C: Component> {
|
||||||
Add(Typed<C>),
|
Add(Typed<C>),
|
||||||
|
AddIfEmpty(Typed<C>),
|
||||||
AddMany(Vec<Typed<C>>),
|
AddMany(Vec<Typed<C>>),
|
||||||
InsertAfterId(&'static str, Typed<C>),
|
InsertAfterId(&'static str, Typed<C>),
|
||||||
InsertBeforeId(&'static str, Typed<C>),
|
InsertBeforeId(&'static str, Typed<C>),
|
||||||
|
|
@ -230,6 +232,7 @@ impl Children {
|
||||||
pub fn with_child(mut self, op: ChildOp) -> Self {
|
pub fn with_child(mut self, op: ChildOp) -> Self {
|
||||||
match op {
|
match op {
|
||||||
ChildOp::Add(any) => self.add(any),
|
ChildOp::Add(any) => self.add(any),
|
||||||
|
ChildOp::AddIfEmpty(any) => self.add_if_empty(any),
|
||||||
ChildOp::AddMany(many) => self.add_many(many),
|
ChildOp::AddMany(many) => self.add_many(many),
|
||||||
ChildOp::InsertAfterId(id, any) => self.insert_after_id(id, any),
|
ChildOp::InsertAfterId(id, any) => self.insert_after_id(id, any),
|
||||||
ChildOp::InsertBeforeId(id, any) => self.insert_before_id(id, any),
|
ChildOp::InsertBeforeId(id, any) => self.insert_before_id(id, any),
|
||||||
|
|
@ -246,6 +249,7 @@ impl Children {
|
||||||
pub fn with_typed<C: Component>(mut self, op: TypedOp<C>) -> Self {
|
pub fn with_typed<C: Component>(mut self, op: TypedOp<C>) -> Self {
|
||||||
match op {
|
match op {
|
||||||
TypedOp::Add(typed) => self.add(typed.into()),
|
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::<C>::into)),
|
TypedOp::AddMany(many) => self.add_many(many.into_iter().map(Typed::<C>::into)),
|
||||||
TypedOp::InsertAfterId(id, typed) => self.insert_after_id(id, typed.into()),
|
TypedOp::InsertAfterId(id, typed) => self.insert_after_id(id, typed.into()),
|
||||||
TypedOp::InsertBeforeId(id, typed) => self.insert_before_id(id, typed.into()),
|
TypedOp::InsertBeforeId(id, typed) => self.insert_before_id(id, typed.into()),
|
||||||
|
|
@ -266,6 +270,15 @@ impl Children {
|
||||||
self
|
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 >***********************************************************************
|
// **< Children GETTERS >***********************************************************************
|
||||||
|
|
||||||
/// Devuelve el número de componentes hijo de la lista.
|
/// Devuelve el número de componentes hijo de la lista.
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,33 @@ pub trait Theme: Extension + Send + Sync {
|
||||||
/// - Realizar *tracing* o recopilar métricas.
|
/// - Realizar *tracing* o recopilar métricas.
|
||||||
/// - Aplicar ajustes finales al estado de la página antes de producir el `<head>` o la
|
/// - Aplicar ajustes finales al estado de la página antes de producir el `<head>` o la
|
||||||
/// respuesta final.
|
/// 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)]
|
#[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 `<head>` de la página.
|
||||||
|
///
|
||||||
|
/// Aunque en una página el `<head>` se encuentra antes del `<body>`, 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 (`<meta name="description">`), 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) {
|
if page.param_or("include_basic_assets", false) {
|
||||||
let pkg_version = env!("CARGO_PKG_VERSION");
|
let pkg_version = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
|
@ -108,29 +129,6 @@ pub trait Theme: Extension + Send + Sync {
|
||||||
.with_weight(-99),
|
.with_weight(-99),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Renderiza el contenido del `<head>` de la página.
|
|
||||||
///
|
|
||||||
/// Aunque en una página el `<head>` se encuentra antes del `<body>`, 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 (`<meta name="description">`), 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";
|
let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no";
|
||||||
html! {
|
html! {
|
||||||
meta charset="utf-8";
|
meta charset="utf-8";
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,11 @@ body {
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Page layout */
|
/*
|
||||||
|
* Region Footer
|
||||||
|
*/
|
||||||
|
|
||||||
.region--footer {
|
.region-footer {
|
||||||
padding-bottom: 2rem;
|
padding: .75rem 0 3rem;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Header
|
* Intro Header
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.intro-header {
|
.intro-header {
|
||||||
|
|
@ -125,7 +125,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Content
|
* Intro Content
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.intro-content {
|
.intro-content {
|
||||||
|
|
@ -445,7 +445,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Footer
|
* Intro Footer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.intro-footer {
|
.intro-footer {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue