From d8812433f17618d318160a1ad2a5581b97f102de Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 7 Jun 2023 22:52:20 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Asignaci=C3=B3n=20de=20componentes?= =?UTF-8?q?=20predefinidos=20por=20tema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagetop/src/core/component.rs | 4 --- pagetop/src/core/component/all.rs | 21 ----------- pagetop/src/core/component/bundle.rs | 14 ++++++++ pagetop/src/core/theme.rs | 4 +++ pagetop/src/core/theme/regions.rs | 46 +++++++++++++++++++++++++ pagetop/src/html/maud.rs | 6 ++++ pagetop/src/response/page/definition.rs | 29 +++++++--------- 7 files changed, 83 insertions(+), 41 deletions(-) delete mode 100644 pagetop/src/core/component/all.rs create mode 100644 pagetop/src/core/theme/regions.rs diff --git a/pagetop/src/core/component.rs b/pagetop/src/core/component.rs index 2095ec04..cadd3340 100644 --- a/pagetop/src/core/component.rs +++ b/pagetop/src/core/component.rs @@ -12,9 +12,5 @@ pub use one::OneComponent; mod bundle; pub use bundle::ComponentsBundle; -mod all; -pub use all::add_component_to; -pub(crate) use all::common_components; - mod renderable; pub use renderable::{IsRenderable, Renderable}; diff --git a/pagetop/src/core/component/all.rs b/pagetop/src/core/component/all.rs deleted file mode 100644 index 3ada09b9..00000000 --- a/pagetop/src/core/component/all.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::core::component::{ComponentTrait, ComponentsBundle}; -use crate::LazyStatic; - -use std::collections::HashMap; -use std::sync::RwLock; - -static COMPONENTS: LazyStatic>> = - LazyStatic::new(|| RwLock::new(HashMap::new())); - -pub fn add_component_to(region: &'static str, component: impl ComponentTrait) { - let mut hmap = COMPONENTS.write().unwrap(); - if let Some(regions) = hmap.get_mut(region) { - regions.add(component); - } else { - hmap.insert(region, ComponentsBundle::new_with(component)); - } -} - -pub fn common_components() -> HashMap<&'static str, ComponentsBundle> { - COMPONENTS.read().unwrap().clone() -} diff --git a/pagetop/src/core/component/bundle.rs b/pagetop/src/core/component/bundle.rs index 8b8e3a72..63feee4c 100644 --- a/pagetop/src/core/component/bundle.rs +++ b/pagetop/src/core/component/bundle.rs @@ -17,6 +17,20 @@ impl ComponentsBundle { bundle } + pub(crate) fn merge(one: Option<&ComponentsBundle>, other: Option<&ComponentsBundle>) -> Self { + if let Some(one) = one { + let mut components = one.0.clone(); + if let Some(other) = other { + components.append(&mut other.0.clone()); + } + ComponentsBundle(components) + } else if let Some(other) = other { + ComponentsBundle(other.0.clone()) + } else { + ComponentsBundle::default() + } + } + pub fn add(&mut self, component: impl ComponentTrait) { self.0.push(Arc::new(RwLock::new(component))); } diff --git a/pagetop/src/core/theme.rs b/pagetop/src/core/theme.rs index 67902dcb..696e2407 100644 --- a/pagetop/src/core/theme.rs +++ b/pagetop/src/core/theme.rs @@ -1,4 +1,8 @@ mod definition; pub use definition::{ThemeStaticRef, ThemeTrait}; +mod regions; +pub use regions::add_component_to; +pub(crate) use regions::ComponentsRegions; + pub(crate) mod all; diff --git a/pagetop/src/core/theme/regions.rs b/pagetop/src/core/theme/regions.rs new file mode 100644 index 00000000..8c42d088 --- /dev/null +++ b/pagetop/src/core/theme/regions.rs @@ -0,0 +1,46 @@ +use crate::core::component::{ComponentTrait, ComponentsBundle}; +use crate::LazyStatic; + +use std::collections::HashMap; +use std::sync::RwLock; + +static THEME_REGIONS: LazyStatic>> = + LazyStatic::new(|| RwLock::new(HashMap::new())); + +#[derive(Default)] +pub struct ComponentsRegions(HashMap<&'static str, ComponentsBundle>); + +impl ComponentsRegions { + pub fn new() -> Self { + ComponentsRegions::default() + } + + pub fn add_to(&mut self, region: &'static str, component: impl ComponentTrait) { + if let Some(region) = self.0.get_mut(region) { + region.add(component); + } else { + self.0.insert(region, ComponentsBundle::new_with(component)); + } + } + + pub fn get_extended_bundle(&self, theme: &str, region: &str) -> ComponentsBundle { + if let Some(hm_theme) = THEME_REGIONS.read().unwrap().get(theme) { + ComponentsBundle::merge(self.0.get(region), hm_theme.0.get(region)) + } else { + ComponentsBundle::merge(self.0.get(region), None) + } + } +} + +pub fn add_component_to(theme: &'static str, region: &'static str, component: impl ComponentTrait) { + let mut hm = THEME_REGIONS.write().unwrap(); + if let Some(hm_theme) = hm.get_mut(theme) { + hm_theme.add_to(region, component); + } else { + hm.insert(theme, { + let mut regions = ComponentsRegions::new(); + regions.add_to(region, component); + regions + }); + } +} diff --git a/pagetop/src/html/maud.rs b/pagetop/src/html/maud.rs index 8d2cd12e..801895e5 100644 --- a/pagetop/src/html/maud.rs +++ b/pagetop/src/html/maud.rs @@ -228,6 +228,12 @@ impl> Render for PreEscaped { /// The `html!` macro expands to an expression of this type. pub type Markup = PreEscaped; +impl Markup { + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + impl + Into> PreEscaped { /// Converts the inner value to a string. pub fn into_string(self) -> String { diff --git a/pagetop/src/response/page/definition.rs b/pagetop/src/response/page/definition.rs index ffb6a9a6..4b6b2c94 100644 --- a/pagetop/src/response/page/definition.rs +++ b/pagetop/src/response/page/definition.rs @@ -1,8 +1,7 @@ use crate::base::component::L10n; use crate::core::action::{action_ref, run_actions}; -use crate::core::component::{ - common_components, ComponentTrait, ComponentsBundle, ContextOp, OneComponent, RenderContext, -}; +use crate::core::component::{ComponentTrait, ContextOp, OneComponent, RenderContext}; +use crate::core::theme::ComponentsRegions; use crate::html::{html, Classes, ClassesOp, Favicon, Markup, DOCTYPE}; use crate::locale::{langid_for, LanguageIdentifier}; use crate::response::fatal_error::FatalError; @@ -12,8 +11,6 @@ use crate::{fn_builder, server}; use unic_langid::CharacterDirection; -use std::collections::HashMap; - type PageTitle = OneComponent; type PageDescription = OneComponent; @@ -26,7 +23,7 @@ pub struct Page { favicon : Option, context : RenderContext, body_classes: Classes, - regions : HashMap<&'static str, ComponentsBundle>, + regions : ComponentsRegions, template : String, } @@ -41,7 +38,7 @@ impl Default for Page { favicon : None, context : RenderContext::new(), body_classes: Classes::new().with_value(ClassesOp::SetDefault, "body"), - regions : common_components(), + regions : ComponentsRegions::new(), template : "default".to_owned(), } } @@ -110,12 +107,7 @@ impl Page { region: &'static str, component: impl ComponentTrait, ) -> &mut Self { - if let Some(regions) = self.regions.get_mut(region) { - regions.add(component); - } else { - self.regions - .insert(region, ComponentsBundle::new_with(component)); - } + self.regions.add_to(region, component); self } @@ -196,9 +188,14 @@ impl Page { } pub fn render_region(&mut self, region: &str) -> Option { - match self.regions.get_mut(region) { - Some(components) => Some(components.render(&mut self.context)), - None => None, + let render = self + .regions + .get_extended_bundle(self.context.theme().single_name(), region) + .render(self.context()); + if render.is_empty() { + None + } else { + Some(render) } } }