diff --git a/pagetop/src/base.rs b/pagetop/src/base.rs index acfd1dbe..49ae12b4 100644 --- a/pagetop/src/base.rs +++ b/pagetop/src/base.rs @@ -1,5 +1,5 @@ -pub mod action; +pub mod actions; -pub mod component; +pub mod components; -pub mod theme; +pub mod themes; diff --git a/pagetop/src/base/action.rs b/pagetop/src/base/actions.rs similarity index 65% rename from pagetop/src/base/action.rs rename to pagetop/src/base/actions.rs index de26ffe3..3764ff1e 100644 --- a/pagetop/src/base/action.rs +++ b/pagetop/src/base/actions.rs @@ -1,3 +1,7 @@ mod before_prepare_component; mod after_prepare_component; + +pub mod block; + +pub mod page; diff --git a/pagetop/src/base/action/after_prepare_component.rs b/pagetop/src/base/actions/after_prepare_component.rs similarity index 90% rename from pagetop/src/base/action/after_prepare_component.rs rename to pagetop/src/base/actions/after_prepare_component.rs index 44a9a4d5..00f9cdb1 100644 --- a/pagetop/src/base/action/after_prepare_component.rs +++ b/pagetop/src/base/actions/after_prepare_component.rs @@ -4,10 +4,10 @@ macro_rules! action_after_prepare_component { $crate::paste! { $crate::use_handle!($ACTION_HANDLE); - type Action = fn(&$Component, &mut RenderContext); + pub type ActionAfter = fn(component: &$Component, rcx: &mut RenderContext); pub struct [] { - action: Option, + action: Option, weight: isize, } @@ -34,7 +34,7 @@ macro_rules! action_after_prepare_component { impl [] { #[allow(dead_code)] - pub fn with_action(mut self, action: Action) -> Self { + pub fn with_action(mut self, action: ActionAfter) -> Self { self.action = Some(action); self } diff --git a/pagetop/src/base/action/before_prepare_component.rs b/pagetop/src/base/actions/before_prepare_component.rs similarity index 89% rename from pagetop/src/base/action/before_prepare_component.rs rename to pagetop/src/base/actions/before_prepare_component.rs index e0ed8eee..29e435dc 100644 --- a/pagetop/src/base/action/before_prepare_component.rs +++ b/pagetop/src/base/actions/before_prepare_component.rs @@ -4,10 +4,10 @@ macro_rules! action_before_prepare_component { $crate::paste! { $crate::use_handle!($ACTION_HANDLE); - type Action = fn(&$Component, &mut RenderContext); + pub type ActionBefore = fn(component: &$Component, rcx: &mut RenderContext); pub struct [] { - action: Option, + action: Option, weight: isize, } @@ -34,7 +34,7 @@ macro_rules! action_before_prepare_component { impl [] { #[allow(dead_code)] - pub fn with_action(mut self, action: Action) -> Self { + pub fn with_action(mut self, action: ActionBefore) -> Self { self.action = Some(action); self } diff --git a/pagetop/src/base/actions/block.rs b/pagetop/src/base/actions/block.rs new file mode 100644 index 00000000..25b364ad --- /dev/null +++ b/pagetop/src/base/actions/block.rs @@ -0,0 +1,8 @@ +use crate::prelude::*; + +action_before_prepare_component!( + ACTION_BEFORE_PREPARE_BLOCK for Block +); +action_after_prepare_component!( + ACTION_AFTER_PREPARE_BLOCK for Block +); diff --git a/pagetop/src/base/actions/page.rs b/pagetop/src/base/actions/page.rs new file mode 100644 index 00000000..20e55a3a --- /dev/null +++ b/pagetop/src/base/actions/page.rs @@ -0,0 +1,13 @@ +use crate::prelude::*; + +pub type ActionPage = fn(page: &mut Page); + +mod before_prepare_page; +pub use before_prepare_page::{ + run_actions_before_prepare_page, ActionBeforePreparePage, ACTION_BEFORE_PREPARE_PAGE, +}; + +mod before_render_page; +pub use before_render_page::{ + run_actions_before_render_page, ActionBeforeRenderPage, ACTION_BEFORE_RENDER_PAGE, +}; diff --git a/pagetop/src/response/page/before_prepare_page.rs b/pagetop/src/base/actions/page/before_prepare_page.rs similarity index 69% rename from pagetop/src/response/page/before_prepare_page.rs rename to pagetop/src/base/actions/page/before_prepare_page.rs index e246738a..13fdd909 100644 --- a/pagetop/src/response/page/before_prepare_page.rs +++ b/pagetop/src/base/actions/page/before_prepare_page.rs @@ -1,13 +1,11 @@ -use crate::core::action::{ActionTrait, AnyAction}; -use crate::response::page::Page; -use crate::{use_handle, Handle}; +use crate::prelude::*; + +use super::ActionPage; use_handle!(ACTION_BEFORE_PREPARE_PAGE); -type Action = fn(&mut Page); - pub struct ActionBeforePreparePage { - action: Option, + action: Option, weight: isize, } @@ -33,7 +31,7 @@ impl ActionTrait for ActionBeforePreparePage { } impl ActionBeforePreparePage { - pub fn with_action(mut self, action: Action) -> Self { + pub fn with_action(mut self, action: ActionPage) -> Self { self.action = Some(action); self } @@ -49,3 +47,10 @@ impl ActionBeforePreparePage { } } } + +#[inline(always)] +pub fn run_actions_before_prepare_page(page: &mut Page) { + run_actions(ACTION_BEFORE_PREPARE_PAGE, |action| { + action_ref::(&**action).run(page) + }); +} diff --git a/pagetop/src/response/page/before_render_page.rs b/pagetop/src/base/actions/page/before_render_page.rs similarity index 69% rename from pagetop/src/response/page/before_render_page.rs rename to pagetop/src/base/actions/page/before_render_page.rs index 216d018d..d035d2d8 100644 --- a/pagetop/src/response/page/before_render_page.rs +++ b/pagetop/src/base/actions/page/before_render_page.rs @@ -1,13 +1,11 @@ -use crate::core::action::{ActionTrait, AnyAction}; -use crate::response::page::Page; -use crate::{use_handle, Handle}; +use crate::prelude::*; + +use super::ActionPage; use_handle!(ACTION_BEFORE_RENDER_PAGE); -type Action = fn(&mut Page); - pub struct ActionBeforeRenderPage { - action: Option, + action: Option, weight: isize, } @@ -33,7 +31,7 @@ impl ActionTrait for ActionBeforeRenderPage { } impl ActionBeforeRenderPage { - pub fn with_action(mut self, action: Action) -> Self { + pub fn with_action(mut self, action: ActionPage) -> Self { self.action = Some(action); self } @@ -49,3 +47,10 @@ impl ActionBeforeRenderPage { } } } + +#[inline(always)] +pub fn run_actions_before_render_page(page: &mut Page) { + run_actions(ACTION_BEFORE_RENDER_PAGE, |action| { + action_ref::(&**action).run(page) + }); +} diff --git a/pagetop/src/base/component.rs b/pagetop/src/base/components.rs similarity index 100% rename from pagetop/src/base/component.rs rename to pagetop/src/base/components.rs diff --git a/pagetop/src/base/component/block.rs b/pagetop/src/base/components/block.rs similarity index 93% rename from pagetop/src/base/component/block.rs rename to pagetop/src/base/components/block.rs index 78cd707d..1f443e95 100644 --- a/pagetop/src/base/component/block.rs +++ b/pagetop/src/base/components/block.rs @@ -2,8 +2,6 @@ use crate::prelude::*; use_handle!(COMPONENT_BLOCK); -action_before_prepare_component!(ACTION_BEFORE_PREPARE_BLOCK for Block); - #[rustfmt::skip] #[derive(Default)] pub struct Block { @@ -38,7 +36,7 @@ impl ComponentTrait for Block { } fn before_prepare_component(&mut self, rcx: &mut RenderContext) { - run_actions_before_prepare_component(self, rcx); + actions::block::run_actions_before_prepare_component(self, rcx); } fn prepare_component(&self, rcx: &mut RenderContext) -> PrepareMarkup { @@ -55,6 +53,10 @@ impl ComponentTrait for Block { }) } + fn after_prepare_component(&mut self, rcx: &mut RenderContext) { + actions::block::run_actions_after_prepare_component(self, rcx); + } + fn as_ref_any(&self) -> &dyn AnyComponent { self } diff --git a/pagetop/src/base/component/html.rs b/pagetop/src/base/components/html.rs similarity index 100% rename from pagetop/src/base/component/html.rs rename to pagetop/src/base/components/html.rs diff --git a/pagetop/src/base/component/l10n.rs b/pagetop/src/base/components/l10n.rs similarity index 100% rename from pagetop/src/base/component/l10n.rs rename to pagetop/src/base/components/l10n.rs diff --git a/pagetop/src/base/theme.rs b/pagetop/src/base/theme.rs deleted file mode 100644 index c135c08d..00000000 --- a/pagetop/src/base/theme.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod basic; -pub(crate) use basic::Basic; diff --git a/pagetop/src/base/themes.rs b/pagetop/src/base/themes.rs new file mode 100644 index 00000000..3a192746 --- /dev/null +++ b/pagetop/src/base/themes.rs @@ -0,0 +1,2 @@ +mod basic; +pub use basic::Basic; diff --git a/pagetop/src/base/theme/basic.rs b/pagetop/src/base/themes/basic.rs similarity index 100% rename from pagetop/src/base/theme/basic.rs rename to pagetop/src/base/themes/basic.rs diff --git a/pagetop/src/core/action/all.rs b/pagetop/src/core/action/all.rs index 9737d98c..6273c2e7 100644 --- a/pagetop/src/core/action/all.rs +++ b/pagetop/src/core/action/all.rs @@ -11,8 +11,8 @@ static ACTIONS: LazyStatic>> = pub fn add_action(action: Action) { let mut actions = ACTIONS.write().unwrap(); let action_handle = action.handle(); - if let Some(bundle) = actions.get_mut(&action_handle) { - bundle.add(action); + if let Some(list) = actions.get_mut(&action_handle) { + list.add(action); } else { actions.insert(action_handle, ActionsList::new_with(action)); } @@ -22,7 +22,7 @@ pub fn run_actions(action_handle: Handle, f: F) where F: FnMut(&Action) -> B, { - if let Some(bundle) = ACTIONS.read().unwrap().get(&action_handle) { - bundle.iter_map(f) + if let Some(list) = ACTIONS.read().unwrap().get(&action_handle) { + list.iter_map(f) } } diff --git a/pagetop/src/core/action/list.rs b/pagetop/src/core/action/list.rs index 699c76b4..99ea1887 100644 --- a/pagetop/src/core/action/list.rs +++ b/pagetop/src/core/action/list.rs @@ -6,8 +6,8 @@ pub type Action = Box; #[macro_export] macro_rules! action { - ( $action:ident => $f:ident $(, $weight:expr)? ) => {{ - Box::new($action::new().with_action($f)$(.with_weight($weight))?) + ( $action:ty => $f:ident $(, $weight:expr)? ) => {{ + Box::new(<$action>::new().with_action($f)$(.with_weight($weight))?) }}; } @@ -19,15 +19,15 @@ impl ActionsList { } pub fn new_with(action: Action) -> Self { - let mut bundle = ActionsList::new(); - bundle.add(action); - bundle + let mut list = ActionsList::new(); + list.add(action); + list } pub fn add(&mut self, action: Action) { - let mut bundle = self.0.write().unwrap(); - bundle.push(action); - bundle.sort_by_key(|a| a.weight()); + let mut list = self.0.write().unwrap(); + list.push(action); + list.sort_by_key(|a| a.weight()); } pub fn iter_map(&self, f: F) diff --git a/pagetop/src/core/component/context.rs b/pagetop/src/core/component/context.rs index f95da247..39f1a356 100644 --- a/pagetop/src/core/component/context.rs +++ b/pagetop/src/core/component/context.rs @@ -10,7 +10,7 @@ use std::str::FromStr; static THEME: LazyStatic = LazyStatic::new(|| match theme_by_single_name(&config::SETTINGS.app.theme) { Some(theme) => theme, - None => &crate::base::theme::Basic, + None => &crate::base::themes::Basic, }); pub enum ContextOp { diff --git a/pagetop/src/core/component/pack.rs b/pagetop/src/core/component/pack.rs index 4da60920..d50d7d14 100644 --- a/pagetop/src/core/component/pack.rs +++ b/pagetop/src/core/component/pack.rs @@ -25,9 +25,9 @@ impl PackComponents { } pub fn new_with(component: impl ComponentTrait) -> Self { - let mut bundle = PackComponents::new(); - bundle.alter_pack(PackOp::Add, component); - bundle + let mut pack = PackComponents::new(); + pack.alter_pack(PackOp::Add, component); + pack } pub(crate) fn merge(one: Option<&PackComponents>, other: Option<&PackComponents>) -> Self { diff --git a/pagetop/src/core/module/all.rs b/pagetop/src/core/module/all.rs index 428fbfc4..b5db24c8 100644 --- a/pagetop/src/core/module/all.rs +++ b/pagetop/src/core/module/all.rs @@ -28,7 +28,7 @@ pub fn register_modules(app: ModuleStaticRef) { let mut list: Vec = Vec::new(); // Enable basic theme. - add_to_enabled(&mut list, &crate::base::theme::Basic); + add_to_enabled(&mut list, &crate::base::themes::Basic); // Enable application modules. add_to_enabled(&mut list, app); diff --git a/pagetop/src/core/module/definition.rs b/pagetop/src/core/module/definition.rs index 5b1057f9..21aabba2 100644 --- a/pagetop/src/core/module/definition.rs +++ b/pagetop/src/core/module/definition.rs @@ -1,4 +1,4 @@ -use crate::base::component::L10n; +use crate::base::components::L10n; use crate::core::action::Action; use crate::core::theme::ThemeStaticRef; use crate::{service, util, Handle}; diff --git a/pagetop/src/core/theme/definition.rs b/pagetop/src/core/theme/definition.rs index 47c921a8..b801f3c8 100644 --- a/pagetop/src/core/theme/definition.rs +++ b/pagetop/src/core/theme/definition.rs @@ -1,4 +1,4 @@ -use crate::base::component::L10n; +use crate::base::components::L10n; use crate::core::component::{ComponentTrait, RenderContext}; use crate::core::module::ModuleTrait; use crate::html::{html, Favicon, Markup}; diff --git a/pagetop/src/locale.rs b/pagetop/src/locale.rs index e755a196..bec587f3 100644 --- a/pagetop/src/locale.rs +++ b/pagetop/src/locale.rs @@ -87,7 +87,7 @@ //! use_locale!(LOCALE_SAMPLE["path/to/locale"]); //! ``` //! -//! Usa el componente [L10n](crate::base::component::L10n) para incluir textos y contenidos +//! Usa el componente [L10n](crate::base::components::L10n) para incluir textos y contenidos //! opcionalmente traducibles segĂșn el contexto de renderizado. use crate::{args, config, trace, LazyStatic}; diff --git a/pagetop/src/prelude.rs b/pagetop/src/prelude.rs index ae67e289..c2039bf2 100644 --- a/pagetop/src/prelude.rs +++ b/pagetop/src/prelude.rs @@ -32,7 +32,9 @@ pub use crate::core::{action::*, component::*, module::*, theme::*}; pub use crate::{action, action_after_prepare_component, action_before_prepare_component}; -pub use crate::base::component::*; +pub use crate::base::actions; +pub use crate::base::components::*; +pub use crate::base::themes; pub use crate::service; pub use crate::service::HttpMessage; diff --git a/pagetop/src/response/fatal_error.rs b/pagetop/src/response/fatal_error.rs index 3994b91c..cf22a205 100644 --- a/pagetop/src/response/fatal_error.rs +++ b/pagetop/src/response/fatal_error.rs @@ -3,7 +3,7 @@ pub use error403::ERROR_403; mod error404; pub use error404::ERROR_404; -use crate::base::component::L10n; +use crate::base::components::L10n; use crate::response::{page::Page, ResponseError}; use crate::service::http::{header::ContentType, StatusCode}; use crate::service::{HttpRequest, HttpResponse}; diff --git a/pagetop/src/response/page.rs b/pagetop/src/response/page.rs index bde474ab..19bbab3c 100644 --- a/pagetop/src/response/page.rs +++ b/pagetop/src/response/page.rs @@ -1,10 +1,190 @@ +use crate::base::actions; +use crate::base::components::L10n; +use crate::core::component::{ComponentTrait, ContextOp, OneComponent, RenderContext}; +use crate::core::theme::ComponentsRegions; +use crate::html::{html, Classes, ClassesOp, Favicon, Markup, DOCTYPE}; +use crate::response::fatal_error::FatalError; +use crate::{fn_builder, service}; + +use unic_langid::CharacterDirection; + pub use actix_web::Result as ResultPage; -mod before_prepare_page; -pub use before_prepare_page::{ActionBeforePreparePage, ACTION_BEFORE_PREPARE_PAGE}; +type PageTitle = OneComponent; +type PageDescription = OneComponent; -mod before_render_page; -pub use before_render_page::{ActionBeforeRenderPage, ACTION_BEFORE_RENDER_PAGE}; +#[rustfmt::skip] +pub struct Page { + title : PageTitle, + description : PageDescription, + metadata : Vec<(&'static str, &'static str)>, + properties : Vec<(&'static str, &'static str)>, + favicon : Option, + context : RenderContext, + body_classes: Classes, + regions : ComponentsRegions, + template : String, +} -mod definition; -pub use definition::Page; +impl Default for Page { + #[rustfmt::skip] + fn default() -> Self { + Page { + title : PageTitle::new(), + description : PageDescription::new(), + metadata : Vec::new(), + properties : Vec::new(), + favicon : None, + context : RenderContext::new(), + body_classes: Classes::new().with_value(ClassesOp::SetDefault, "body"), + regions : ComponentsRegions::new(), + template : "default".to_owned(), + } + } +} + +impl Page { + pub fn new(request: service::HttpRequest) -> Self { + let mut page = Page::default(); + page.context.alter(ContextOp::Request(Some(request))); + page + } + + // Page BUILDER. + + #[fn_builder] + pub fn alter_title(&mut self, title: L10n) -> &mut Self { + self.title.set(title); + self + } + + #[fn_builder] + pub fn alter_description(&mut self, description: L10n) -> &mut Self { + self.description.set(description); + self + } + + #[fn_builder] + pub fn alter_metadata(&mut self, name: &'static str, content: &'static str) -> &mut Self { + self.metadata.push((name, content)); + self + } + + #[fn_builder] + pub fn alter_property(&mut self, property: &'static str, content: &'static str) -> &mut Self { + self.metadata.push((property, content)); + self + } + + #[fn_builder] + pub fn alter_favicon(&mut self, favicon: Option) -> &mut Self { + self.favicon = favicon; + self + } + + #[fn_builder] + pub fn alter_context(&mut self, op: ContextOp) -> &mut Self { + self.context.alter(op); + self + } + + #[fn_builder] + pub fn alter_body_classes(&mut self, op: ClassesOp, classes: &str) -> &mut Self { + self.body_classes.alter_value(op, classes); + self + } + + #[fn_builder] + pub fn alter_in(&mut self, region: &'static str, component: impl ComponentTrait) -> &mut Self { + self.regions.add_to(region, component); + self + } + + #[fn_builder] + pub fn alter_template(&mut self, template: &str) -> &mut Self { + self.template = template.to_owned(); + self + } + + // Page GETTERS. + + pub fn title(&mut self) -> String { + self.title.prepare(&mut self.context).into_string() + } + + pub fn description(&mut self) -> String { + self.description.prepare(&mut self.context).into_string() + } + + pub fn metadata(&self) -> &Vec<(&str, &str)> { + &self.metadata + } + + pub fn properties(&self) -> &Vec<(&str, &str)> { + &self.properties + } + + pub fn favicon(&self) -> &Option { + &self.favicon + } + + pub fn context(&mut self) -> &mut RenderContext { + &mut self.context + } + + pub fn body_classes(&self) -> &Classes { + &self.body_classes + } + + pub fn template(&self) -> &str { + self.template.as_str() + } + + // Page RENDER. + + pub fn render(&mut self) -> ResultPage { + // Module actions before preparing the page. + actions::page::run_actions_before_prepare_page(self); + + // Theme actions before preparing the page. + self.context.theme().before_prepare_page(self); + + // Prepare page body. + let body = self.context.theme().prepare_page_body(self); + + // Module actions before rendering the page. + actions::page::run_actions_before_render_page(self); + + // Theme actions before rendering the page. + self.context.theme().before_render_page(self); + + // Prepare page head. + let head = self.context.theme().prepare_page_head(self); + + // Render the page. + let lang = self.context.langid().language.as_str(); + let dir = match self.context.langid().character_direction() { + CharacterDirection::LTR => "ltr", + CharacterDirection::RTL => "rtl", + }; + Ok(html! { + (DOCTYPE) + html lang=(lang) dir=(dir) { + (head) + (body) + } + }) + } + + pub fn prepare_region(&mut self, region: &str) -> Option { + let render = self + .regions + .get_extended_pack(self.context.theme().single_name(), region) + .prepare(self.context()); + if render.is_empty() { + None + } else { + Some(render) + } + } +} diff --git a/pagetop/src/response/page/definition.rs b/pagetop/src/response/page/definition.rs deleted file mode 100644 index c7ae62d6..00000000 --- a/pagetop/src/response/page/definition.rs +++ /dev/null @@ -1,195 +0,0 @@ -use crate::base::component::L10n; -use crate::core::action::{action_ref, run_actions}; -use crate::core::component::{ComponentTrait, ContextOp, OneComponent, RenderContext}; -use crate::core::theme::ComponentsRegions; -use crate::html::{html, Classes, ClassesOp, Favicon, Markup, DOCTYPE}; -use crate::response::fatal_error::FatalError; -use crate::response::page::ResultPage; -use crate::response::page::{ActionBeforePreparePage, ACTION_BEFORE_PREPARE_PAGE}; -use crate::response::page::{ActionBeforeRenderPage, ACTION_BEFORE_RENDER_PAGE}; -use crate::{fn_builder, service}; - -use unic_langid::CharacterDirection; - -type PageTitle = OneComponent; -type PageDescription = OneComponent; - -#[rustfmt::skip] -pub struct Page { - title : PageTitle, - description : PageDescription, - metadata : Vec<(&'static str, &'static str)>, - properties : Vec<(&'static str, &'static str)>, - favicon : Option, - context : RenderContext, - body_classes: Classes, - regions : ComponentsRegions, - template : String, -} - -impl Default for Page { - #[rustfmt::skip] - fn default() -> Self { - Page { - title : PageTitle::new(), - description : PageDescription::new(), - metadata : Vec::new(), - properties : Vec::new(), - favicon : None, - context : RenderContext::new(), - body_classes: Classes::new().with_value(ClassesOp::SetDefault, "body"), - regions : ComponentsRegions::new(), - template : "default".to_owned(), - } - } -} - -impl Page { - pub fn new(request: service::HttpRequest) -> Self { - let mut page = Page::default(); - page.context.alter(ContextOp::Request(Some(request))); - page - } - - // Page BUILDER. - - #[fn_builder] - pub fn alter_title(&mut self, title: L10n) -> &mut Self { - self.title.set(title); - self - } - - #[fn_builder] - pub fn alter_description(&mut self, description: L10n) -> &mut Self { - self.description.set(description); - self - } - - #[fn_builder] - pub fn alter_metadata(&mut self, name: &'static str, content: &'static str) -> &mut Self { - self.metadata.push((name, content)); - self - } - - #[fn_builder] - pub fn alter_property(&mut self, property: &'static str, content: &'static str) -> &mut Self { - self.metadata.push((property, content)); - self - } - - #[fn_builder] - pub fn alter_favicon(&mut self, favicon: Option) -> &mut Self { - self.favicon = favicon; - self - } - - #[fn_builder] - pub fn alter_context(&mut self, op: ContextOp) -> &mut Self { - self.context.alter(op); - self - } - - #[fn_builder] - pub fn alter_body_classes(&mut self, op: ClassesOp, classes: &str) -> &mut Self { - self.body_classes.alter_value(op, classes); - self - } - - #[fn_builder] - pub fn alter_in(&mut self, region: &'static str, component: impl ComponentTrait) -> &mut Self { - self.regions.add_to(region, component); - self - } - - #[fn_builder] - pub fn alter_template(&mut self, template: &str) -> &mut Self { - self.template = template.to_owned(); - self - } - - // Page GETTERS. - - pub fn title(&mut self) -> String { - self.title.prepare(&mut self.context).into_string() - } - - pub fn description(&mut self) -> String { - self.description.prepare(&mut self.context).into_string() - } - - pub fn metadata(&self) -> &Vec<(&str, &str)> { - &self.metadata - } - - pub fn properties(&self) -> &Vec<(&str, &str)> { - &self.properties - } - - pub fn favicon(&self) -> &Option { - &self.favicon - } - - pub fn context(&mut self) -> &mut RenderContext { - &mut self.context - } - - pub fn body_classes(&self) -> &Classes { - &self.body_classes - } - - pub fn template(&self) -> &str { - self.template.as_str() - } - - // Page RENDER. - - pub fn render(&mut self) -> ResultPage { - // Module actions before preparing the page. - run_actions(ACTION_BEFORE_PREPARE_PAGE, |action| { - action_ref::(&**action).run(self) - }); - - // Theme actions before preparing the page. - self.context.theme().before_prepare_page(self); - - // Prepare page body. - let body = self.context.theme().prepare_page_body(self); - - // Module actions before rendering the page. - run_actions(ACTION_BEFORE_RENDER_PAGE, |action| { - action_ref::(&**action).run(self) - }); - - // Theme actions before rendering the page. - self.context.theme().before_render_page(self); - - // Prepare page head. - let head = self.context.theme().prepare_page_head(self); - - // Render the page. - let lang = self.context.langid().language.as_str(); - let dir = match self.context.langid().character_direction() { - CharacterDirection::LTR => "ltr", - CharacterDirection::RTL => "rtl", - }; - Ok(html! { - (DOCTYPE) - html lang=(lang) dir=(dir) { - (head) - (body) - } - }) - } - - pub fn prepare_region(&mut self, region: &str) -> Option { - let render = self - .regions - .get_extended_pack(self.context.theme().single_name(), region) - .prepare(self.context()); - if render.is_empty() { - None - } else { - Some(render) - } - } -}