diff --git a/drust/src/main.rs b/drust/src/main.rs index 6b610c8b..66a8d192 100644 --- a/drust/src/main.rs +++ b/drust/src/main.rs @@ -1,12 +1,18 @@ -use pagetop::prelude::*; +use pagetop::{prelude::*, core::app::AppTrait}; -fn bootstrap() { - include_module(&pagetop_admin::Admin); - include_module(&pagetop_user::User); - include_module(&pagetop_node::Node); +struct Drust; + +impl AppTrait for Drust { + fn enabled_modules(&self) -> Vec<&'static dyn ModuleTrait> { + vec![ + &pagetop_admin::Admin, + &pagetop_user::User, + &pagetop_node::Node, + ] + } } #[actix_web::main] async fn main() -> std::io::Result<()> { - Application::prepare(UsingBootstrap::Fn(bootstrap)).await?.run()?.await + Application::prepare(Drust).await?.run()?.await } diff --git a/pagetop-admin/src/lib.rs b/pagetop-admin/src/lib.rs index d05138b4..d495ecaf 100644 --- a/pagetop-admin/src/lib.rs +++ b/pagetop-admin/src/lib.rs @@ -28,9 +28,9 @@ impl ModuleTrait for Admin { ); } - fn actions(&self) -> Vec { + fn actions(&self) -> Vec { vec![ - action_item!(ActionBeforeRenderPage => before_render_page) + hook_item!(BeforeRenderPageHook => before_render_page) ] } } diff --git a/pagetop-node/src/lib.rs b/pagetop-node/src/lib.rs index 98af01bd..5556fefe 100644 --- a/pagetop-node/src/lib.rs +++ b/pagetop-node/src/lib.rs @@ -26,9 +26,9 @@ impl ModuleTrait for Node { cfg.route("/node", app::web::get().to(node)); } - fn actions(&self) -> Vec { + fn actions(&self) -> Vec { vec![ - action_item!(ActionBeforeRenderPage => before_render_page, -1) + hook_item!(BeforeRenderPageHook => before_render_page, -1) ] } diff --git a/pagetop/src/api/action/definition.rs b/pagetop/src/api/action/definition.rs deleted file mode 100644 index 1c950686..00000000 --- a/pagetop/src/api/action/definition.rs +++ /dev/null @@ -1,17 +0,0 @@ -pub use std::any::Any as AnyAction; - -pub trait ActionTrait: AnyAction + Send + Sync { - fn new() -> Self where Self: Sized; - - fn handler(&self) -> &'static str; - - fn weight(&self) -> isize { - 0 - } - - fn as_ref_any(&self) -> &dyn AnyAction; -} - -pub fn action_ref(action: &dyn ActionTrait) -> &A { - action.as_ref_any().downcast_ref::().unwrap() -} diff --git a/pagetop/src/api/action/mod.rs b/pagetop/src/api/action/mod.rs deleted file mode 100644 index 53e32f8d..00000000 --- a/pagetop/src/api/action/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -mod definition; -pub use definition::{ - ActionTrait, - AnyAction, - action_ref, -}; - -mod holder; -pub use holder::ActionItem; -use holder::ActionsHolder; - -mod all; -pub use all::run_actions; -pub(crate) use all::add_action; diff --git a/pagetop/src/api/component/action.rs b/pagetop/src/api/component/action.rs deleted file mode 100644 index 243646cc..00000000 --- a/pagetop/src/api/component/action.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::api::action::{ActionTrait, AnyAction}; -use super::{Assets, ComponentTrait}; - -pub const BEFORE_RENDER_COMPONENT_ACTION: &str = "pagetop::action::before_render_component"; - -pub struct BeforeRenderComponentAction { - action: Option, - weight: isize, -} - -impl ActionTrait for BeforeRenderComponentAction { - fn new() -> Self { - BeforeRenderComponentAction { - action: None, - weight: 0, - } - } - - fn handler(&self) -> &'static str { - BEFORE_RENDER_COMPONENT_ACTION - } - - fn weight(&self) -> isize { - self.weight - } - - fn as_ref_any(&self) -> &dyn AnyAction { - self - } -} - -impl BeforeRenderComponentAction { - pub fn with_action(mut self, action: fn(&mut dyn ComponentTrait, &mut Assets)) -> Self { - self.action = Some(action); - self - } - - pub fn with_weight(mut self, weight: isize) -> Self { - self.weight = weight; - self - } - - pub fn run(&self, component: &mut dyn ComponentTrait, assets: &mut Assets) { - if let Some(action) = self.action { - action(component, assets) - } - } -} diff --git a/pagetop/src/base/component/form/form.rs b/pagetop/src/base/component/form/form.rs index dcf209b0..189eb0c4 100644 --- a/pagetop/src/base/component/form/form.rs +++ b/pagetop/src/base/component/form/form.rs @@ -95,7 +95,7 @@ impl Form { self } - pub fn with_action(mut self, action: &str) -> Self { + pub fn with_hook(mut self, action: &str) -> Self { self.alter_action(action); self } diff --git a/pagetop/src/app/application.rs b/pagetop/src/core/app/application.rs similarity index 57% rename from pagetop/src/app/application.rs rename to pagetop/src/core/app/application.rs index 6432e265..01af2c5b 100644 --- a/pagetop/src/app/application.rs +++ b/pagetop/src/core/app/application.rs @@ -1,57 +1,63 @@ -use crate::{Lazy, app, base, trace}; +use crate::{Lazy, base, trace}; use crate::config::SETTINGS; -use crate::api::{module, theme}; +use crate::core::{module, theme}; +use super::AppTrait; use std::io::Error; use actix_web::middleware::normalize::{NormalizePath, TrailingSlash}; pub struct Application { - server: app::Server, + server: super::Server, } -pub enum UsingBootstrap {Fn(fn()), No} - impl Application { - pub async fn prepare(bootstrap: UsingBootstrap) -> Result { + pub async fn prepare(brrrz: impl AppTrait) -> Result { // Rótulo de presentación. - app::banner::print_on_startup(); + super::banner::print_on_startup(); // Inicia registro de trazas y eventos. - Lazy::force(&app::tracing::TRACING); + Lazy::force(&super::tracing::TRACING); // Valida el identificador de idioma. - Lazy::force(&app::locale::LANGID); + Lazy::force(&super::locale::LANGID); // Conecta con la base de datos (opcional). #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] - Lazy::force(&app::db::DBCONN); + Lazy::force(&super::db::DBCONN); // Registra los temas predeterminados. - theme::register_theme(&base::theme::aliner::Aliner); - theme::register_theme(&base::theme::minimal::Minimal); - theme::register_theme(&base::theme::bootsier::Bootsier); - theme::register_theme(&base::theme::bulmix::Bulmix); + theme::register_themes(vec![ + &base::theme::aliner::Aliner, + &base::theme::minimal::Minimal, + &base::theme::bootsier::Bootsier, + &base::theme::bulmix::Bulmix, + ]); + theme::register_themes(brrrz.register_themes()); + + // Habilita los módulos predeterminados. + module::enable_modules(brrrz.enabled_modules()); + // Habilita el módulo de presentación de PageTop. + // Normalmente se sobrecargará en la función de inicio. + module::enable_module(&base::module::demopage::Demopage); + + // Registra las acciones de todos los módulos. + module::all::register_hooks(); // Ejecuta la función de inicio de la aplicación. trace::info!("Calling application bootstrap"); + brrrz.bootstrap(); + /* if let UsingBootstrap::Fn(bootstrap) = bootstrap { let _ = &bootstrap(); - } - - // Registra el módulo de presentación de PageTop. - // Normalmente se sobrecargará en la función de inicio. - module::include_module(&base::module::demopage::Demopage); - - // Registra las acciones de todos los módulos. - module::all::register_actions(); + }*/ // Actualizaciones pendientes de la base de datos (opcional). #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] module::all::run_migrations(); // Prepara el servidor web. - let server = app::HttpServer::new(move || { - app::App::new() + let server = super::HttpServer::new(move || { + super::App::new() .wrap(tracing_actix_web::TracingLogger) .wrap(NormalizePath::new(TrailingSlash::Trim)) .configure(&module::all::modules) @@ -66,7 +72,7 @@ impl Application { Ok(Self { server }) } - pub fn run(self) -> Result { + pub fn run(self) -> Result { Ok(self.server) } } diff --git a/pagetop/src/app/banner/mod.rs b/pagetop/src/core/app/banner/mod.rs similarity index 100% rename from pagetop/src/app/banner/mod.rs rename to pagetop/src/core/app/banner/mod.rs diff --git a/pagetop/src/app/banner/slant.flf b/pagetop/src/core/app/banner/slant.flf similarity index 100% rename from pagetop/src/app/banner/slant.flf rename to pagetop/src/core/app/banner/slant.flf diff --git a/pagetop/src/app/banner/small.flf b/pagetop/src/core/app/banner/small.flf similarity index 100% rename from pagetop/src/app/banner/small.flf rename to pagetop/src/core/app/banner/small.flf diff --git a/pagetop/src/app/banner/speed.flf b/pagetop/src/core/app/banner/speed.flf similarity index 100% rename from pagetop/src/app/banner/speed.flf rename to pagetop/src/core/app/banner/speed.flf diff --git a/pagetop/src/app/banner/starwars.flf b/pagetop/src/core/app/banner/starwars.flf similarity index 100% rename from pagetop/src/app/banner/starwars.flf rename to pagetop/src/core/app/banner/starwars.flf diff --git a/pagetop/src/app/db.rs b/pagetop/src/core/app/db.rs similarity index 100% rename from pagetop/src/app/db.rs rename to pagetop/src/core/app/db.rs diff --git a/pagetop/src/core/app/definition.rs b/pagetop/src/core/app/definition.rs new file mode 100644 index 00000000..7c13f9b0 --- /dev/null +++ b/pagetop/src/core/app/definition.rs @@ -0,0 +1,19 @@ +use crate::core::module::ModuleTrait; +use crate::core::theme::ThemeTrait; + +pub trait AppTrait: Send + Sync { + fn bootstrap(&self) { + } + + fn enabled_modules(&self) -> Vec<&'static dyn ModuleTrait> { + vec![] + } + + fn disabled_modules(&self) -> Vec<&'static dyn ModuleTrait> { + vec![] + } + + fn register_themes(&self) -> Vec<&'static dyn ThemeTrait> { + vec![] + } +} diff --git a/pagetop/src/app/locale.rs b/pagetop/src/core/app/locale.rs similarity index 100% rename from pagetop/src/app/locale.rs rename to pagetop/src/core/app/locale.rs diff --git a/pagetop/src/app/mod.rs b/pagetop/src/core/app/mod.rs similarity index 85% rename from pagetop/src/app/mod.rs rename to pagetop/src/core/app/mod.rs index 07404f64..04feaf83 100644 --- a/pagetop/src/app/mod.rs +++ b/pagetop/src/core/app/mod.rs @@ -12,4 +12,7 @@ pub mod locale; #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] pub mod db; +mod definition; +pub use definition::AppTrait; + pub mod application; diff --git a/pagetop/src/app/tracing.rs b/pagetop/src/core/app/tracing.rs similarity index 100% rename from pagetop/src/app/tracing.rs rename to pagetop/src/core/app/tracing.rs diff --git a/pagetop/src/api/component/all.rs b/pagetop/src/core/component/all.rs similarity index 100% rename from pagetop/src/api/component/all.rs rename to pagetop/src/core/component/all.rs diff --git a/pagetop/src/api/component/assets.rs b/pagetop/src/core/component/assets.rs similarity index 99% rename from pagetop/src/api/component/assets.rs rename to pagetop/src/core/component/assets.rs index 1ff78d23..1274348d 100644 --- a/pagetop/src/api/component/assets.rs +++ b/pagetop/src/core/component/assets.rs @@ -1,7 +1,7 @@ use crate::{Lazy, base, concat_string, util}; use crate::config::SETTINGS; use crate::html::{Markup, PreEscaped, html}; -use crate::api::theme::*; +use crate::core::theme::*; static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| { match theme_by_single_name(&SETTINGS.app.theme) { diff --git a/pagetop/src/api/component/definition.rs b/pagetop/src/core/component/definition.rs similarity index 86% rename from pagetop/src/api/component/definition.rs rename to pagetop/src/core/component/definition.rs index 4381b08e..45fa3e91 100644 --- a/pagetop/src/api/component/definition.rs +++ b/pagetop/src/core/component/definition.rs @@ -1,7 +1,7 @@ use crate::util; use crate::html::{Markup, html}; -use crate::api::action::{action_ref, run_actions}; -use super::{BEFORE_RENDER_COMPONENT_ACTION, BeforeRenderComponentAction}; +use crate::core::hook::{hook_ref, run_hooks}; +use super::{BEFORE_RENDER_COMPONENT_HOOK, BeforeRenderComponentHook}; use super::Assets; pub use std::any::Any as AnyComponent; @@ -54,9 +54,9 @@ pub fn render_component(component: &mut dyn ComponentTrait, assets: &mut Assets) component.before_render(assets); // Acciones de los módulos antes de renderizar el componente. - run_actions( - BEFORE_RENDER_COMPONENT_ACTION, - |a| action_ref::(&**a).run(component, assets) + run_hooks( + BEFORE_RENDER_COMPONENT_HOOK, + |a| hook_ref::(&**a).run(component, assets) ); // Acciones del tema antes de renderizar el componente. diff --git a/pagetop/src/api/component/holder.rs b/pagetop/src/core/component/holder.rs similarity index 100% rename from pagetop/src/api/component/holder.rs rename to pagetop/src/core/component/holder.rs diff --git a/pagetop/src/core/component/hook.rs b/pagetop/src/core/component/hook.rs new file mode 100644 index 00000000..a35e09ad --- /dev/null +++ b/pagetop/src/core/component/hook.rs @@ -0,0 +1,48 @@ +use crate::core::hook::{HookTrait, AnyHook}; +use super::{Assets, ComponentTrait}; + +pub const BEFORE_RENDER_COMPONENT_HOOK: &str = "pagetop::action::before_render_component"; + +pub struct BeforeRenderComponentHook { + hook: Option, + weight: isize, +} + +impl HookTrait for BeforeRenderComponentHook { + fn new() -> Self { + BeforeRenderComponentHook { + hook: None, + weight: 0, + } + } + + fn handler(&self) -> &'static str { + BEFORE_RENDER_COMPONENT_HOOK + } + + fn weight(&self) -> isize { + self.weight + } + + fn as_ref_any(&self) -> &dyn AnyHook { + self + } +} + +impl BeforeRenderComponentHook { + pub fn with_hook(mut self, hook: fn(&mut dyn ComponentTrait, &mut Assets)) -> Self { + self.hook = Some(hook); + self + } + + pub fn with_weight(mut self, weight: isize) -> Self { + self.weight = weight; + self + } + + pub fn run(&self, component: &mut dyn ComponentTrait, assets: &mut Assets) { + if let Some(hook) = self.hook { + hook(component, assets) + } + } +} diff --git a/pagetop/src/api/component/mod.rs b/pagetop/src/core/component/mod.rs similarity index 82% rename from pagetop/src/api/component/mod.rs rename to pagetop/src/core/component/mod.rs index a8ee3c4d..1f710deb 100644 --- a/pagetop/src/api/component/mod.rs +++ b/pagetop/src/core/component/mod.rs @@ -1,7 +1,7 @@ -mod action; -pub use action::{ - BEFORE_RENDER_COMPONENT_ACTION, - BeforeRenderComponentAction, +mod hook; +pub use hook::{ + BEFORE_RENDER_COMPONENT_HOOK, + BeforeRenderComponentHook, }; mod assets; diff --git a/pagetop/src/api/action/all.rs b/pagetop/src/core/hook/all.rs similarity index 58% rename from pagetop/src/api/action/all.rs rename to pagetop/src/core/hook/all.rs index cb9bfb8d..2329b251 100644 --- a/pagetop/src/api/action/all.rs +++ b/pagetop/src/core/hook/all.rs @@ -1,25 +1,25 @@ use crate::Lazy; -use super::{ActionItem, ActionsHolder}; +use super::{HookItem, HooksHolder}; use std::sync::RwLock; use std::collections::HashMap; // Registered actions. -static ACTIONS: Lazy>> = Lazy::new(|| { +static ACTIONS: Lazy>> = Lazy::new(|| { RwLock::new(HashMap::new()) }); -pub fn add_action(action: ActionItem) { +pub fn add_hook(action: HookItem) { let mut hmap = ACTIONS.write().unwrap(); let action_handler = action.handler(); if let Some(actions) = hmap.get_mut(action_handler) { actions.add(action); } else { - hmap.insert(action_handler, ActionsHolder::new_with(action)); + hmap.insert(action_handler, HooksHolder::new_with(action)); } } -pub fn run_actions(action_handler: &str, f: F) where F: FnMut(&ActionItem) -> B { +pub fn run_hooks(action_handler: &str, f: F) where F: FnMut(&HookItem) -> B { if let Some(actions) = ACTIONS.read().unwrap().get(action_handler) { actions.iter_map(f) } diff --git a/pagetop/src/core/hook/definition.rs b/pagetop/src/core/hook/definition.rs new file mode 100644 index 00000000..823e830e --- /dev/null +++ b/pagetop/src/core/hook/definition.rs @@ -0,0 +1,17 @@ +pub use std::any::Any as AnyHook; + +pub trait HookTrait: AnyHook + Send + Sync { + fn new() -> Self where Self: Sized; + + fn handler(&self) -> &'static str; + + fn weight(&self) -> isize { + 0 + } + + fn as_ref_any(&self) -> &dyn AnyHook; +} + +pub fn hook_ref(action: &dyn HookTrait) -> &A { + action.as_ref_any().downcast_ref::().unwrap() +} diff --git a/pagetop/src/api/action/holder.rs b/pagetop/src/core/hook/holder.rs similarity index 50% rename from pagetop/src/api/action/holder.rs rename to pagetop/src/core/hook/holder.rs index 7009e103..3cd6d369 100644 --- a/pagetop/src/api/action/holder.rs +++ b/pagetop/src/core/hook/holder.rs @@ -1,36 +1,36 @@ -use super::ActionTrait; +use super::HookTrait; use std::sync::{Arc, RwLock}; -pub type ActionItem = Box; +pub type HookItem = Box; #[macro_export] -macro_rules! action_item { +macro_rules! hook_item { ( $action:ident => $f:ident $(, $weight:expr)? ) => {{ - Box::new($action::new().with_action($f)$(.with_weight($weight))?) + Box::new($action::new().with_hook($f)$(.with_weight($weight))?) }}; } -pub struct ActionsHolder(Arc>>); +pub struct HooksHolder(Arc>>); -impl ActionsHolder { +impl HooksHolder { pub fn new() -> Self { - ActionsHolder(Arc::new(RwLock::new(Vec::new()))) + HooksHolder(Arc::new(RwLock::new(Vec::new()))) } - pub fn new_with(action: ActionItem) -> Self { - let mut container = ActionsHolder::new(); + pub fn new_with(action: HookItem) -> Self { + let mut container = HooksHolder::new(); container.add(action); container } - pub fn add(&mut self, action: ActionItem) { + pub fn add(&mut self, action: HookItem) { let mut actions = self.0.write().unwrap(); actions.push(action); actions.sort_by_key(|a| a.weight()); } - pub fn iter_map(&self, f: F) where Self: Sized, F: FnMut(&ActionItem) -> B { + pub fn iter_map(&self, f: F) where Self: Sized, F: FnMut(&HookItem) -> B { let _: Vec<_> = self.0.read().unwrap().iter().map(f).collect(); } } diff --git a/pagetop/src/core/hook/mod.rs b/pagetop/src/core/hook/mod.rs new file mode 100644 index 00000000..8b83a58d --- /dev/null +++ b/pagetop/src/core/hook/mod.rs @@ -0,0 +1,14 @@ +mod definition; +pub use definition::{ + HookTrait, + AnyHook, + hook_ref, +}; + +mod holder; +pub use holder::HookItem; +use holder::HooksHolder; + +mod all; +pub use all::run_hooks; +pub(crate) use all::add_hook; diff --git a/pagetop/src/api/mod.rs b/pagetop/src/core/mod.rs similarity index 57% rename from pagetop/src/api/mod.rs rename to pagetop/src/core/mod.rs index ff5daff9..e3208027 100644 --- a/pagetop/src/api/mod.rs +++ b/pagetop/src/core/mod.rs @@ -1,4 +1,5 @@ -pub mod action; // API to define functions that alter the behavior of PageTop core. +pub mod app; // API to initialize the PageTop base application. pub mod component; // API to build new components. +pub mod hook; // API to define functions that alter the behavior of PageTop core. pub mod module; // API to add new features with modules. pub mod theme; // API to create themes. diff --git a/pagetop/src/api/module/all.rs b/pagetop/src/core/module/all.rs similarity index 54% rename from pagetop/src/api/module/all.rs rename to pagetop/src/core/module/all.rs index 778dba2e..ac5e8144 100644 --- a/pagetop/src/api/module/all.rs +++ b/pagetop/src/core/module/all.rs @@ -1,26 +1,38 @@ -use crate::{Lazy, app, run_now, trace}; -use crate::api::action::add_action; +use crate::{Lazy, run_now, trace}; +use crate::core::app; +use crate::core::hook::add_hook; use crate::db::*; use super::ModuleTrait; use std::sync::RwLock; -// Módulos registrados. -static MODULES: Lazy>> = Lazy::new(|| { +// Enabled modules. +static ENABLED_MODULES: Lazy>> = Lazy::new(|| { RwLock::new(Vec::new()) }); -pub fn include_module(module: &'static dyn ModuleTrait) { +/* Disabled modules. +static DISABLED_MODULES: Lazy>> = Lazy::new(|| { + RwLock::new(Vec::new()) +}); */ + +pub fn enable_modules(modules: Vec<&'static dyn ModuleTrait>) { + for m in modules { + enable_module(m) + } +} + +pub fn enable_module(module: &'static dyn ModuleTrait) { let mut list: Vec<&dyn ModuleTrait> = Vec::new(); add_to(&mut list, module); list.reverse(); - MODULES.write().unwrap().append(&mut list); + ENABLED_MODULES.write().unwrap().append(&mut list); } fn add_to(list: &mut Vec<&dyn ModuleTrait>, module: &'static dyn ModuleTrait) { - if !MODULES.read().unwrap().iter().any(|m| m.handler() == module.handler()) { + if !ENABLED_MODULES.read().unwrap().iter().any(|m| m.handler() == module.handler()) { if !list.iter().any(|m| m.handler() == module.handler()) { - trace::debug!("Including module \"{}\"", module.single_name()); + trace::debug!("Enabling module \"{}\"", module.single_name()); list.push(module); let mut dependencies = module.dependencies(); @@ -32,16 +44,20 @@ fn add_to(list: &mut Vec<&dyn ModuleTrait>, module: &'static dyn ModuleTrait) { } } +#[allow(unused_variables)] +pub fn disable_module(module: &'static dyn ModuleTrait) { +} + pub fn modules(cfg: &mut app::web::ServiceConfig) { - for m in MODULES.read().unwrap().iter() { + for m in ENABLED_MODULES.read().unwrap().iter() { m.configure_service(cfg); } } -pub fn register_actions() { - for m in MODULES.read().unwrap().iter() { +pub fn register_hooks() { + for m in ENABLED_MODULES.read().unwrap().iter() { for a in m.actions().into_iter() { - add_action(a); + add_hook(a); } } } @@ -53,7 +69,7 @@ pub fn run_migrations() { impl MigratorTrait for Migrator { fn migrations() -> Vec { let mut migrations = vec![]; - for m in MODULES.read().unwrap().iter() { + for m in ENABLED_MODULES.read().unwrap().iter() { migrations.append(&mut m.migrations()); } migrations diff --git a/pagetop/src/api/module/definition.rs b/pagetop/src/core/module/definition.rs similarity index 89% rename from pagetop/src/api/module/definition.rs rename to pagetop/src/core/module/definition.rs index e457e3f0..89904cc0 100644 --- a/pagetop/src/api/module/definition.rs +++ b/pagetop/src/core/module/definition.rs @@ -1,5 +1,6 @@ -use crate::{app, util}; -use crate::api::action::ActionItem; +use crate::util; +use crate::core::app; +use crate::core::hook::HookItem; #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] use crate::db::MigrationItem; @@ -28,7 +29,7 @@ pub trait ModuleTrait: BaseModule + Send + Sync { fn configure_service(&self, cfg: &mut app::web::ServiceConfig) { } - fn actions(&self) -> Vec { + fn actions(&self) -> Vec { vec![] } diff --git a/pagetop/src/api/module/mod.rs b/pagetop/src/core/module/mod.rs similarity index 65% rename from pagetop/src/api/module/mod.rs rename to pagetop/src/core/module/mod.rs index 9c186aea..424595e3 100644 --- a/pagetop/src/api/module/mod.rs +++ b/pagetop/src/core/module/mod.rs @@ -6,5 +6,7 @@ pub use definition::{ pub(crate) mod all; pub use all::{ - include_module, + disable_module, + enable_module, + enable_modules, }; diff --git a/pagetop/src/api/theme/all.rs b/pagetop/src/core/theme/all.rs similarity index 83% rename from pagetop/src/api/theme/all.rs rename to pagetop/src/core/theme/all.rs index c4bb54fe..2a54f578 100644 --- a/pagetop/src/api/theme/all.rs +++ b/pagetop/src/core/theme/all.rs @@ -1,4 +1,5 @@ -use crate::{Lazy, app, theme_static_files, trace}; +use crate::{Lazy, theme_static_files, trace}; +use crate::core::app; use super::ThemeTrait; use std::sync::RwLock; @@ -10,6 +11,12 @@ static THEMES: Lazy>> = Lazy::new(|| { RwLock::new(Vec::new()) }); +pub fn register_themes(themes: Vec<&'static dyn ThemeTrait>) { + for t in themes { + register_theme(t) + } +} + pub fn register_theme(theme: &'static dyn ThemeTrait) { let mut themes = THEMES.write().unwrap(); if !themes.iter().any(|t| t.handler() == theme.handler()) { diff --git a/pagetop/src/api/theme/definition.rs b/pagetop/src/core/theme/definition.rs similarity index 96% rename from pagetop/src/api/theme/definition.rs rename to pagetop/src/core/theme/definition.rs index d5ca1db0..697f52ea 100644 --- a/pagetop/src/api/theme/definition.rs +++ b/pagetop/src/core/theme/definition.rs @@ -1,7 +1,8 @@ -use crate::{app, concat_string, util}; +use crate::{concat_string, util}; use crate::config::SETTINGS; use crate::html::{Markup, html}; -use crate::api::component::{Assets, ComponentTrait, Favicon}; +use crate::core::app; +use crate::core::component::{Assets, ComponentTrait, Favicon}; use crate::response::page::Page; use crate::base::component::Chunck; diff --git a/pagetop/src/api/theme/mod.rs b/pagetop/src/core/theme/mod.rs similarity index 88% rename from pagetop/src/api/theme/mod.rs rename to pagetop/src/core/theme/mod.rs index ccb55a6d..5a4b4060 100644 --- a/pagetop/src/api/theme/mod.rs +++ b/pagetop/src/core/theme/mod.rs @@ -7,5 +7,6 @@ pub use definition::{ pub(crate) mod all; pub use all::{ register_theme, + register_themes, theme_by_single_name, }; diff --git a/pagetop/src/lib.rs b/pagetop/src/lib.rs index 20a25229..64da0481 100644 --- a/pagetop/src/lib.rs +++ b/pagetop/src/lib.rs @@ -18,10 +18,10 @@ 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 api; // Main APIs for actions, components, modules and themes. +pub mod core; // 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 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/locale.rs b/pagetop/src/locale.rs index 93e9e7e8..98e88823 100644 --- a/pagetop/src/locale.rs +++ b/pagetop/src/locale.rs @@ -7,7 +7,7 @@ pub use fluent_templates::fluent_bundle::FluentValue; macro_rules! localize { ( $dir_locales:literal $(, $core_locales:literal)? ) => { use $crate::locale::*; - use $crate::app::locale::LANGID; + use $crate::core::app::locale::LANGID; static_locale! { static LOCALES = { diff --git a/pagetop/src/prelude.rs b/pagetop/src/prelude.rs index 357c31cf..0495bc70 100644 --- a/pagetop/src/prelude.rs +++ b/pagetop/src/prelude.rs @@ -20,17 +20,20 @@ pub use crate::{ migration_item, }; -pub use crate::{action_item, api::{ - action::*, +pub use crate::{hook_item, core::{ +// app::*, component::*, + hook::*, module::*, theme::*, }}; +pub use crate::core::app; +pub use crate::core::app::application::Application; pub use crate::response::page::*; -pub use crate::app; -pub use crate::app::application::{Application, UsingBootstrap}; +//pub use crate::app; +//pub use crate::app::application::{Application, UsingBootstrap}; pub use crate::base::component::*; diff --git a/pagetop/src/response/page/action.rs b/pagetop/src/response/page/action.rs deleted file mode 100644 index 7869987c..00000000 --- a/pagetop/src/response/page/action.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::api::action::{ActionTrait, AnyAction}; -use super::Page; - -pub const BEFORE_RENDER_PAGE_ACTION: &str = "pagetop::action::before_render_page"; - -pub struct ActionBeforeRenderPage { - action: Option, - weight: isize, -} - -impl ActionTrait for ActionBeforeRenderPage { - fn new() -> Self { - ActionBeforeRenderPage { - action: None, - weight: 0, - } - } - - fn handler(&self) -> &'static str { - BEFORE_RENDER_PAGE_ACTION - } - - fn weight(&self) -> isize { - self.weight - } - - fn as_ref_any(&self) -> &dyn AnyAction { - self - } -} - -impl ActionBeforeRenderPage { - pub fn with_action(mut self, action: fn(&mut Page)) -> Self { - self.action = Some(action); - self - } - - pub fn with_weight(mut self, weight: isize) -> Self { - self.weight = weight; - self - } - - pub fn run(&self, page: &mut Page) { - if let Some(action) = self.action { - action(page) - } - } -} diff --git a/pagetop/src/response/page/hook.rs b/pagetop/src/response/page/hook.rs new file mode 100644 index 00000000..e63a189c --- /dev/null +++ b/pagetop/src/response/page/hook.rs @@ -0,0 +1,48 @@ +use crate::core::hook::{HookTrait, AnyHook}; +use super::Page; + +pub const BEFORE_RENDER_PAGE_HOOK: &str = "pagetop::action::before_render_page"; + +pub struct BeforeRenderPageHook { + hook: Option, + weight: isize, +} + +impl HookTrait for BeforeRenderPageHook { + fn new() -> Self { + BeforeRenderPageHook { + hook: None, + weight: 0, + } + } + + fn handler(&self) -> &'static str { + BEFORE_RENDER_PAGE_HOOK + } + + fn weight(&self) -> isize { + self.weight + } + + fn as_ref_any(&self) -> &dyn AnyHook { + self + } +} + +impl BeforeRenderPageHook { + pub fn with_hook(mut self, hook: fn(&mut Page)) -> Self { + self.hook = Some(hook); + self + } + + pub fn with_weight(mut self, weight: isize) -> Self { + self.weight = weight; + self + } + + pub fn run(&self, page: &mut Page) { + if let Some(hook) = self.hook { + hook(page) + } + } +} diff --git a/pagetop/src/response/page/mod.rs b/pagetop/src/response/page/mod.rs index e08e55f0..82c5d7da 100644 --- a/pagetop/src/response/page/mod.rs +++ b/pagetop/src/response/page/mod.rs @@ -1,7 +1,7 @@ -mod action; -pub use action::{ - BEFORE_RENDER_PAGE_ACTION, - ActionBeforeRenderPage, +mod hook; +pub use hook::{ + BEFORE_RENDER_PAGE_HOOK, + BeforeRenderPageHook, }; mod page; diff --git a/pagetop/src/response/page/page.rs b/pagetop/src/response/page/page.rs index a4fc741b..6febf1ac 100644 --- a/pagetop/src/response/page/page.rs +++ b/pagetop/src/response/page/page.rs @@ -1,9 +1,10 @@ -use crate::{Lazy, app, trace}; +use crate::{Lazy, trace}; use crate::config::SETTINGS; use crate::html::*; -use crate::api::action::{action_ref, run_actions}; -use crate::api::component::*; -use super::{BEFORE_RENDER_PAGE_ACTION, ActionBeforeRenderPage}; +use crate::core::app; +use crate::core::hook::{hook_ref, run_hooks}; +use crate::core::component::*; +use super::{BEFORE_RENDER_PAGE_HOOK, BeforeRenderPageHook}; use std::collections::HashMap; @@ -151,9 +152,9 @@ impl<'a> Page<'a> { pub fn render(&mut self) -> app::Result { // Acciones de los módulos antes de renderizar la página. - run_actions( - BEFORE_RENDER_PAGE_ACTION, - |a| action_ref::(&**a).run(self) + run_hooks( + BEFORE_RENDER_PAGE_HOOK, + |a| hook_ref::(&**a).run(self) ); // Acciones del tema antes de renderizar la página.