From db3efa9ef92b09c189fcda21a5f5f460b91f0f1f Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Tue, 1 Mar 2022 19:35:02 +0100 Subject: [PATCH] =?UTF-8?q?Modifica=20gesti=C3=B3n=20de=20p=C3=A1ginas=20p?= =?UTF-8?q?ara=20normalizar=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/all.rs | 10 --- src/core/response/page/assets.rs | 13 ++- src/core/response/page/component.rs | 10 +-- src/core/response/page/mod.rs | 11 +-- src/core/response/page/page.rs | 122 ++++++++++++++++++---------- src/core/theme/api.rs | 38 +++++++-- src/core/theme/mod.rs | 16 +--- 7 files changed, 128 insertions(+), 92 deletions(-) diff --git a/src/core/all.rs b/src/core/all.rs index 3174fc5f..eb7bed10 100644 --- a/src/core/all.rs +++ b/src/core/all.rs @@ -1,5 +1,4 @@ use crate::Lazy; -use crate::config::SETTINGS; use crate::core::theme::Theme; use crate::core::module::Module; use crate::core::response::page::PageContainer; @@ -23,15 +22,6 @@ pub static THEMES: Lazy>> = Lazy::new(|| { ]) }); -pub static DEFAULT_THEME: Lazy<&dyn Theme> = Lazy::new(|| { - for t in THEMES.read().unwrap().iter() { - if t.name().to_lowercase() == SETTINGS.app.theme.to_lowercase() { - return *t; - } - } - &base::theme::bootsier::BootsierTheme -}); - pub fn themes(cfg: &mut server::web::ServiceConfig) { cfg.service(actix_web_static_files::ResourceFiles::new( "/theme", diff --git a/src/core/response/page/assets.rs b/src/core/response/page/assets.rs index 7e1205eb..71c3f668 100644 --- a/src/core/response/page/assets.rs +++ b/src/core/response/page/assets.rs @@ -1,6 +1,17 @@ -use crate::core::all::DEFAULT_THEME; +use crate::{Lazy, base}; +use crate::config::SETTINGS; +use crate::core::all; use crate::core::theme::{Markup, PreEscaped, Theme, find_theme, html}; +pub static DEFAULT_THEME: Lazy<&dyn Theme> = Lazy::new(|| { + for t in all::THEMES.read().unwrap().iter() { + if t.name().to_lowercase() == SETTINGS.app.theme.to_lowercase() { + return *t; + } + } + &base::theme::bootsier::BootsierTheme +}); + // ----------------------------------------------------------------------------- // Favicon. // ----------------------------------------------------------------------------- diff --git a/src/core/response/page/component.rs b/src/core/response/page/component.rs index aebb1f43..a7e0ffd7 100644 --- a/src/core/response/page/component.rs +++ b/src/core/response/page/component.rs @@ -9,7 +9,7 @@ pub trait Component: Downcast + Send + Sync { fn prepare() -> Self where Self: Sized; - fn name(&self) -> &str { + fn name(&self) -> &'static str { let name = type_name::(); match name.rfind("::") { Some(position) => &name[(position + 2)..], @@ -17,12 +17,12 @@ pub trait Component: Downcast + Send + Sync { } } - fn qualified_name(&self) -> &str { - type_name::() + fn fullname(&self) -> String { + type_name::().to_string() } - fn description(&self) -> &str { - "" + fn description(&self) -> String { + "".to_string() } fn is_renderable(&self) -> bool { diff --git a/src/core/response/page/mod.rs b/src/core/response/page/mod.rs index 83f0e0e9..d10c5fcc 100644 --- a/src/core/response/page/mod.rs +++ b/src/core/response/page/mod.rs @@ -1,5 +1,3 @@ -use crate::core::all::COMPONENTS; - pub mod assets; pub use assets::Assets as PageAssets; @@ -12,12 +10,5 @@ pub use container::Container as PageContainer; mod page; pub use page::Page; pub use page::render_component; +pub use page::add_component_to; -pub fn add_component_to(region: &'static str, component: impl PageComponent) { - 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)); - } -} diff --git a/src/core/response/page/page.rs b/src/core/response/page/page.rs index 99041edd..48ea5094 100644 --- a/src/core/response/page/page.rs +++ b/src/core/response/page/page.rs @@ -1,63 +1,96 @@ +use crate::{Lazy, trace, util}; use crate::config::SETTINGS; -use crate::core::server; -use crate::core::all::COMPONENTS; +use crate::core::{all, server}; use crate::core::theme::{DOCTYPE, Markup, html}; use crate::core::response::page::{PageAssets, PageComponent, PageContainer}; use std::borrow::Cow; use std::collections::HashMap; -pub enum TextDirection { LeftToRight, RightToLeft, Auto } +pub static DEFAULT_LANGUAGE: Lazy> = Lazy::new(|| { + let language = SETTINGS.app.language[..2].to_lowercase(); + if !language.is_empty() { + Some(language) + } else { + None + } +}); + +pub static DEFAULT_DIRECTION: Lazy> = Lazy::new(|| { + let direction = SETTINGS.app.direction.to_lowercase(); + match direction.as_str() { + "auto" => Some("auto".to_string()), + "ltr" => Some("ltr".to_string()), + "rtl" => Some("rtl".to_string()), + "" => None, + _ => { + trace::warn!( + "Text direction \"{}\" not valid. {}.", + SETTINGS.app.direction, + "Check the settings file" + ); + None + } + } +}); + +pub enum TextDirection { Auto, LeftToRight, RightToLeft } pub struct Page<'a> { - language : &'a str, - title : &'a str, - direction : &'a str, - description : &'a str, - body_classes: Cow<'a, str>, + language : Option, + direction : Option, + title : Option, + description : Option, assets : PageAssets, + body_classes: Cow<'a, str>, regions : HashMap<&'a str, PageContainer>, - template : &'a str, + template : Option, } impl<'a> Page<'a> { pub fn prepare() -> Self { Page { - language : &SETTINGS.app.language[..2], - title : &SETTINGS.app.name, - direction : "ltr", - description : "", + language : match &*DEFAULT_LANGUAGE { + Some(language) => Some(language.to_string()), + _ => None, + }, + direction : match &*DEFAULT_DIRECTION { + Some(direction) => Some(direction.to_string()), + _ => None, + }, + title : None, + description : None, body_classes: "body".into(), assets : PageAssets::new(), - regions : COMPONENTS.read().unwrap().clone(), - template : "default", + regions : all::COMPONENTS.read().unwrap().clone(), + template : Some("default".to_string()), } } // Page BUILDER. - pub fn with_language(&mut self, language: &'a str) -> &mut Self { - self.language = language; - self - } - - pub fn with_title(&mut self, title: &'a str) -> &mut Self { - self.title = title; + pub fn with_language(&mut self, language: &str) -> &mut Self { + self.language = util::optional_value(language); self } pub fn with_direction(&mut self, dir: TextDirection) -> &mut Self { self.direction = match dir { - TextDirection::LeftToRight => "ltr", - TextDirection::RightToLeft => "rtl", - _ => "auto" + TextDirection::Auto => Some("auto".to_string()), + TextDirection::LeftToRight => Some("ltr".to_string()), + TextDirection::RightToLeft => Some("rtl".to_string()), }; self } - pub fn with_description(&mut self, description: &'a str) -> &mut Self { - self.description = description; + pub fn with_title(&mut self, title: &str) -> &mut Self { + self.title = util::optional_value(title); + self + } + + pub fn with_description(&mut self, description: &str) -> &mut Self { + self.description = util::optional_value(description); self } @@ -86,31 +119,27 @@ impl<'a> Page<'a> { self } - pub fn using_template(&mut self, template: &'a str) -> &mut Self { - self.template = template; + pub fn using_template(&mut self, template: &str) -> &mut Self { + self.template = util::optional_value(template); self } // Page GETTERS. pub fn language(&self) -> &str { - self.language + util::assigned_value(&self.language) + } + + pub fn direction(&self) -> &str { + util::assigned_value(&self.direction) } pub fn title(&self) -> &str { - self.title - } - - pub fn direction(&self) -> TextDirection { - match self.direction { - "ltr" => TextDirection::LeftToRight, - "rtl" => TextDirection::RightToLeft, - _ => TextDirection::Auto - } + util::assigned_value(&self.title) } pub fn description(&self) -> &str { - self.description + util::assigned_value(&self.description) } pub fn body_classes(&self) -> &str { @@ -125,7 +154,7 @@ impl<'a> Page<'a> { } pub fn template(&self) -> &str { - self.template + util::assigned_value(&self.template) } // Page RENDER. @@ -143,7 +172,7 @@ impl<'a> Page<'a> { // Finalmente, renderizar la página. return Ok(html! { (DOCTYPE) - html lang=(self.language) dir=(self.direction) { + html lang=[&self.language] dir=[&self.direction] { (head) (body) } @@ -177,3 +206,12 @@ pub fn render_component( false => html! {} } } + +pub fn add_component_to(region: &'static str, component: impl PageComponent) { + let mut hmap = all::COMPONENTS.write().unwrap(); + if let Some(regions) = hmap.get_mut(region) { + regions.add(component); + } else { + hmap.insert(region, PageContainer::new_with(component)); + } +} diff --git a/src/core/theme/api.rs b/src/core/theme/api.rs index 45f3e6a8..36350110 100644 --- a/src/core/theme/api.rs +++ b/src/core/theme/api.rs @@ -1,13 +1,14 @@ -use crate::core::server; +use crate::config::SETTINGS; +use crate::core::{all, server}; use crate::core::theme::{Markup, html}; use crate::core::response::page::{Page, PageAssets, PageComponent}; use crate::base::component::Chunck; /// Los temas deben implementar este "trait". pub trait Theme: Send + Sync { - fn id(&self) -> &'static str; + fn name(&self) -> &'static str; - fn name(&self) -> String; + fn fullname(&self) -> String; fn description(&self) -> String { "".to_string() @@ -22,19 +23,26 @@ pub trait Theme: Send + Sync { } fn render_page_head(&self, page: &mut Page) -> Markup { - let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no"; + let title = page.title(); + let title = if title.is_empty() { + SETTINGS.app.name.to_string() + } else { + [SETTINGS.app.name.to_string(), title.to_string()].join(" | ") + }; let description = page.description(); + let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no"; html! { head { meta charset="utf-8"; - meta http-equiv="X-UA-Compatible" content="IE=edge"; - meta name="viewport" content=(viewport); + title { (title) } + @if !description.is_empty() { meta name="description" content=(description); } - title { (page.title()) } + meta http-equiv="X-UA-Compatible" content="IE=edge"; + meta name="viewport" content=(viewport); (page.assets().render()) } @@ -72,8 +80,8 @@ pub trait Theme: Send + Sync { /* Cómo usarlo: - match component.type_name() { - "Block" => { + match component.handle() { + "block" => { let block = component.downcast_mut::().unwrap(); match block.template() { "default" => Some(block_default(block)), @@ -96,3 +104,15 @@ pub trait Theme: Send + Sync { .render() } } + +pub fn register_theme(t: &'static (dyn Theme + 'static)) { + all::THEMES.write().unwrap().push(t); +} + +pub fn find_theme(name: &str) -> Option<&'static (dyn Theme + 'static)> { + let themes = all::THEMES.write().unwrap(); + match themes.iter().find(|t| t.name() == name) { + Some(theme) => Some(*theme), + _ => None, + } +} diff --git a/src/core/theme/mod.rs b/src/core/theme/mod.rs index 973af092..9f708803 100644 --- a/src/core/theme/mod.rs +++ b/src/core/theme/mod.rs @@ -1,18 +1,4 @@ -use crate::core::all::THEMES; - pub use maud::{DOCTYPE, Markup, PreEscaped, html}; mod api; -pub use api::Theme; - -pub fn register_theme(t: &'static (dyn Theme + 'static)) { - THEMES.write().unwrap().push(t); -} - -pub fn find_theme(id: &str) -> Option<&'static (dyn Theme + 'static)> { - let themes = THEMES.write().unwrap(); - match themes.iter().find(|t| t.id() == id) { - Some(theme) => Some(*theme), - _ => None, - } -} +pub use api::{Theme, find_theme, register_theme};