From b0446c720613385f1630a0311e39383955723b3a Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sun, 18 Dec 2022 14:09:53 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20PageContext=20pasa=20a?= =?UTF-8?q?=20ser=20RenderResources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ahora los componentes no tendrán acceso al contexto de la página (PageContext) porque podrían usarse en otros tipos de respuesta que no sean sólo páginas. En su lugar se usará RenderResources que formarán también parte de la página. --- pagetop-admin/src/summary.rs | 2 +- pagetop/src/base/component/anchor.rs | 10 +- pagetop/src/base/component/block.rs | 14 +-- pagetop/src/base/component/container.rs | 20 ++-- .../src/base/component/form_element/button.rs | 6 +- .../src/base/component/form_element/date.rs | 6 +- .../src/base/component/form_element/form.rs | 12 +-- .../src/base/component/form_element/hidden.rs | 2 +- .../src/base/component/form_element/input.rs | 6 +- pagetop/src/base/component/grid/column.rs | 12 +-- pagetop/src/base/component/grid/row.rs | 12 +-- pagetop/src/base/component/heading.rs | 6 +- pagetop/src/base/component/html.rs | 6 +- pagetop/src/base/component/icon.rs | 10 +- pagetop/src/base/component/image.rs | 6 +- pagetop/src/base/component/menu.rs | 43 +++++---- pagetop/src/base/component/paragraph.rs | 8 +- pagetop/src/base/module/homepage.rs | 2 +- pagetop/src/base/theme/aliner.rs | 10 +- pagetop/src/base/theme/bootsier.rs | 26 +++--- pagetop/src/base/theme/bulmix.rs | 20 ++-- pagetop/src/core/component.rs | 3 + pagetop/src/core/component/bundle.rs | 8 +- pagetop/src/core/component/definition.rs | 33 +++---- pagetop/src/core/component/renderable.rs | 6 +- .../component/resources.rs} | 75 +++++---------- pagetop/src/core/theme/definition.rs | 33 +++++-- pagetop/src/response/fatal_error.rs | 4 +- pagetop/src/response/page.rs | 22 ----- pagetop/src/response/page/definition.rs | 92 ++++++++++++++----- 30 files changed, 263 insertions(+), 252 deletions(-) rename pagetop/src/{response/page/context.rs => core/component/resources.rs} (59%) diff --git a/pagetop-admin/src/summary.rs b/pagetop-admin/src/summary.rs index c91b31db..4d10d42e 100644 --- a/pagetop-admin/src/summary.rs +++ b/pagetop-admin/src/summary.rs @@ -41,7 +41,7 @@ pub async fn summary() -> ResultPage { .with_item(MenuItem::label("Opción 4")); Page::new() - .with_context(PageOp::SetTheme("Bootsier")) + .with_resource(ResourceOp::SetTheme("Bootsier")) .with_title("Admin") .add_to("top-menu", top_menu) .add_to( diff --git a/pagetop/src/base/component/anchor.rs b/pagetop/src/base/component/anchor.rs index b91e939e..5e3c5070 100644 --- a/pagetop/src/base/component/anchor.rs +++ b/pagetop/src/base/component/anchor.rs @@ -51,12 +51,12 @@ impl ComponentTrait for Anchor { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } #[rustfmt::skip] - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { let target = match &self.target() { AnchorTarget::Blank => Some("_blank"), AnchorTarget::Parent => Some("_parent"), @@ -71,9 +71,9 @@ impl ComponentTrait for Anchor { href=[self.href().get()] target=[target] { - (self.left_icon().render(context)) + (self.left_icon().render(rsx)) span { (*self.html()) } - (self.right_icon().render(context)) + (self.right_icon().render(rsx)) } } } diff --git a/pagetop/src/base/component/block.rs b/pagetop/src/base/component/block.rs index af89daca..c419df63 100644 --- a/pagetop/src/base/component/block.rs +++ b/pagetop/src/base/component/block.rs @@ -29,23 +29,23 @@ impl ComponentTrait for Block { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn before_render(&mut self, context: &mut PageContext) { - before_render_inline(self, context); + fn before_render(&mut self, rsx: &mut RenderResources) { + before_render_inline(self, rsx); } - fn default_render(&self, context: &mut PageContext) -> Markup { - let id = context.required_id::(self.id()); + fn default_render(&self, rsx: &mut RenderResources) -> Markup { + let id = rsx.required_id::(self.id()); html! { div id=(id) class=[self.classes().get()] { @if let Some(title) = self.title().get() { h2 class="block-title" { (title) } } div class="block-body" { - (self.components().render(context)) + (self.components().render(rsx)) } } } diff --git a/pagetop/src/base/component/container.rs b/pagetop/src/base/component/container.rs index 1024e4de..64e461cf 100644 --- a/pagetop/src/base/component/container.rs +++ b/pagetop/src/base/component/container.rs @@ -42,47 +42,47 @@ impl ComponentTrait for Container { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn before_render(&mut self, context: &mut PageContext) { - before_render_inline(self, context); + fn before_render(&mut self, rsx: &mut RenderResources) { + before_render_inline(self, rsx); } - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { match self.container_type() { ContainerType::Header => html! { header id=[self.id().get()] class=[self.classes().get()] { div class=[self.inner_classes().get()] { - (self.components().render(context)) + (self.components().render(rsx)) } } }, ContainerType::Footer => html! { footer id=[self.id().get()] class=[self.classes().get()] { div class=[self.inner_classes().get()] { - (self.components().render(context)) + (self.components().render(rsx)) } } }, ContainerType::Main => html! { main id=[self.id().get()] class=[self.classes().get()] { div class=[self.inner_classes().get()] { - (self.components().render(context)) + (self.components().render(rsx)) } } }, ContainerType::Section => html! { section id=[self.id().get()] class=[self.classes().get()] { div class=[self.inner_classes().get()] { - (self.components().render(context)) + (self.components().render(rsx)) } } }, _ => html! { div id=[self.id().get()] class=[self.classes().get()] { - (self.components().render(context)) + (self.components().render(rsx)) } }, } diff --git a/pagetop/src/base/component/form_element/button.rs b/pagetop/src/base/component/form_element/button.rs index 32f7c9f7..dfa9b771 100644 --- a/pagetop/src/base/component/form_element/button.rs +++ b/pagetop/src/base/component/form_element/button.rs @@ -39,11 +39,11 @@ impl ComponentTrait for Button { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { let button_type = match self.button_type() { ButtonType::Button => "button", ButtonType::Submit => "submit", diff --git a/pagetop/src/base/component/form_element/date.rs b/pagetop/src/base/component/form_element/date.rs index 910e989a..260daa11 100644 --- a/pagetop/src/base/component/form_element/date.rs +++ b/pagetop/src/base/component/form_element/date.rs @@ -36,11 +36,11 @@ impl ComponentTrait for Date { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { let id = self.name().get().map(|name| concat_string!("edit-", name)); html! { div class=[self.classes().get()] { diff --git a/pagetop/src/base/component/form_element/form.rs b/pagetop/src/base/component/form_element/form.rs index 8f24800e..b47df647 100644 --- a/pagetop/src/base/component/form_element/form.rs +++ b/pagetop/src/base/component/form_element/form.rs @@ -40,15 +40,15 @@ impl ComponentTrait for Form { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn before_render(&mut self, context: &mut PageContext) { - before_render_inline(self, context); + fn before_render(&mut self, rsx: &mut RenderResources) { + before_render_inline(self, rsx); } - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { let method = match self.method() { FormMethod::Post => Some("post".to_owned()), FormMethod::Get => None, @@ -61,7 +61,7 @@ impl ComponentTrait for Form { method=[method] accept-charset=[self.charset().get()] { - div { (self.elements().render(context)) } + div { (self.elements().render(rsx)) } } } } diff --git a/pagetop/src/base/component/form_element/hidden.rs b/pagetop/src/base/component/form_element/hidden.rs index 2d105bf0..fab1e35f 100644 --- a/pagetop/src/base/component/form_element/hidden.rs +++ b/pagetop/src/base/component/form_element/hidden.rs @@ -23,7 +23,7 @@ impl ComponentTrait for Hidden { self.weight } - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { let id = self.name().get().map(|name| concat_string!("value-", name)); html! { input type="hidden" id=[id] name=[self.name().get()] value=[self.value().get()]; diff --git a/pagetop/src/base/component/form_element/input.rs b/pagetop/src/base/component/form_element/input.rs index edbf171a..40c16ce3 100644 --- a/pagetop/src/base/component/form_element/input.rs +++ b/pagetop/src/base/component/form_element/input.rs @@ -53,12 +53,12 @@ impl ComponentTrait for Input { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } #[rustfmt::skip] - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { let type_input = match self.input_type() { InputType::Textfield => "text", InputType::Password => "password", diff --git a/pagetop/src/base/component/grid/column.rs b/pagetop/src/base/component/grid/column.rs index bb78e9c4..da203229 100644 --- a/pagetop/src/base/component/grid/column.rs +++ b/pagetop/src/base/component/grid/column.rs @@ -61,18 +61,18 @@ impl ComponentTrait for Column { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn before_render(&mut self, context: &mut PageContext) { - before_render_inline(self, context); + fn before_render(&mut self, rsx: &mut RenderResources) { + before_render_inline(self, rsx); } - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { html! { div id=[self.id().get()] class=[self.classes().get()] { - (self.components().render(context)) + (self.components().render(rsx)) } } } diff --git a/pagetop/src/base/component/grid/row.rs b/pagetop/src/base/component/grid/row.rs index bd2ddd94..4382fc1b 100644 --- a/pagetop/src/base/component/grid/row.rs +++ b/pagetop/src/base/component/grid/row.rs @@ -28,18 +28,18 @@ impl ComponentTrait for Row { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn before_render(&mut self, context: &mut PageContext) { - before_render_inline(self, context); + fn before_render(&mut self, rsx: &mut RenderResources) { + before_render_inline(self, rsx); } - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { html! { div id=[self.id().get()] class=[self.classes().get()] { - (self.columns().render(context)) + (self.columns().render(rsx)) } } } diff --git a/pagetop/src/base/component/heading.rs b/pagetop/src/base/component/heading.rs index bf90567d..1108355b 100644 --- a/pagetop/src/base/component/heading.rs +++ b/pagetop/src/base/component/heading.rs @@ -51,11 +51,11 @@ impl ComponentTrait for Heading { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { let id = self.id().get(); let classes = self.classes().get(); html! { @match &self.heading_type() { diff --git a/pagetop/src/base/component/html.rs b/pagetop/src/base/component/html.rs index dfc51289..b169bf2a 100644 --- a/pagetop/src/base/component/html.rs +++ b/pagetop/src/base/component/html.rs @@ -24,11 +24,11 @@ impl ComponentTrait for Html { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { html! { (*self.html()) } } diff --git a/pagetop/src/base/component/icon.rs b/pagetop/src/base/component/icon.rs index 368fb4cc..1cb41331 100644 --- a/pagetop/src/base/component/icon.rs +++ b/pagetop/src/base/component/icon.rs @@ -24,17 +24,17 @@ impl ComponentTrait for Icon { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn before_render(&mut self, context: &mut PageContext) { - context.alter(PageOp::AddStyleSheet( + fn before_render(&mut self, rsx: &mut RenderResources) { + rsx.alter(ResourceOp::AddStyleSheet( StyleSheet::located("/theme/icons/bootstrap-icons.css").with_version("1.8.2"), )); } - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { html! { i class=[self.classes().get()] {}; } } diff --git a/pagetop/src/base/component/image.rs b/pagetop/src/base/component/image.rs index eb0b79f8..0272289e 100644 --- a/pagetop/src/base/component/image.rs +++ b/pagetop/src/base/component/image.rs @@ -26,11 +26,11 @@ impl ComponentTrait for Image { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn default_render(&self, _: &mut PageContext) -> Markup { + fn default_render(&self, _: &mut RenderResources) -> Markup { html! { img src=[self.source().get()] diff --git a/pagetop/src/base/component/menu.rs b/pagetop/src/base/component/menu.rs index 81a0c348..23f389a4 100644 --- a/pagetop/src/base/component/menu.rs +++ b/pagetop/src/base/component/menu.rs @@ -37,11 +37,11 @@ impl ComponentTrait for MenuItem { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { match self.item_type() { MenuItemType::Void => html! {}, @@ -63,7 +63,7 @@ impl ComponentTrait for MenuItem { li class="submenu" { a href="#" { (label) } ul { - (menu.items().render(context)) + (menu.items().render(rsx)) } } }, @@ -186,32 +186,31 @@ impl ComponentTrait for Menu { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn before_render(&mut self, context: &mut PageContext) { - before_render_inline(self, context); + fn before_render(&mut self, rsx: &mut RenderResources) { + before_render_inline(self, rsx); } - fn default_render(&self, context: &mut PageContext) -> Markup { - context - .alter(PageOp::AddStyleSheet( - StyleSheet::located("/theme/menu/css/menu.css").with_version("1.1.1"), - )) - .alter(PageOp::AddStyleSheet( - StyleSheet::located("/theme/menu/css/menu-clean.css").with_version("1.1.1"), - )) - .alter(PageOp::AddJavaScript( - JavaScript::located("/theme/menu/js/menu.min.js").with_version("1.1.1"), - )) - .alter(PageOp::AddJQuery); + fn default_render(&self, rsx: &mut RenderResources) -> Markup { + rsx.alter(ResourceOp::AddStyleSheet( + StyleSheet::located("/theme/menu/css/menu.css").with_version("1.1.1"), + )) + .alter(ResourceOp::AddStyleSheet( + StyleSheet::located("/theme/menu/css/menu-clean.css").with_version("1.1.1"), + )) + .alter(ResourceOp::AddJavaScript( + JavaScript::located("/theme/menu/js/menu.min.js").with_version("1.1.1"), + )) + .alter(ResourceOp::AddJQuery); - let id = context.required_id::(self.id()); + let id = rsx.required_id::(self.id()); html! { ul id=(id) class=[self.classes().get()] { - (self.items().render(context)) + (self.items().render(rsx)) } script type="text/javascript" defer { "jQuery(function(){jQuery('#" (id) "').smartmenus({" diff --git a/pagetop/src/base/component/paragraph.rs b/pagetop/src/base/component/paragraph.rs index fa60c233..65c932dd 100644 --- a/pagetop/src/base/component/paragraph.rs +++ b/pagetop/src/base/component/paragraph.rs @@ -38,17 +38,17 @@ impl ComponentTrait for Paragraph { self.weight } - fn is_renderable(&self, context: &PageContext) -> bool { - (self.renderable.check)(context) + fn is_renderable(&self, rsx: &RenderResources) -> bool { + (self.renderable.check)(rsx) } - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { html! { p id=[self.id().get()] class=[self.classes().get()] { - (self.components().render(context)) + (self.components().render(rsx)) } } } diff --git a/pagetop/src/base/module/homepage.rs b/pagetop/src/base/module/homepage.rs index 5fb37d63..d8b37051 100644 --- a/pagetop/src/base/module/homepage.rs +++ b/pagetop/src/base/module/homepage.rs @@ -27,7 +27,7 @@ impl ModuleTrait for DefaultHomePage { async fn demo() -> ResultPage { Page::new() .with_title(l("page_title").as_str()) - .with_context(PageOp::AddStyleSheet(StyleSheet::located( + .with_resource(ResourceOp::AddStyleSheet(StyleSheet::located( "/theme/module/homepage/styles.css", ))) .with_body_classes(ClassesOp::AddFirst, "default-homepage") diff --git a/pagetop/src/base/theme/aliner.rs b/pagetop/src/base/theme/aliner.rs index 28bdf386..bc94a621 100644 --- a/pagetop/src/base/theme/aliner.rs +++ b/pagetop/src/base/theme/aliner.rs @@ -16,11 +16,9 @@ impl ThemeTrait for Aliner { } fn before_render_page(&self, page: &mut Page) { - page.alter_context(PageOp::AddFavicon( - Favicon::new().with_icon("/theme/favicon.ico"), - )) - .alter_context(PageOp::AddStyleSheet( - StyleSheet::located("/aliner/css/styles.css").with_weight(-99), - )); + page.alter_favicon(Some(Favicon::new().with_icon("/theme/favicon.ico"))) + .alter_resource(ResourceOp::AddStyleSheet( + StyleSheet::located("/aliner/css/styles.css").with_weight(-99), + )); } } diff --git a/pagetop/src/base/theme/bootsier.rs b/pagetop/src/base/theme/bootsier.rs index a824b0da..8e2d4bdd 100644 --- a/pagetop/src/base/theme/bootsier.rs +++ b/pagetop/src/base/theme/bootsier.rs @@ -18,20 +18,18 @@ impl ThemeTrait for Bootsier { } fn before_render_page(&self, page: &mut Page) { - page.alter_context(PageOp::AddFavicon( - Favicon::new().with_icon("/theme/favicon.ico"), - )) - .alter_context(PageOp::AddStyleSheet( - StyleSheet::located("/bootsier/css/bootstrap.min.css") - .with_version("5.1.3") - .with_weight(-99), - )) - .alter_context(PageOp::AddJavaScript( - JavaScript::located("/bootsier/js/bootstrap.bundle.min.js") - .with_version("5.1.3") - .with_weight(-99), - )) - .alter_context(PageOp::AddJQuery); + page.alter_favicon(Some(Favicon::new().with_icon("/theme/favicon.ico"))) + .alter_resource(ResourceOp::AddStyleSheet( + StyleSheet::located("/bootsier/css/bootstrap.min.css") + .with_version("5.1.3") + .with_weight(-99), + )) + .alter_resource(ResourceOp::AddJavaScript( + JavaScript::located("/bootsier/js/bootstrap.bundle.min.js") + .with_version("5.1.3") + .with_weight(-99), + )) + .alter_resource(ResourceOp::AddJQuery); } fn error_404_not_found(&self) -> Container { diff --git a/pagetop/src/base/theme/bulmix.rs b/pagetop/src/base/theme/bulmix.rs index 90ce8c9c..4fa0c702 100644 --- a/pagetop/src/base/theme/bulmix.rs +++ b/pagetop/src/base/theme/bulmix.rs @@ -16,22 +16,20 @@ impl ThemeTrait for Bulmix { } fn before_render_page(&self, page: &mut Page) { - page.alter_context(PageOp::AddFavicon( - Favicon::new().with_icon("/theme/favicon.ico"), - )) - .alter_context(PageOp::AddStyleSheet( - StyleSheet::located("/bulmix/css/bulma.min.css") - .with_version("0.9.4") - .with_weight(-99), - )) - .alter_context(PageOp::AddJQuery); + page.alter_favicon(Some(Favicon::new().with_icon("/theme/favicon.ico"))) + .alter_resource(ResourceOp::AddStyleSheet( + StyleSheet::located("/bulmix/css/bulma.min.css") + .with_version("0.9.4") + .with_weight(-99), + )) + .alter_resource(ResourceOp::AddJQuery); } #[rustfmt::skip] fn before_render_component( &self, component: &mut dyn ComponentTrait, - _context: &mut PageContext, + _rsx: &mut RenderResources, ) { match component.handle() { COMPONENT_ANCHOR => { @@ -110,7 +108,7 @@ impl ThemeTrait for Bulmix { fn render_component( &self, component: &dyn ComponentTrait, - _context: &mut PageContext, + _rsx: &mut RenderResources, ) -> Option { match component.handle() { COMPONENT_ICON => { diff --git a/pagetop/src/core/component.rs b/pagetop/src/core/component.rs index cd596397..8f712325 100644 --- a/pagetop/src/core/component.rs +++ b/pagetop/src/core/component.rs @@ -1,3 +1,6 @@ +mod resources; +pub use resources::{RenderResources, ResourceOp}; + mod definition; pub use definition::{component_mut, component_ref, AnyComponent, BaseComponent, ComponentTrait}; diff --git a/pagetop/src/core/component/bundle.rs b/pagetop/src/core/component/bundle.rs index 2927ff29..44a5280f 100644 --- a/pagetop/src/core/component/bundle.rs +++ b/pagetop/src/core/component/bundle.rs @@ -1,6 +1,6 @@ -use super::ComponentTrait; +use super::{ComponentTrait, RenderResources}; + use crate::html::{html, Markup}; -use crate::response::page::PageContext; use std::sync::{Arc, RwLock}; @@ -26,12 +26,12 @@ impl ComponentsBundle { self.0.clear(); } - pub fn render(&self, context: &mut PageContext) -> Markup { + pub fn render(&self, rsx: &mut RenderResources) -> Markup { let mut components = self.0.clone(); components.sort_by_key(|c| c.read().unwrap().weight()); html! { @for c in components.iter() { - (" ")(c.write().unwrap().render(context))(" ") + (" ")(c.write().unwrap().render(rsx))(" ") } } } diff --git a/pagetop/src/core/component/definition.rs b/pagetop/src/core/component/definition.rs index f7df0561..84181a9e 100644 --- a/pagetop/src/core/component/definition.rs +++ b/pagetop/src/core/component/definition.rs @@ -1,11 +1,12 @@ +use super::RenderResources; + use crate::html::{html, Markup}; -use crate::response::page::PageContext; use crate::util::{single_type_name, Handle}; pub use std::any::Any as AnyComponent; pub trait BaseComponent { - fn render(&mut self, context: &mut PageContext) -> Markup; + fn render(&mut self, rsx: &mut RenderResources) -> Markup; } pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync { @@ -28,15 +29,15 @@ pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync { } #[allow(unused_variables)] - fn is_renderable(&self, context: &PageContext) -> bool { + fn is_renderable(&self, rsx: &RenderResources) -> bool { true } #[allow(unused_variables)] - fn before_render(&mut self, context: &mut PageContext) {} + fn before_render(&mut self, rsx: &mut RenderResources) {} #[allow(unused_variables)] - fn default_render(&self, context: &mut PageContext) -> Markup { + fn default_render(&self, rsx: &mut RenderResources) -> Markup { html! {} } @@ -46,17 +47,17 @@ pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync { } impl BaseComponent for C { - fn render(&mut self, context: &mut PageContext) -> Markup { + fn render(&mut self, rsx: &mut RenderResources) -> Markup { // Acciones del componente antes de renderizar. - self.before_render(context); + self.before_render(rsx); // Acciones del tema antes de renderizar el componente. - context.theme().before_render_component(self, context); + rsx.theme().before_render_component(self, rsx); - match self.is_renderable(context) { - true => match context.theme().render_component(self, context) { + match self.is_renderable(rsx) { + true => match rsx.theme().render_component(self, rsx) { Some(html) => html, - None => self.default_render(context), + None => self.default_render(rsx), }, false => html! {}, } @@ -77,7 +78,7 @@ macro_rules! hook_before_render_component { paste::paste! { $crate::pub_handle!($ACTION_HANDLE); - type Action = fn(&$Component, &mut PageContext); + type Action = fn(&$Component, &mut RenderResources); pub struct [< BeforeRender $Component >] { action: Option, @@ -118,18 +119,18 @@ macro_rules! hook_before_render_component { self } - pub fn run(&self, component: &mut $Component, context: &mut PageContext) { + pub fn run(&self, component: &mut $Component, rsx: &mut RenderResources) { if let Some(action) = self.action { - action(component, context) + action(component, rsx) } } } #[inline(always)] - fn before_render_inline(component: &mut $Component, context: &mut PageContext) { + fn before_render_inline(component: &mut $Component, rsx: &mut RenderResources) { run_actions($ACTION_HANDLE, |action| action_ref::<[< BeforeRender $Component >]>(&**action) - .run(component, context) + .run(component, rsx) ); } } diff --git a/pagetop/src/core/component/renderable.rs b/pagetop/src/core/component/renderable.rs index c93da898..039b5887 100644 --- a/pagetop/src/core/component/renderable.rs +++ b/pagetop/src/core/component/renderable.rs @@ -1,6 +1,6 @@ -use crate::response::page::PageContext; +use crate::core::component::RenderResources; -pub type IsRenderable = fn(&PageContext) -> bool; +pub type IsRenderable = fn(&RenderResources) -> bool; pub struct Renderable { pub check: IsRenderable, @@ -14,6 +14,6 @@ impl Default for Renderable { } } -fn render_always(_: &PageContext) -> bool { +fn render_always(_: &RenderResources) -> bool { true } diff --git a/pagetop/src/response/page/context.rs b/pagetop/src/core/component/resources.rs similarity index 59% rename from pagetop/src/response/page/context.rs rename to pagetop/src/core/component/resources.rs index 1e5e7a06..1130372d 100644 --- a/pagetop/src/response/page/context.rs +++ b/pagetop/src/core/component/resources.rs @@ -1,7 +1,5 @@ -use super::PageOp; - use crate::core::theme::{all::theme_by_single_name, ThemeStaticRef}; -use crate::html::{html, Assets, Favicon, IdentifierValue, JavaScript, Markup, ModeJS, StyleSheet}; +use crate::html::{html, Assets, IdentifierValue, JavaScript, Markup, ModeJS, StyleSheet}; use crate::{base, concat_string, config, util, LazyStatic}; static DEFAULT_THEME: LazyStatic = @@ -10,26 +8,29 @@ static DEFAULT_THEME: LazyStatic = None => &base::theme::bootsier::Bootsier, }); +pub enum ResourceOp { + SetTheme(&'static str), + AddStyleSheet(StyleSheet), + RemoveStyleSheet(&'static str), + AddJavaScript(JavaScript), + RemoveJavaScript(&'static str), + AddJQuery, +} + #[rustfmt::skip] -pub struct PageContext { +pub struct RenderResources { theme : ThemeStaticRef, - favicon : Option, - metadata : Vec<(&'static str, &'static str)>, - properties : Vec<(&'static str, &'static str)>, stylesheets: Assets, javascripts: Assets, with_jquery: bool, id_counter : usize, } -impl Default for PageContext { +impl Default for RenderResources { #[rustfmt::skip] fn default() -> Self { - PageContext { + RenderResources { theme : *DEFAULT_THEME, - favicon : None, - metadata : Vec::new(), - properties : Vec::new(), stylesheets: Assets::::new(), javascripts: Assets::::new(), with_jquery: false, @@ -38,45 +39,29 @@ impl Default for PageContext { } } -impl PageContext { +impl RenderResources { pub fn new() -> Self { - PageContext::default() + RenderResources::default() } - pub fn alter(&mut self, op: PageOp) -> &mut Self { + pub fn alter(&mut self, op: ResourceOp) -> &mut Self { match op { - PageOp::SetTheme(theme_name) => { + ResourceOp::SetTheme(theme_name) => { self.theme = theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME); } - - PageOp::AddFavicon(favicon) => { - self.favicon = Some(favicon); - } - PageOp::RemoveFavicon => { - self.favicon = None; - } - - PageOp::AddMetadata(name, content) => { - self.metadata.push((name, content)); - } - PageOp::AddProperty(property, content) => { - self.properties.push((property, content)); - } - - PageOp::AddStyleSheet(css) => { + ResourceOp::AddStyleSheet(css) => { self.stylesheets.add(css); } - PageOp::RemoveStyleSheet(source) => { + ResourceOp::RemoveStyleSheet(source) => { self.stylesheets.remove(source); } - - PageOp::AddJavaScript(js) => { + ResourceOp::AddJavaScript(js) => { self.javascripts.add(js); } - PageOp::RemoveJavaScript(source) => { + ResourceOp::RemoveJavaScript(source) => { self.javascripts.remove(source); } - PageOp::AddJQuery => { + ResourceOp::AddJQuery => { if !self.with_jquery { self.javascripts.add( JavaScript::located("/theme/js/jquery.min.js") @@ -91,32 +76,22 @@ impl PageContext { self } - /// PageContext GETTERS. + /// Resources GETTERS. pub(crate) fn theme(&mut self) -> ThemeStaticRef { self.theme } - /// PageContext RENDER. + /// Resources RENDER. pub fn render(&mut self) -> Markup { html! { - @match &self.favicon { - Some(favicon) => (favicon.render()), - None => "", - } - @for (name, content) in &self.metadata { - meta name=(name) content=(content) {} - } - @for (property, content) in &self.properties { - meta property=(property) content=(content) {} - } (self.stylesheets.render()) (self.javascripts.render()) } } - // PageContext EXTRAS. + // Resources EXTRAS. pub fn required_id(&mut self, id: &IdentifierValue) -> String { match id.get() { diff --git a/pagetop/src/core/theme/definition.rs b/pagetop/src/core/theme/definition.rs index 3234fe78..f5da0564 100644 --- a/pagetop/src/core/theme/definition.rs +++ b/pagetop/src/core/theme/definition.rs @@ -1,7 +1,7 @@ use crate::base::component::{Container, Html}; -use crate::core::component::ComponentTrait; +use crate::core::component::{ComponentTrait, RenderResources}; use crate::html::{html, Favicon, Markup}; -use crate::response::page::{Page, PageContext, PageOp}; +use crate::response::page::Page; use crate::util::{single_type_name, Handle}; use crate::{concat_string, config, server}; @@ -28,9 +28,9 @@ pub trait ThemeTrait: BaseTheme + Send + Sync { #[allow(unused_variables)] fn before_render_page(&self, page: &mut Page) { - page.alter_context(PageOp::AddFavicon( - Favicon::new().with_icon("/theme/favicon.ico"), - )); + if page.favicon().is_none() { + page.alter_favicon(Some(Favicon::new().with_icon("/theme/favicon.ico"))); + } } fn render_page_head(&self, page: &mut Page) -> Markup { @@ -49,10 +49,22 @@ pub trait ThemeTrait: BaseTheme + Send + Sync { @if let Some(d) = page.description().get() { meta name="description" content=(d); } - meta http-equiv="X-UA-Compatible" content="IE=edge"; - meta name="viewport" content=(viewport); - (page.context().render()) + meta name="viewport" content=(viewport); + @for (name, content) in page.metadata() { + meta name=(name) content=(content) {} + } + + meta http-equiv="X-UA-Compatible" content="IE=edge"; + @for (property, content) in page.properties() { + meta property=(property) content=(content) {} + } + + @if let Some(f) = page.favicon() { + (f.render()) + } + + (page.resources().render()) } } } @@ -84,7 +96,7 @@ pub trait ThemeTrait: BaseTheme + Send + Sync { fn before_render_component( &self, component: &mut dyn ComponentTrait, - context: &mut PageContext, + rsx: &mut RenderResources, ) { /* Cómo usarlo: @@ -99,11 +111,12 @@ pub trait ThemeTrait: BaseTheme + Send + Sync { */ } + #[rustfmt::skip] #[allow(unused_variables)] fn render_component( &self, component: &dyn ComponentTrait, - context: &mut PageContext, + rsx: &mut RenderResources, ) -> Option { None /* diff --git a/pagetop/src/response/fatal_error.rs b/pagetop/src/response/fatal_error.rs index 00b82e91..29e39077 100644 --- a/pagetop/src/response/fatal_error.rs +++ b/pagetop/src/response/fatal_error.rs @@ -25,7 +25,7 @@ impl fmt::Display for FatalError { // Error 403. FatalError::AccessDenied => { let mut error_page = Page::new(); - let error_content = error_page.context().theme().error_403_access_denied(); + let error_content = error_page.resources().theme().error_403_access_denied(); if let Ok(page) = error_page .with_title("Error FORBIDDEN") .using_template("error") @@ -40,7 +40,7 @@ impl fmt::Display for FatalError { // Error 404. FatalError::NotFound => { let mut error_page = Page::new(); - let error_content = error_page.context().theme().error_404_not_found(); + let error_content = error_page.resources().theme().error_404_not_found(); if let Ok(page) = error_page .with_title("Error RESOURCE NOT FOUND") .using_template("error") diff --git a/pagetop/src/response/page.rs b/pagetop/src/response/page.rs index 92a8241f..3f82c157 100644 --- a/pagetop/src/response/page.rs +++ b/pagetop/src/response/page.rs @@ -1,27 +1,5 @@ -use crate::html::{Favicon, JavaScript, StyleSheet}; - pub use actix_web::Result as ResultPage; -pub enum PageOp { - SetTheme(&'static str), - - AddFavicon(Favicon), - RemoveFavicon, - - AddMetadata(&'static str, &'static str), - AddProperty(&'static str, &'static str), - - AddStyleSheet(StyleSheet), - RemoveStyleSheet(&'static str), - - AddJavaScript(JavaScript), - RemoveJavaScript(&'static str), - AddJQuery, -} - -mod context; -pub use context::PageContext; - mod hook; pub use hook::{BeforeRenderPageHook, HOOK_BEFORE_RENDER_PAGE}; diff --git a/pagetop/src/response/page/definition.rs b/pagetop/src/response/page/definition.rs index 1ba7389d..2ae4a63d 100644 --- a/pagetop/src/response/page/definition.rs +++ b/pagetop/src/response/page/definition.rs @@ -1,8 +1,8 @@ -use super::{BeforeRenderPageHook, PageContext, PageOp, ResultPage, HOOK_BEFORE_RENDER_PAGE}; +use super::{BeforeRenderPageHook, ResultPage, HOOK_BEFORE_RENDER_PAGE}; use crate::core::component::*; use crate::core::hook::{action_ref, run_actions}; -use crate::html::{html, AttributeValue, Classes, ClassesOp, Markup, DOCTYPE}; +use crate::html::{html, AttributeValue, Classes, ClassesOp, Favicon, Markup, DOCTYPE}; use crate::response::FatalError; use crate::{config, trace, LazyStatic}; @@ -43,11 +43,14 @@ pub enum TextDirection { #[rustfmt::skip] pub struct Page { - context : PageContext, language : AttributeValue, direction : AttributeValue, title : AttributeValue, description : AttributeValue, + metadata : Vec<(&'static str, &'static str)>, + properties : Vec<(&'static str, &'static str)>, + favicon : Option, + resources : RenderResources, body_classes: Classes, regions : HashMap<&'static str, ComponentsBundle>, template : String, @@ -57,7 +60,6 @@ impl Default for Page { #[rustfmt::skip] fn default() -> Self { Page { - context : PageContext::new(), language : match &*DEFAULT_LANGUAGE { Some(language) => AttributeValue::new().with_value(language), _ => AttributeValue::new(), @@ -68,6 +70,10 @@ impl Default for Page { }, title : AttributeValue::new(), description : AttributeValue::new(), + metadata : Vec::new(), + properties : Vec::new(), + favicon : None, + resources : RenderResources::new(), body_classes: Classes::new().with_value(ClassesOp::SetDefault, "body"), regions : common_components(), template : "default".to_owned(), @@ -82,11 +88,6 @@ impl Page { // Page BUILDER. - pub fn with_context(mut self, op: PageOp) -> Self { - self.alter_context(op); - self - } - pub fn with_language(mut self, language: &str) -> Self { self.alter_language(language); self @@ -107,6 +108,26 @@ impl Page { self } + pub fn with_metadata(mut self, name: &'static str, content: &'static str) -> Self { + self.alter_metadata(name, content); + self + } + + pub fn with_property(mut self, property: &'static str, content: &'static str) -> Self { + self.alter_property(property, content); + self + } + + pub fn with_favicon(mut self, favicon: Option) -> Self { + self.alter_favicon(favicon); + self + } + + pub fn with_resource(mut self, op: ResourceOp) -> Self { + self.alter_resource(op); + self + } + pub fn with_body_classes(mut self, op: ClassesOp, classes: &str) -> Self { self.alter_body_classes(op, classes); self @@ -129,11 +150,6 @@ impl Page { // Page ALTER. - pub fn alter_context(&mut self, op: PageOp) -> &mut Self { - self.context.alter(op); - self - } - pub fn alter_language(&mut self, language: &str) -> &mut Self { self.language.alter_value(language); self @@ -158,6 +174,26 @@ impl Page { self } + pub fn alter_metadata(&mut self, name: &'static str, content: &'static str) -> &mut Self { + self.metadata.push((name, content)); + self + } + + pub fn alter_property(&mut self, property: &'static str, content: &'static str) -> &mut Self { + self.metadata.push((property, content)); + self + } + + pub fn alter_favicon(&mut self, favicon: Option) -> &mut Self { + self.favicon = favicon; + self + } + + pub fn alter_resource(&mut self, op: ResourceOp) -> &mut Self { + self.resources.alter(op); + self + } + pub fn alter_body_classes(&mut self, op: ClassesOp, classes: &str) -> &mut Self { self.body_classes.alter_value(op, classes); self @@ -170,10 +206,6 @@ impl Page { // Page GETTERS. - pub fn context(&mut self) -> &mut PageContext { - &mut self.context - } - pub fn language(&self) -> &AttributeValue { &self.language } @@ -190,6 +222,22 @@ impl Page { &self.description } + 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 resources(&mut self) -> &mut RenderResources { + &mut self.resources + } + pub fn body_classes(&self) -> &Classes { &self.body_classes } @@ -207,13 +255,13 @@ impl Page { }); // Acciones del tema antes de renderizar la página. - self.context.theme().before_render_page(self); + self.resources.theme().before_render_page(self); // Primero, renderizar el cuerpo. - let body = self.context.theme().render_page_body(self); + let body = self.resources.theme().render_page_body(self); // Luego, renderizar la cabecera. - let head = self.context.theme().render_page_head(self); + let head = self.resources.theme().render_page_head(self); // Finalmente, renderizar la página. Ok(html! { @@ -227,7 +275,7 @@ impl Page { pub fn render_region(&mut self, region: &str) -> Option { match self.regions.get_mut(region) { - Some(components) => Some(components.render(&mut self.context)), + Some(components) => Some(components.render(&mut self.resources)), None => None, } }