From 970cb3a0b1705bd1572cd337a33aa361281a3730 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sat, 4 Jan 2025 08:37:32 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20A=C3=B1ade=20nuevo=20componente=20R?= =?UTF-8?q?egion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagetop/src/base/component.rs | 3 ++ pagetop/src/base/component/region.rs | 64 +++++++++++++++++++++++++++ pagetop/src/core/component/context.rs | 8 ++-- pagetop/src/core/theme/definition.rs | 8 ++-- pagetop/src/core/theme/regions.rs | 22 +++++---- pagetop/src/response/page.rs | 10 +++-- 6 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 pagetop/src/base/component/region.rs diff --git a/pagetop/src/base/component.rs b/pagetop/src/base/component.rs index 93b22fa1..02d8d521 100644 --- a/pagetop/src/base/component.rs +++ b/pagetop/src/base/component.rs @@ -9,3 +9,6 @@ pub use error403::Error403; mod error404; pub use error404::Error404; + +mod region; +pub use region::Region; diff --git a/pagetop/src/base/component/region.rs b/pagetop/src/base/component/region.rs new file mode 100644 index 00000000..d914c6cc --- /dev/null +++ b/pagetop/src/base/component/region.rs @@ -0,0 +1,64 @@ +use crate::prelude::*; + +#[rustfmt::skip] +#[derive(AutoDefault)] +pub struct Region { + id : OptionId, + classes: OptionClasses, +} + +impl ComponentTrait for Region { + fn new() -> Self { + Region::default() + } + + fn id(&self) -> Option { + self.id.get() + } + + fn setup_before_prepare(&mut self, _cx: &mut Context) { + self.alter_classes(ClassesOp::Prepend, "region-container"); + } + + fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { + let output = if let Some(id) = self.id() { + cx.render_region(id) + } else { + html! {} + }; + if output.is_empty() { + return PrepareMarkup::None; + } + PrepareMarkup::With(html! { + div id=[self.id()] class=[self.classes().get()] { + (output) + } + }) + } +} + +impl Region { + pub fn of(id: impl Into) -> Self { + Region::default().with_id(id) + } + + // Region BUILDER. + + #[fn_builder] + pub fn with_id(mut self, id: impl Into) -> Self { + self.id.alter_value(id); + self + } + + #[fn_builder] + pub fn with_classes(mut self, op: ClassesOp, classes: impl Into) -> Self { + self.classes.alter_value(op, classes); + self + } + + // Region GETTERS. + + fn classes(&self) -> &OptionClasses { + &self.classes + } +} diff --git a/pagetop/src/core/component/context.rs b/pagetop/src/core/component/context.rs index 8f53bf64..5f524264 100644 --- a/pagetop/src/core/component/context.rs +++ b/pagetop/src/core/component/context.rs @@ -115,8 +115,8 @@ impl Context { self } - pub fn alter_in_region(&mut self, region: &'static str, op: ChildOp) -> &mut Self { - self.regions.alter_in_region(region, op); + pub fn alter_in_region(&mut self, region_id: &'static str, op: ChildOp) -> &mut Self { + self.regions.alter_in_region(region_id, op); self } @@ -170,9 +170,9 @@ impl Context { } } - pub fn render_region(&mut self, region: impl Into) -> Markup { + pub fn render_region(&mut self, region_id: impl Into) -> Markup { self.regions - .all_in_region(self.theme, ®ion.into()) + .all_in_region(self.theme, ®ion_id.into()) .render(self) } diff --git a/pagetop/src/core/theme/definition.rs b/pagetop/src/core/theme/definition.rs index f5d6b3bf..43688b2f 100644 --- a/pagetop/src/core/theme/definition.rs +++ b/pagetop/src/core/theme/definition.rs @@ -1,3 +1,5 @@ +use crate::base::component::Region; +use crate::core::component::ComponentBase; use crate::core::package::PackageTrait; use crate::global; use crate::html::{html, Markup}; @@ -9,7 +11,7 @@ pub type ThemeRef = &'static dyn ThemeTrait; /// Los temas deben implementar este "trait". pub trait ThemeTrait: PackageTrait + Send + Sync { fn regions(&self) -> Vec<(&'static str, L10n)> { - vec![("content", L10n::l("content"))] + vec![("region-content", L10n::l("content"))] } #[allow(unused_variables)] @@ -18,8 +20,8 @@ pub trait ThemeTrait: PackageTrait + Send + Sync { fn render_page_body(&self, page: &mut Page) -> Markup { html! { body id=[page.body_id().get()] class=[page.body_classes().get()] { - @for (region_name, _) in self.regions() { - (page.context().render_region(region_name)) + @for (region_id, _) in self.regions() { + (Region::of(region_id).render(page.context())) } } } diff --git a/pagetop/src/core/theme/regions.rs b/pagetop/src/core/theme/regions.rs index d0fec339..acd6c37b 100644 --- a/pagetop/src/core/theme/regions.rs +++ b/pagetop/src/core/theme/regions.rs @@ -19,26 +19,30 @@ impl ChildrenInRegions { ChildrenInRegions::default() } - pub fn with(region: &'static str, child: ChildComponent) -> Self { - ChildrenInRegions::default().with_in_region(region, ChildOp::Add(child)) + pub fn with(region_id: &'static str, child: ChildComponent) -> Self { + ChildrenInRegions::default().with_in_region(region_id, ChildOp::Add(child)) } #[fn_builder] - pub fn with_in_region(mut self, region: &'static str, op: ChildOp) -> Self { - if let Some(region) = self.0.get_mut(region) { + pub fn with_in_region(mut self, region_id: &'static str, op: ChildOp) -> Self { + if let Some(region) = self.0.get_mut(region_id) { region.alter_child(op); } else { - self.0.insert(region, Children::new().with_child(op)); + self.0.insert(region_id, Children::new().with_child(op)); } self } - pub fn all_in_region(&self, theme: ThemeRef, region: &str) -> Children { + pub fn all_in_region(&self, theme: ThemeRef, region_id: &str) -> Children { let common = COMMON_REGIONS.read().unwrap(); if let Some(r) = THEME_REGIONS.read().unwrap().get(&theme.type_id()) { - Children::merge(&[common.0.get(region), self.0.get(region), r.0.get(region)]) + Children::merge(&[ + common.0.get(region_id), + self.0.get(region_id), + r.0.get(region_id), + ]) } else { - Children::merge(&[common.0.get(region), self.0.get(region)]) + Children::merge(&[common.0.get(region_id), self.0.get(region_id)]) } } } @@ -56,7 +60,7 @@ impl InRegion { COMMON_REGIONS .write() .unwrap() - .alter_in_region("content", ChildOp::Add(child)); + .alter_in_region("region-content", ChildOp::Add(child)); } InRegion::Named(name) => { COMMON_REGIONS diff --git a/pagetop/src/response/page.rs b/pagetop/src/response/page.rs index 984bfb2b..7ae2f16c 100644 --- a/pagetop/src/response/page.rs +++ b/pagetop/src/response/page.rs @@ -96,14 +96,16 @@ impl Page { } #[fn_builder] - pub fn with_in_region(mut self, region: &'static str, op: ChildOp) -> Self { - self.context.alter_in_region(region, op); + pub fn with_in_region(mut self, region_id: &'static str, op: ChildOp) -> Self { + self.context.alter_in_region(region_id, op); self } pub fn with_component(mut self, component: impl ComponentTrait) -> Self { - self.context - .alter_in_region("content", ChildOp::Add(ChildComponent::with(component))); + self.context.alter_in_region( + "region-content", + ChildOp::Add(ChildComponent::with(component)), + ); self }