From 3764f707daa61b0c84325206ac8bf04425fcc9c2 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sat, 26 Feb 2022 21:15:00 +0100 Subject: [PATCH] =?UTF-8?q?A=C3=B1ade=20elecci=C3=B3n=20de=20tema=20espec?= =?UTF-8?q?=C3=ADfico=20por=20p=C3=A1gina?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Característica útil para facilitar que el módulo Admin pueda renderizar sus páginas siempre con el mismo tema, indepedientemente del tema por defecto. También podrá ser decisivo para permitir a los usuarios usar un tema diferente. --- src/base/module/admin/summary.rs | 3 ++ src/core/all.rs | 55 ++++++++++++++++++++++++-- src/core/mod.rs | 5 --- src/core/module/mod.rs | 14 +++++++ src/core/response/page/assets.rs | 18 ++++++++- src/core/response/page/mod.rs | 11 ++++++ src/core/response/page/page.rs | 19 ++++++--- src/core/server/main.rs | 3 +- src/core/state.rs | 67 -------------------------------- src/core/theme/mod.rs | 14 +++++++ src/prelude.rs | 4 +- 11 files changed, 127 insertions(+), 86 deletions(-) delete mode 100644 src/core/state.rs diff --git a/src/base/module/admin/summary.rs b/src/base/module/admin/summary.rs index 6f620fd0..a6fe5e5d 100644 --- a/src/base/module/admin/summary.rs +++ b/src/base/module/admin/summary.rs @@ -32,6 +32,9 @@ pub async fn summary() -> server::Result { .add(MenuItem::label("Opción 4")); Page::prepare() + + .using_theme(&bootsier::BootsierTheme) + .with_title("Admin") .add_to("top-menu", top_menu) diff --git a/src/core/all.rs b/src/core/all.rs index 3fe712b6..3174fc5f 100644 --- a/src/core/all.rs +++ b/src/core/all.rs @@ -1,20 +1,69 @@ -use crate::core::{server, state}; +use crate::Lazy; +use crate::config::SETTINGS; +use crate::core::theme::Theme; +use crate::core::module::Module; +use crate::core::response::page::PageContainer; +use crate::core::server; +use crate::base; + +use std::sync::RwLock; +use std::collections::HashMap; include!(concat!(env!("OUT_DIR"), "/theme.rs")); +// ----------------------------------------------------------------------------- +// Temas registrados y tema por defecto. +// ----------------------------------------------------------------------------- + +pub static THEMES: Lazy>> = Lazy::new(|| { + RwLock::new(vec![ + &base::theme::aliner::AlinerTheme, + &base::theme::minimal::MinimalTheme, + &base::theme::bootsier::BootsierTheme, + ]) +}); + +pub static DEFAULT_THEME: Lazy<&dyn Theme> = Lazy::new(|| { + for t in THEMES.read().unwrap().iter() { + if t.name().to_lowercase() == SETTINGS.app.theme.to_lowercase() { + return *t; + } + } + &base::theme::bootsier::BootsierTheme +}); + pub fn themes(cfg: &mut server::web::ServiceConfig) { cfg.service(actix_web_static_files::ResourceFiles::new( "/theme", assets() )); - for t in state::THEMES.read().unwrap().iter() { + for t in THEMES.read().unwrap().iter() { t.configure_theme(cfg); } } +// ----------------------------------------------------------------------------- +// Módulos registrados. +// ----------------------------------------------------------------------------- + +pub static MODULES: Lazy>> = Lazy::new(|| { + RwLock::new(vec![ + &base::module::admin::AdminModule, + &base::module::user::UserModule, + ]) +}); + pub fn modules(cfg: &mut server::web::ServiceConfig) { - for m in state::MODULES.read().unwrap().iter() { + for m in MODULES.read().unwrap().iter() { m.configure_module(cfg); } } + +// ----------------------------------------------------------------------------- +// Componentes globales. +// ----------------------------------------------------------------------------- + +pub static COMPONENTS: Lazy>> = Lazy::new( + || { RwLock::new(HashMap::new()) } +); diff --git a/src/core/mod.rs b/src/core/mod.rs index de375c10..40530f15 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,10 +1,5 @@ pub use actix_web::dev::Server; -mod state; -pub use state::register_theme; -pub use state::register_module; -pub use state::add_component_to; - mod all; pub mod theme; diff --git a/src/core/module/mod.rs b/src/core/module/mod.rs index a8f85139..c77e530e 100644 --- a/src/core/module/mod.rs +++ b/src/core/module/mod.rs @@ -1,2 +1,16 @@ +use crate::core::all::MODULES; + mod api; pub use api::Module; + +pub fn register_module(m: &'static (dyn Module + 'static)) { + MODULES.write().unwrap().push(m); +} + +pub fn find_module(name: &str) -> Option<&'static (dyn Module + 'static)> { + let modules = MODULES.write().unwrap(); + match modules.iter().find(|t| t.name() == name) { + Some(module) => Some(*module), + _ => None, + } +} diff --git a/src/core/response/page/assets.rs b/src/core/response/page/assets.rs index 8d929f79..c515bb04 100644 --- a/src/core/response/page/assets.rs +++ b/src/core/response/page/assets.rs @@ -1,4 +1,5 @@ -use crate::core::theme::{Markup, PreEscaped, html}; +use crate::core::all::DEFAULT_THEME; +use crate::core::theme::{Markup, PreEscaped, Theme, html}; // ----------------------------------------------------------------------------- // Favicon. @@ -172,6 +173,7 @@ impl JavaScript { // ----------------------------------------------------------------------------- pub struct Assets { + theme : &'static dyn Theme, favicon : Option, metadata : Vec<(String, String)>, stylesheets: Vec, @@ -183,6 +185,7 @@ pub struct Assets { impl Assets { pub fn new() -> Self { Assets { + theme : *DEFAULT_THEME, favicon : None, metadata : Vec::new(), stylesheets: Vec::new(), @@ -192,6 +195,11 @@ impl Assets { } } + pub fn using_theme(&mut self, theme: &'static dyn Theme) -> &mut Self { + self.theme = theme; + self + } + pub fn with_favicon(&mut self, favicon: Favicon) -> &mut Self { self.favicon = Some(favicon); self @@ -238,6 +246,14 @@ impl Assets { self } + /// Assets GETTERS. + + pub fn theme(&mut self) -> &'static dyn Theme { + self.theme + } + + /// Assets RENDER. + pub fn render(&mut self) -> Markup { let ordered_css = &mut self.stylesheets; ordered_css.sort_by_key(|o| o.weight); diff --git a/src/core/response/page/mod.rs b/src/core/response/page/mod.rs index 881e0df3..83f0e0e9 100644 --- a/src/core/response/page/mod.rs +++ b/src/core/response/page/mod.rs @@ -1,3 +1,5 @@ +use crate::core::all::COMPONENTS; + pub mod assets; pub use assets::Assets as PageAssets; @@ -10,3 +12,12 @@ pub use container::Container as PageContainer; mod page; pub use page::Page; pub use page::render_component; + +pub fn add_component_to(region: &'static str, component: impl PageComponent) { + let mut hmap = COMPONENTS.write().unwrap(); + if let Some(regions) = hmap.get_mut(region) { + regions.add(component); + } else { + hmap.insert(region, PageContainer::new_with(component)); + } +} diff --git a/src/core/response/page/page.rs b/src/core/response/page/page.rs index add4c64d..dea08591 100644 --- a/src/core/response/page/page.rs +++ b/src/core/response/page/page.rs @@ -1,7 +1,7 @@ use crate::config::SETTINGS; use crate::core::server; -use crate::core::state::{COMPONENTS, THEME}; -use crate::core::theme::{DOCTYPE, Markup, html}; +use crate::core::all::COMPONENTS; +use crate::core::theme::{DOCTYPE, Markup, Theme, html}; use crate::core::response::page::{PageAssets, PageComponent, PageContainer}; use std::borrow::Cow; @@ -132,13 +132,13 @@ impl<'a> Page<'a> { pub fn render(&mut self) -> server::Result { // Acciones del tema antes de renderizar la página. - THEME.before_render_page(self); + self.assets.theme().before_render_page(self); // Primero, renderizar el cuerpo. - let body = THEME.render_page_body(self); + let body = self.assets.theme().render_page_body(self); // Luego, renderizar la cabecera. - let head = THEME.render_page_head(self); + let head = self.assets.theme().render_page_head(self); // Finalmente, renderizar la página. return Ok(html! { @@ -156,6 +156,13 @@ impl<'a> Page<'a> { None => html! {} } } + + // Page EXTRAS. + + pub fn using_theme(&mut self, theme: &'static dyn Theme) -> &mut Self { + self.assets.using_theme(theme); + self + } } pub fn render_component( @@ -163,7 +170,7 @@ pub fn render_component( assets: &mut PageAssets ) -> Markup { match component.is_renderable() { - true => match THEME.render_component(component, assets) { + true => match assets.theme().render_component(component, assets) { Some(markup) => markup, None => component.default_render(assets) }, diff --git a/src/core/server/main.rs b/src/core/server/main.rs index 8616158e..2c8e2d37 100644 --- a/src/core/server/main.rs +++ b/src/core/server/main.rs @@ -1,6 +1,7 @@ use crate::{base, trace}; use crate::config::SETTINGS; -use crate::core::{Server, all, register_module, server}; +use crate::core::{Server, all, server}; +use crate::core::module::register_module; use tracing_log::LogTracer; use tracing_subscriber::{EnvFilter, Registry}; diff --git a/src/core/state.rs b/src/core/state.rs deleted file mode 100644 index a53d8d80..00000000 --- a/src/core/state.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::Lazy; -use crate::config::SETTINGS; -use crate::core::theme::Theme; -use crate::core::module::Module; -use crate::core::response::page::{PageComponent, PageContainer}; -use crate::base; - -use std::sync::RwLock; -use std::collections::HashMap; - -// ----------------------------------------------------------------------------- -// Temas registrados. -// ----------------------------------------------------------------------------- - -pub static THEMES: Lazy>> = Lazy::new(|| { - RwLock::new(vec![ - &base::theme::aliner::AlinerTheme, - &base::theme::minimal::MinimalTheme, - &base::theme::bootsier::BootsierTheme, - ]) -}); - -pub static THEME: Lazy<&dyn Theme> = Lazy::new(|| { - for t in THEMES.read().unwrap().iter() { - if t.name().to_lowercase() == SETTINGS.app.theme.to_lowercase() { - return *t; - } - } - &base::theme::bootsier::BootsierTheme -}); - -pub fn register_theme(t: &'static (dyn Theme + 'static)) { - THEMES.write().unwrap().push(t); -} - -// ----------------------------------------------------------------------------- -// Módulos registrados. -// ----------------------------------------------------------------------------- - -pub static MODULES: Lazy>> = Lazy::new(|| { - RwLock::new(vec![ - &base::module::admin::AdminModule, - &base::module::user::UserModule, - ]) -}); - -pub fn register_module(m: &'static (dyn Module + 'static)) { - MODULES.write().unwrap().push(m); -} - -// ----------------------------------------------------------------------------- -// Componentes globales. -// ----------------------------------------------------------------------------- - -pub static COMPONENTS: Lazy>> = Lazy::new( - || { RwLock::new(HashMap::new()) } -); - -#[allow(dead_code)] -pub fn add_component_to(region: &'static str, component: impl PageComponent) { - let mut hmap = COMPONENTS.write().unwrap(); - if let Some(regions) = hmap.get_mut(region) { - regions.add(component); - } else { - hmap.insert(region, PageContainer::new_with(component)); - } -} diff --git a/src/core/theme/mod.rs b/src/core/theme/mod.rs index 9b908257..b3376d49 100644 --- a/src/core/theme/mod.rs +++ b/src/core/theme/mod.rs @@ -1,4 +1,18 @@ +use crate::core::all::THEMES; + pub use maud::{DOCTYPE, Markup, PreEscaped, html}; mod api; pub use api::Theme; + +pub fn register_theme(t: &'static (dyn Theme + 'static)) { + THEMES.write().unwrap().push(t); +} + +pub fn find_theme(name: &str) -> Option<&'static (dyn Theme + 'static)> { + let themes = THEMES.write().unwrap(); + match themes.iter().find(|t| t.name() == name) { + Some(theme) => Some(*theme), + _ => None, + } +} diff --git a/src/prelude.rs b/src/prelude.rs index 4a66e08b..1792da41 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -15,8 +15,6 @@ pub use crate::core::response::page::*; pub use crate::core::response::page::assets::*; pub use crate::core::server; -pub use crate::core::register_theme; -pub use crate::core::register_module; -pub use crate::core::add_component_to; +pub use crate::base::theme::*; pub use crate::base::component::*;