From d0e566aede64683e2d8ccfbe9bd014120aebd278 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 4 May 2022 18:07:56 +0200 Subject: [PATCH] Modifica las extensiones por acciones registradas --- pagetop/src/api/action/all.rs | 27 ++++++++ .../extension.rs => api/action/definition.rs} | 17 +++-- pagetop/src/api/action/holder.rs | 30 +++++++++ pagetop/src/api/action/mod.rs | 19 ++++++ pagetop/src/api/component/action.rs | 55 ++++++++++++++++ pagetop/src/api/component/all.rs | 22 +++++++ .../response/page => api/component}/assets.rs | 2 +- .../page => api/component}/container.rs | 2 +- .../component/definition.rs} | 28 ++++++++- .../response/page => api/component}/mod.rs | 16 +++-- pagetop/src/api/mod.rs | 4 ++ pagetop/src/{core => api}/module/all.rs | 30 +-------- .../src/{core => api}/module/definition.rs | 6 -- pagetop/src/api/module/mod.rs | 10 +++ pagetop/src/{core => api}/theme/all.rs | 0 pagetop/src/{core => api}/theme/definition.rs | 3 +- pagetop/src/{core => api}/theme/mod.rs | 0 pagetop/src/app/application.rs | 2 +- pagetop/src/core/mod.rs | 3 - pagetop/src/core/module/mod.rs | 16 ----- pagetop/src/lib.rs | 4 +- pagetop/src/prelude.rs | 7 ++- pagetop/src/{core => }/response/mod.rs | 0 pagetop/src/response/page/action.rs | 63 +++++++++++++++++++ pagetop/src/response/page/mod.rs | 4 ++ pagetop/src/{core => }/response/page/page.rs | 39 +++--------- 26 files changed, 309 insertions(+), 100 deletions(-) create mode 100644 pagetop/src/api/action/all.rs rename pagetop/src/{core/module/extension.rs => api/action/definition.rs} (59%) create mode 100644 pagetop/src/api/action/holder.rs create mode 100644 pagetop/src/api/action/mod.rs create mode 100644 pagetop/src/api/component/action.rs create mode 100644 pagetop/src/api/component/all.rs rename pagetop/src/{core/response/page => api/component}/assets.rs (99%) rename pagetop/src/{core/response/page => api/component}/container.rs (91%) rename pagetop/src/{core/response/page/component.rs => api/component/definition.rs} (64%) rename pagetop/src/{core/response/page => api/component}/mod.rs (67%) create mode 100644 pagetop/src/api/mod.rs rename pagetop/src/{core => api}/module/all.rs (63%) rename pagetop/src/{core => api}/module/definition.rs (91%) create mode 100644 pagetop/src/api/module/mod.rs rename pagetop/src/{core => api}/theme/all.rs (100%) rename pagetop/src/{core => api}/theme/definition.rs (97%) rename pagetop/src/{core => api}/theme/mod.rs (100%) delete mode 100644 pagetop/src/core/mod.rs delete mode 100644 pagetop/src/core/module/mod.rs rename pagetop/src/{core => }/response/mod.rs (100%) create mode 100644 pagetop/src/response/page/action.rs create mode 100644 pagetop/src/response/page/mod.rs rename pagetop/src/{core => }/response/page/page.rs (82%) diff --git a/pagetop/src/api/action/all.rs b/pagetop/src/api/action/all.rs new file mode 100644 index 00000000..e7a4981f --- /dev/null +++ b/pagetop/src/api/action/all.rs @@ -0,0 +1,27 @@ +use crate::Lazy; +use super::{ActionItem, ActionsHolder, ActionTrait}; + +use std::sync::RwLock; +use std::collections::HashMap; + +// Registered actions. +static ACTIONS: Lazy>> = Lazy::new(|| { + RwLock::new(HashMap::new()) +}); + +pub fn register_action(action: impl ActionTrait) { + let mut hmap = ACTIONS.write().unwrap(); + let action_name = action.type_name(); + if let Some(actions) = hmap.get_mut(action_name) { + actions.add(action); + } else { + hmap.insert(action_name, ActionsHolder::new_with(action)); + } +} + +pub fn run_actions(type_name: &'static str, f: F) where F: FnMut(&ActionItem) -> B { + let hmap = ACTIONS.read().unwrap(); + if let Some(actions) = hmap.get(type_name) { + actions.iter_map(f) + } +} diff --git a/pagetop/src/core/module/extension.rs b/pagetop/src/api/action/definition.rs similarity index 59% rename from pagetop/src/core/module/extension.rs rename to pagetop/src/api/action/definition.rs index e8b8107c..4a813ef9 100644 --- a/pagetop/src/core/module/extension.rs +++ b/pagetop/src/api/action/definition.rs @@ -1,6 +1,8 @@ use crate::util; -pub trait BaseExtension { +pub use std::any::Any as AnyAction; + +pub trait BaseAction { fn type_name(&self) -> &'static str; fn single_name(&self) -> &'static str; @@ -8,14 +10,17 @@ pub trait BaseExtension { fn qualified_name(&self, last: u8) -> &'static str; } -/// Las extensiones deben extender este *trait*. -pub trait ExtensionTrait: BaseExtension + Send + Sync { +pub trait ActionTrait: AnyAction + BaseAction + Send + Sync { + fn new() -> Self where Self: Sized; + fn weight(&self) -> i8 { 0 } + + fn as_ref_any(&self) -> &dyn AnyAction; } -impl BaseExtension for E { +impl BaseAction for C { fn type_name(&self) -> &'static str { std::any::type_name::() } @@ -28,3 +33,7 @@ impl BaseExtension for E { util::partial_type_name(std::any::type_name::(), last) } } + +pub fn action_ref(action: &dyn ActionTrait) -> &A { + action.as_ref_any().downcast_ref::().unwrap() +} diff --git a/pagetop/src/api/action/holder.rs b/pagetop/src/api/action/holder.rs new file mode 100644 index 00000000..c7dd3ef3 --- /dev/null +++ b/pagetop/src/api/action/holder.rs @@ -0,0 +1,30 @@ +use super::ActionTrait; + +use std::sync::{Arc, RwLock}; + +pub type ActionItem = Box; + +#[derive(Clone)] +pub struct ActionsHolder(Arc>>); + +impl ActionsHolder { + pub fn new() -> Self { + ActionsHolder(Arc::new(RwLock::new(Vec::new()))) + } + + pub fn new_with(action: impl ActionTrait) -> Self { + let mut container = ActionsHolder::new(); + container.add(action); + container + } + + pub fn add(&mut self, action: impl ActionTrait) { + let mut actions = self.0.write().unwrap(); + actions.push(Box::new(action)); + actions.sort_by_key(|a| a.weight()); + } + + pub fn iter_map(&self, f: F) where Self: Sized, F: FnMut(&ActionItem) -> B { + let _ = self.0.read().unwrap().iter().map(f); + } +} diff --git a/pagetop/src/api/action/mod.rs b/pagetop/src/api/action/mod.rs new file mode 100644 index 00000000..e28122e0 --- /dev/null +++ b/pagetop/src/api/action/mod.rs @@ -0,0 +1,19 @@ +mod definition; +pub use definition::{ + ActionTrait, + AnyAction, + BaseAction, + action_ref, +}; + +mod holder; +pub use holder::{ + ActionItem, + ActionsHolder, +}; + +mod all; +pub use all::{ + register_action, + run_actions, +}; diff --git a/pagetop/src/api/component/action.rs b/pagetop/src/api/component/action.rs new file mode 100644 index 00000000..2569be85 --- /dev/null +++ b/pagetop/src/api/component/action.rs @@ -0,0 +1,55 @@ +use crate::api::action::{ActionTrait, AnyAction}; +use super::{ComponentTrait, PageAssets}; + +pub enum TypeAction { + BeforeRenderComponent(fn(&mut dyn ComponentTrait, &mut PageAssets)), + None, +} + +pub struct ComponentAction { + action: TypeAction, + weight: i8, +} + +impl ActionTrait for ComponentAction { + fn new() -> Self { + ComponentAction { + action: TypeAction::None, + weight: 0, + } + } + + fn weight(&self) -> i8 { + self.weight + } + + fn as_ref_any(&self) -> &dyn AnyAction { + self + } +} + +impl ComponentAction { + pub fn new(action: TypeAction) -> Self { + ComponentAction { + action, + weight: 0, + } + } + + pub fn new_with_weight(action: TypeAction, weight: i8) -> Self { + ComponentAction { + action, + weight, + } + } + + pub fn before_render_component( + &self, + component: &mut dyn ComponentTrait, + assets: &mut PageAssets) + { + if let TypeAction::BeforeRenderComponent(f) = self.action { + f(component, assets) + } + } +} diff --git a/pagetop/src/api/component/all.rs b/pagetop/src/api/component/all.rs new file mode 100644 index 00000000..6ba66752 --- /dev/null +++ b/pagetop/src/api/component/all.rs @@ -0,0 +1,22 @@ +use crate::Lazy; +use super::{ComponentTrait, PageContainer}; + +use std::sync::RwLock; +use std::collections::HashMap; + +static COMPONENTS: Lazy>> = Lazy::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, PageContainer::new_with(component)); + } +} + +pub fn common_components() -> HashMap<&'static str, PageContainer> { + COMPONENTS.read().unwrap().clone() +} diff --git a/pagetop/src/core/response/page/assets.rs b/pagetop/src/api/component/assets.rs similarity index 99% rename from pagetop/src/core/response/page/assets.rs rename to pagetop/src/api/component/assets.rs index 7eef7b1a..16821ada 100644 --- a/pagetop/src/core/response/page/assets.rs +++ b/pagetop/src/api/component/assets.rs @@ -1,7 +1,7 @@ use crate::{Lazy, base, concat_string}; use crate::config::SETTINGS; use crate::html::{Markup, PreEscaped, html}; -use crate::core::theme::*; +use crate::api::theme::*; static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| { match theme_by_name(&SETTINGS.app.theme) { diff --git a/pagetop/src/core/response/page/container.rs b/pagetop/src/api/component/container.rs similarity index 91% rename from pagetop/src/core/response/page/container.rs rename to pagetop/src/api/component/container.rs index 91c685fd..5ca41056 100644 --- a/pagetop/src/core/response/page/container.rs +++ b/pagetop/src/api/component/container.rs @@ -1,5 +1,5 @@ use crate::html::{Markup, html}; -use crate::core::response::page::{PageAssets, ComponentTrait, render_component}; +use super::{PageAssets, ComponentTrait, render_component}; use std::sync::{Arc, RwLock}; diff --git a/pagetop/src/core/response/page/component.rs b/pagetop/src/api/component/definition.rs similarity index 64% rename from pagetop/src/core/response/page/component.rs rename to pagetop/src/api/component/definition.rs index 0bbc3abf..d32f1b3f 100644 --- a/pagetop/src/core/response/page/component.rs +++ b/pagetop/src/api/component/definition.rs @@ -1,6 +1,8 @@ use crate::html::{Markup, html}; -use crate::core::response::page::PageAssets; use crate::util; +use crate::api::action::{action_ref, run_actions}; +use super::PageAssets; +use super::action::ComponentAction; pub use std::any::Any as AnyComponent; @@ -67,3 +69,27 @@ pub fn component_ref(component: &dyn ComponentTrait) -> &C { pub fn component_mut(component: &mut dyn ComponentTrait) -> &mut C { component.as_mut_any().downcast_mut::().unwrap() } + +pub fn render_component(component: &mut dyn ComponentTrait, assets: &mut PageAssets) -> Markup { + // Acciones del componente antes de renderizar. + component.before_render(assets); + + // Acciones de los módulos antes de renderizar el componente. + run_actions( + "", + |a| action_ref::(&**a).before_render_component(component, assets) + ); + + // Acciones del tema antes de renderizar el componente. + assets.theme().before_render_component(component, assets); + + match component.is_renderable() { + true => { + match assets.theme().render_component(component, assets) { + Some(html) => html, + None => component.default_render(assets) + } + }, + false => html! {} + } +} diff --git a/pagetop/src/core/response/page/mod.rs b/pagetop/src/api/component/mod.rs similarity index 67% rename from pagetop/src/core/response/page/mod.rs rename to pagetop/src/api/component/mod.rs index 01add24f..7c9482c6 100644 --- a/pagetop/src/core/response/page/mod.rs +++ b/pagetop/src/api/component/mod.rs @@ -1,3 +1,5 @@ +pub mod action; + mod assets; pub use assets::{ Favicon, @@ -6,22 +8,24 @@ pub use assets::{ PageAssets, }; -mod component; -pub use component::{ +mod definition; +pub use definition::{ AnyComponent, BaseComponent, ComponentTrait, component_ref, component_mut, }; +use definition::render_component; mod container; pub use container::PageContainer; -mod page; -pub use page::Page; -pub use page::render_component; -pub use page::add_component_to; +mod all; +pub use all::{ + add_component_to, + common_components, +}; pub fn render_always() -> bool { true } diff --git a/pagetop/src/api/mod.rs b/pagetop/src/api/mod.rs new file mode 100644 index 00000000..b69ec91b --- /dev/null +++ b/pagetop/src/api/mod.rs @@ -0,0 +1,4 @@ +pub mod action; // API to define functions that alter the behavior of PageTop core. +pub mod component; // API para crear nuevos componentes. +pub mod module; // API para añadir módulos con nuevas funcionalidades. +pub mod theme; // API para crear temas. diff --git a/pagetop/src/core/module/all.rs b/pagetop/src/api/module/all.rs similarity index 63% rename from pagetop/src/core/module/all.rs rename to pagetop/src/api/module/all.rs index e902c1ec..56e1d6c4 100644 --- a/pagetop/src/core/module/all.rs +++ b/pagetop/src/api/module/all.rs @@ -1,20 +1,14 @@ use crate::{Lazy, app, run_now, trace}; use crate::db::*; -use super::{ExtensionTrait, ModuleTrait}; +use super::ModuleTrait; -use std::sync::{Arc, RwLock}; -use std::collections::HashMap; +use std::sync::RwLock; // Módulos registrados. static MODULES: Lazy>> = Lazy::new(|| { RwLock::new(Vec::new()) }); -// Extensiones registradas. -static EXTENSIONS: Lazy>>>> = Lazy::new(|| { - RwLock::new(HashMap::new()) -}); - pub fn register_module(module: &'static dyn ModuleTrait) { let mut list: Vec<&dyn ModuleTrait> = Vec::new(); add_to(&mut list, module); @@ -28,19 +22,6 @@ fn add_to(list: &mut Vec<&dyn ModuleTrait>, module: &'static dyn ModuleTrait) { trace::debug!("Registering \"{}\" module", module.single_name()); list.push(module); - - let mut hmap = EXTENSIONS.write().unwrap(); - for e in module.extensions().iter() { - if let Some(extensions) = hmap.get_mut(e.type_name()) { - let v = Arc::get_mut(extensions).unwrap(); - v.push(*e); - v.sort_by_key(|e| e.weight()); - } else { - hmap.insert(e.type_name(), Arc::new(vec![*e])); - } - } - - let mut dependencies = module.dependencies(); dependencies.reverse(); for d in dependencies.iter() { @@ -56,13 +37,6 @@ pub fn modules(cfg: &mut app::web::ServiceConfig) { } } -pub fn extensions(type_name: &'static str) -> Option>> { - match EXTENSIONS.read().unwrap().get(type_name) { - Some(extensions) => Some(extensions.clone()), - _ => None, - } -} - #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] pub fn migrations() { run_now({ diff --git a/pagetop/src/core/module/definition.rs b/pagetop/src/api/module/definition.rs similarity index 91% rename from pagetop/src/core/module/definition.rs rename to pagetop/src/api/module/definition.rs index 58a8d4ea..288e99bb 100644 --- a/pagetop/src/core/module/definition.rs +++ b/pagetop/src/api/module/definition.rs @@ -3,8 +3,6 @@ use crate::{app, util}; #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] use crate::db; -use super::ExtensionTrait; - pub trait BaseModule { fn type_name(&self) -> &'static str; @@ -27,10 +25,6 @@ pub trait ModuleTrait: BaseModule + Send + Sync { fn configure_module(&self, cfg: &mut app::web::ServiceConfig) { } - fn extensions(&self) -> Vec<&'static dyn ExtensionTrait> { - vec![] - } - #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[allow(unused_variables)] fn migrations(&self) -> Vec> { diff --git a/pagetop/src/api/module/mod.rs b/pagetop/src/api/module/mod.rs new file mode 100644 index 00000000..d1addefe --- /dev/null +++ b/pagetop/src/api/module/mod.rs @@ -0,0 +1,10 @@ +mod definition; +pub use definition::{ + BaseModule, + ModuleTrait, +}; + +pub(crate) mod all; +pub use all::{ + register_module, +}; diff --git a/pagetop/src/core/theme/all.rs b/pagetop/src/api/theme/all.rs similarity index 100% rename from pagetop/src/core/theme/all.rs rename to pagetop/src/api/theme/all.rs diff --git a/pagetop/src/core/theme/definition.rs b/pagetop/src/api/theme/definition.rs similarity index 97% rename from pagetop/src/core/theme/definition.rs rename to pagetop/src/api/theme/definition.rs index 130dfdac..11551680 100644 --- a/pagetop/src/core/theme/definition.rs +++ b/pagetop/src/api/theme/definition.rs @@ -1,7 +1,8 @@ use crate::{app, concat_string}; use crate::config::SETTINGS; use crate::html::{Markup, html}; -use crate::core::response::page::{ComponentTrait, Favicon, Page, PageAssets}; +use crate::api::component::{ComponentTrait, Favicon, PageAssets}; +use crate::response::page::Page; use crate::base::component::Chunck; use crate::util; diff --git a/pagetop/src/core/theme/mod.rs b/pagetop/src/api/theme/mod.rs similarity index 100% rename from pagetop/src/core/theme/mod.rs rename to pagetop/src/api/theme/mod.rs diff --git a/pagetop/src/app/application.rs b/pagetop/src/app/application.rs index db8af1a6..1b7564ea 100644 --- a/pagetop/src/app/application.rs +++ b/pagetop/src/app/application.rs @@ -1,6 +1,6 @@ use crate::{Lazy, app, base, trace}; use crate::config::SETTINGS; -use crate::core::{module, theme}; +use crate::api::{module, theme}; use std::io::Error; use actix_web::middleware::normalize::{NormalizePath, TrailingSlash}; diff --git a/pagetop/src/core/mod.rs b/pagetop/src/core/mod.rs deleted file mode 100644 index 179f3e12..00000000 --- a/pagetop/src/core/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod module; // API para añadir módulos con nuevas funcionalidades. -pub mod response; // Tipos de respuestas web. -pub mod theme; // Temas predefinidos y API para crear temas. diff --git a/pagetop/src/core/module/mod.rs b/pagetop/src/core/module/mod.rs deleted file mode 100644 index d72bd48d..00000000 --- a/pagetop/src/core/module/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -mod definition; -pub use definition::{ - BaseModule, - ModuleTrait, -}; -mod extension; -pub use extension::{ - BaseExtension, - ExtensionTrait, -}; - -pub(crate) mod all; -pub use all::{ - extensions, - register_module -}; diff --git a/pagetop/src/lib.rs b/pagetop/src/lib.rs index 68c23520..fd843285 100644 --- a/pagetop/src/lib.rs +++ b/pagetop/src/lib.rs @@ -18,7 +18,9 @@ pub mod html; // HTML en código. #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] pub mod db; // Acceso a base de datos. -pub mod core; // APIs para módulos, respuestas web y temas. +pub mod api; // Main APIs for actions, components, modules and themes. + +pub mod response; // Tipos de respuestas web. pub mod app; // Aplicación y servidor web. pub mod base; // Base de componentes, módulos y temas. pub mod util; // Macros y funciones útiles. diff --git a/pagetop/src/prelude.rs b/pagetop/src/prelude.rs index d5190250..079deb63 100644 --- a/pagetop/src/prelude.rs +++ b/pagetop/src/prelude.rs @@ -16,12 +16,15 @@ pub use crate::html::*; #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] pub use crate::{db, db::*, boxed_migration}; -pub use crate::core::{ +pub use crate::api::{ + action::*, + component::*, module::*, - response::page::*, theme::*, }; +pub use crate::response::page::*; + pub use crate::app; pub use crate::app::application::{Application, essence}; diff --git a/pagetop/src/core/response/mod.rs b/pagetop/src/response/mod.rs similarity index 100% rename from pagetop/src/core/response/mod.rs rename to pagetop/src/response/mod.rs diff --git a/pagetop/src/response/page/action.rs b/pagetop/src/response/page/action.rs new file mode 100644 index 00000000..e3173d7f --- /dev/null +++ b/pagetop/src/response/page/action.rs @@ -0,0 +1,63 @@ +use crate::api::action::{ActionTrait, AnyAction}; +use crate::api::component::{ComponentTrait, PageAssets}; +use super::Page; + +pub enum TypeAction { + BeforeRenderPage(fn(&mut Page)), + BeforeRenderComponent(fn(&mut dyn ComponentTrait, &mut PageAssets)), + None, +} + +pub struct PageAction { + action: TypeAction, + weight: i8, +} + +impl ActionTrait for PageAction { + fn new() -> Self { + PageAction { + action: TypeAction::None, + weight: 0, + } + } + + fn weight(&self) -> i8 { + self.weight + } + + fn as_ref_any(&self) -> &dyn AnyAction { + self + } +} + +impl PageAction { + pub fn new(action: TypeAction) -> Self { + PageAction { + action, + weight: 0, + } + } + + pub fn new_with_weight(action: TypeAction, weight: i8) -> Self { + PageAction { + action, + weight, + } + } + + pub fn before_render_page(&self, page: &mut Page) { + if let TypeAction::BeforeRenderPage(f) = self.action { + f(page) + } + } + + pub fn before_render_component( + &self, + component: &mut dyn ComponentTrait, + assets: &mut PageAssets) + { + if let TypeAction::BeforeRenderComponent(f) = self.action { + f(component, assets) + } + } +} diff --git a/pagetop/src/response/page/mod.rs b/pagetop/src/response/page/mod.rs new file mode 100644 index 00000000..097bde8b --- /dev/null +++ b/pagetop/src/response/page/mod.rs @@ -0,0 +1,4 @@ +pub mod action; + +mod page; +pub use page::Page; diff --git a/pagetop/src/core/response/page/page.rs b/pagetop/src/response/page/page.rs similarity index 82% rename from pagetop/src/core/response/page/page.rs rename to pagetop/src/response/page/page.rs index c23ea9c2..b52566a8 100644 --- a/pagetop/src/core/response/page/page.rs +++ b/pagetop/src/response/page/page.rs @@ -1,14 +1,12 @@ use crate::{Lazy, app, trace}; use crate::config::SETTINGS; use crate::html::*; -use crate::core::response::page::*; +use crate::api::action::{action_ref, run_actions}; +use crate::api::component::*; -use std::sync::RwLock; use std::collections::HashMap; -static COMPONENTS: Lazy>> = Lazy::new(|| { - RwLock::new(HashMap::new()) -}); +use super::action::PageAction; static DEFAULT_LANGUAGE: Lazy> = Lazy::new(|| { let language = SETTINGS.app.language[..2].to_lowercase(); @@ -65,7 +63,7 @@ impl<'a> Page<'a> { title : OptAttr::new(), description : OptAttr::new(), assets : PageAssets::new(), - regions : COMPONENTS.read().unwrap().clone(), + regions : common_components(), body_classes: Classes::new_with_default("body"), template : "default".to_owned(), } @@ -153,6 +151,12 @@ impl<'a> Page<'a> { // Page RENDER. pub fn render(&mut self) -> app::Result { + // Acciones de los módulos antes de renderizar el tema. + run_actions( + "", + |a| action_ref::(&**a).before_render_page(self) + ); + // Acciones del tema antes de renderizar la página. self.assets.theme().before_render_page(self); @@ -186,26 +190,3 @@ impl<'a> Page<'a> { self } } - -pub fn render_component(component: &mut dyn ComponentTrait, assets: &mut PageAssets) -> Markup { - component.before_render(assets); - assets.theme().before_render_component(component, assets); - match component.is_renderable() { - true => { - match assets.theme().render_component(component, assets) { - Some(html) => html, - None => component.default_render(assets) - } - }, - false => html! {} - } -} - -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, PageContainer::new_with(component)); - } -}