💥 Simplifica RenderContext, ahora es sólo Context

This commit is contained in:
Manuel Cillero 2023-06-28 23:22:09 +02:00
parent c56cb256de
commit a1d51d6d0f
18 changed files with 87 additions and 104 deletions

View file

@ -4,7 +4,7 @@ macro_rules! action_after_prepare_component {
$crate::paste! {
$crate::use_handle!($ACTION_HANDLE);
pub type ActionAfter = fn(component: &$Component, rcx: &mut RenderContext);
pub type ActionAfter = fn(component: &$Component, cx: &mut Context);
pub struct [<AfterPrepare $Component>] {
action: Option<ActionAfter>,
@ -45,9 +45,9 @@ macro_rules! action_after_prepare_component {
self
}
pub fn run(&self, component: &mut $Component, rcx: &mut RenderContext) {
pub fn run(&self, component: &mut $Component, cx: &mut Context) {
if let Some(action) = self.action {
action(component, rcx)
action(component, cx)
}
}
}
@ -55,11 +55,11 @@ macro_rules! action_after_prepare_component {
#[inline(always)]
pub fn run_actions_after_prepare_component(
component: &mut $Component,
rcx: &mut RenderContext
cx: &mut Context
) {
run_actions($ACTION_HANDLE, |action|
action_ref::<[<AfterPrepare $Component>]>(&**action)
.run(component, rcx)
.run(component, cx)
);
}
}

View file

@ -4,7 +4,7 @@ macro_rules! action_before_prepare_component {
$crate::paste! {
$crate::use_handle!($ACTION_HANDLE);
pub type ActionBefore = fn(component: &$Component, rcx: &mut RenderContext);
pub type ActionBefore = fn(component: &$Component, cx: &mut Context);
pub struct [<BeforePrepare $Component>] {
action: Option<ActionBefore>,
@ -45,9 +45,9 @@ macro_rules! action_before_prepare_component {
self
}
pub fn run(&self, component: &mut $Component, rcx: &mut RenderContext) {
pub fn run(&self, component: &mut $Component, cx: &mut Context) {
if let Some(action) = self.action {
action(component, rcx)
action(component, cx)
}
}
}
@ -55,11 +55,11 @@ macro_rules! action_before_prepare_component {
#[inline(always)]
pub fn run_actions_before_prepare_component(
component: &mut $Component,
rcx: &mut RenderContext
cx: &mut Context
) {
run_actions($ACTION_HANDLE, |action|
action_ref::<[<BeforePrepare $Component>]>(&**action)
.run(component, rcx)
.run(component, cx)
);
}
}

View file

@ -31,30 +31,30 @@ impl ComponentTrait for Block {
self.weight
}
fn is_renderable(&self, rcx: &RenderContext) -> bool {
(self.renderable.check)(rcx)
fn is_renderable(&self, cx: &Context) -> bool {
(self.renderable.check)(cx)
}
fn before_prepare_component(&mut self, rcx: &mut RenderContext) {
actions::block::run_actions_before_prepare_component(self, rcx);
fn before_prepare_component(&mut self, cx: &mut Context) {
actions::block::run_actions_before_prepare_component(self, cx);
}
fn prepare_component(&self, rcx: &mut RenderContext) -> PrepareMarkup {
let id = rcx.required_id::<Block>(self.id());
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
let id = cx.required_id::<Block>(self.id());
PrepareMarkup::With(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().prepare(rcx))
(self.components().prepare(cx))
}
}
})
}
fn after_prepare_component(&mut self, rcx: &mut RenderContext) {
actions::block::run_actions_after_prepare_component(self, rcx);
fn after_prepare_component(&mut self, cx: &mut Context) {
actions::block::run_actions_after_prepare_component(self, cx);
}
fn as_ref_any(&self) -> &dyn AnyComponent {

View file

@ -14,7 +14,7 @@ impl ComponentTrait for Html {
COMPONENT_HTML
}
fn prepare_component(&self, _: &mut RenderContext) -> PrepareMarkup {
fn prepare_component(&self, _: &mut Context) -> PrepareMarkup {
PrepareMarkup::With(html! { (self.html()) })
}

View file

@ -28,14 +28,14 @@ impl ComponentTrait for L10n {
COMPONENT_L10N
}
fn prepare_component(&self, rcx: &mut RenderContext) -> PrepareMarkup {
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
match self.op() {
L10nOp::None => PrepareMarkup::None,
L10nOp::Text(text) => PrepareMarkup::Text(text),
L10nOp::Translated(key, locales) => PrepareMarkup::With(html! {
(locales
.lookup_with_args(
rcx.langid(),
cx.langid(),
key,
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
args.insert(key.to_string(), value.to_owned().into());
@ -48,7 +48,7 @@ impl ComponentTrait for L10n {
L10nOp::Escaped(key, locales) => PrepareMarkup::With(html! {
(PreEscaped(locales
.lookup_with_args(
rcx.langid(),
cx.langid(),
key,
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
args.insert(key.to_string(), value.to_owned().into());

View file

@ -1,5 +1,5 @@
mod context;
pub use context::{ContextOp, RenderContext};
pub use context::{Context, ContextOp};
mod definition;
pub use definition::{component_mut, component_ref, AnyComponent, BaseComponent, ComponentTrait};

View file

@ -1,22 +1,16 @@
use crate::core::theme::{all::theme_by_single_name, ThemeStaticRef};
use crate::core::theme::all::{theme_by_single_name, THEME};
use crate::core::theme::ThemeStaticRef;
use crate::html::{html, Assets, JavaScript, Markup, StyleSheet};
use crate::locale::{LanguageIdentifier, LANGID};
use crate::service::HttpRequest;
use crate::{concat_string, config, util, LazyStatic};
use crate::{concat_string, util};
use std::collections::HashMap;
use std::str::FromStr;
static THEME: LazyStatic<ThemeStaticRef> =
LazyStatic::new(|| match theme_by_single_name(&config::SETTINGS.app.theme) {
Some(theme) => theme,
None => &crate::base::themes::Basic,
});
pub enum ContextOp {
LangId(&'static LanguageIdentifier),
Theme(&'static str),
Request(Option<HttpRequest>),
AddStyleSheet(StyleSheet),
RemoveStyleSheet(&'static str),
AddJavaScript(JavaScript),
@ -24,35 +18,29 @@ pub enum ContextOp {
}
#[rustfmt::skip]
pub struct RenderContext {
pub struct Context {
request : HttpRequest,
langid : &'static LanguageIdentifier,
theme : ThemeStaticRef,
request : Option<HttpRequest>,
stylesheets: Assets<StyleSheet>,
javascripts: Assets<JavaScript>,
params : HashMap<&'static str, String>,
id_counter : usize,
}
impl Default for RenderContext {
impl Context {
#[rustfmt::skip]
fn default() -> Self {
RenderContext {
pub(crate) fn new(request: HttpRequest) -> Self {
Context {
request,
langid : &LANGID,
theme : *THEME,
request : None,
stylesheets: Assets::<StyleSheet>::new(),
javascripts: Assets::<JavaScript>::new(),
params : HashMap::<&str, String>::new(),
id_counter : 0,
}
}
}
impl RenderContext {
pub(crate) fn new() -> Self {
RenderContext::default()
}
pub fn alter(&mut self, op: ContextOp) -> &mut Self {
match op {
@ -62,9 +50,6 @@ impl RenderContext {
ContextOp::Theme(theme_name) => {
self.theme = theme_by_single_name(theme_name).unwrap_or(*THEME);
}
ContextOp::Request(request) => {
self.request = request;
}
ContextOp::AddStyleSheet(css) => {
self.stylesheets.add(css);
}
@ -88,6 +73,10 @@ impl RenderContext {
/// Context GETTERS.
pub fn request(&self) -> &HttpRequest {
&self.request
}
pub(crate) fn langid(&self) -> &LanguageIdentifier {
self.langid
}
@ -96,10 +85,6 @@ impl RenderContext {
self.theme
}
pub fn request(&self) -> &Option<HttpRequest> {
&self.request
}
pub fn get_param<T: FromStr + ToString>(&mut self, key: &'static str) -> Option<T> {
if let Some(value) = self.params.get(key) {
if let Ok(value) = T::from_str(value) {

View file

@ -1,11 +1,11 @@
use crate::core::component::RenderContext;
use crate::core::component::Context;
use crate::html::{html, Markup, PrepareMarkup};
use crate::{util, Handle};
pub use std::any::Any as AnyComponent;
pub trait BaseComponent {
fn prepare(&mut self, rcx: &mut RenderContext) -> Markup;
fn prepare(&mut self, cx: &mut Context) -> Markup;
}
pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
@ -32,20 +32,20 @@ pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
}
#[allow(unused_variables)]
fn is_renderable(&self, rcx: &RenderContext) -> bool {
fn is_renderable(&self, cx: &Context) -> bool {
true
}
#[allow(unused_variables)]
fn before_prepare_component(&mut self, rcx: &mut RenderContext) {}
fn before_prepare_component(&mut self, cx: &mut Context) {}
#[allow(unused_variables)]
fn prepare_component(&self, rcx: &mut RenderContext) -> PrepareMarkup {
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
PrepareMarkup::None
}
#[allow(unused_variables)]
fn after_prepare_component(&mut self, rcx: &mut RenderContext) {}
fn after_prepare_component(&mut self, cx: &mut Context) {}
fn as_ref_any(&self) -> &dyn AnyComponent;
@ -53,24 +53,24 @@ pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
}
impl<C: ComponentTrait> BaseComponent for C {
fn prepare(&mut self, rcx: &mut RenderContext) -> Markup {
if self.is_renderable(rcx) {
fn prepare(&mut self, cx: &mut Context) -> Markup {
if self.is_renderable(cx) {
// Acciones antes de preparar el componente.
self.before_prepare_component(rcx);
self.before_prepare_component(cx);
// Acciones del tema antes de preparar el componente.
rcx.theme().before_prepare_component(self, rcx);
cx.theme().before_prepare_component(self, cx);
let markup = match rcx.theme().render_component(self, rcx) {
let markup = match cx.theme().render_component(self, cx) {
Some(html) => html,
None => self.prepare_component(rcx).html(),
None => self.prepare_component(cx).html(),
};
// Acciones después de preparar el componente.
self.after_prepare_component(rcx);
self.after_prepare_component(cx);
// Acciones del tema después de preparar el componente.
rcx.theme().after_prepare_component(self, rcx);
cx.theme().after_prepare_component(self, cx);
markup
} else {

View file

@ -1,4 +1,4 @@
use crate::core::component::{ComponentTrait, RenderContext};
use crate::core::component::{ComponentTrait, Context};
use crate::html::{html, Markup};
use std::sync::{Arc, RwLock};
@ -21,9 +21,9 @@ impl<T: ComponentTrait + Default> OneComponent<T> {
// OneComponent PREPARE.
pub fn prepare(&self, rcx: &mut RenderContext) -> Markup {
pub fn prepare(&self, cx: &mut Context) -> Markup {
if let Some(component) = &self.0 {
return component.write().unwrap().prepare(rcx);
return component.write().unwrap().prepare(cx);
}
html! {}
}

View file

@ -1,4 +1,4 @@
use crate::core::component::{ComponentTrait, RenderContext};
use crate::core::component::{ComponentTrait, Context};
use crate::html::{html, Markup};
use crate::{fn_builder, Handle};
@ -116,12 +116,12 @@ impl PackComponents {
// PackComponents PREPARE.
pub fn prepare(&self, rcx: &mut RenderContext) -> Markup {
pub fn prepare(&self, cx: &mut Context) -> 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().prepare(rcx))(" ")
(" ")(c.write().unwrap().prepare(cx))(" ")
}
}
}

View file

@ -1,6 +1,6 @@
use crate::core::component::RenderContext;
use crate::core::component::Context;
pub type IsRenderable = fn(&RenderContext) -> bool;
pub type IsRenderable = fn(cx: &Context) -> bool;
pub struct Renderable {
pub check: IsRenderable,
@ -14,6 +14,6 @@ impl Default for Renderable {
}
}
fn render_always(_: &RenderContext) -> bool {
fn render_always(_: &Context) -> bool {
true
}

View file

@ -1,3 +1,4 @@
use crate::config;
use crate::core::theme::ThemeStaticRef;
use crate::LazyStatic;
@ -8,6 +9,14 @@ use std::sync::RwLock;
pub static THEMES: LazyStatic<RwLock<Vec<ThemeStaticRef>>> =
LazyStatic::new(|| RwLock::new(Vec::new()));
// DEFAULT THEME ***********************************************************************************
pub static THEME: LazyStatic<ThemeStaticRef> =
LazyStatic::new(|| match theme_by_single_name(&config::SETTINGS.app.theme) {
Some(theme) => theme,
None => &crate::base::themes::Basic,
});
// THEME BY NAME ***********************************************************************************
pub fn theme_by_single_name(single_name: &str) -> Option<ThemeStaticRef> {

View file

@ -1,5 +1,5 @@
use crate::base::components::L10n;
use crate::core::component::{ComponentTrait, RenderContext};
use crate::core::component::{ComponentTrait, Context};
use crate::core::module::ModuleTrait;
use crate::html::{html, Favicon, Markup};
use crate::response::page::Page;
@ -83,7 +83,7 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
fn before_prepare_component(
&self,
component: &mut dyn ComponentTrait,
rcx: &mut RenderContext,
cx: &mut Context,
) {
/*
Cómo usarlo:
@ -103,7 +103,7 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
fn after_prepare_component(
&self,
component: &mut dyn ComponentTrait,
rcx: &mut RenderContext,
cx: &mut Context,
) {
/*
Cómo usarlo:
@ -123,7 +123,7 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
fn render_component(
&self,
component: &dyn ComponentTrait,
rcx: &mut RenderContext,
cx: &mut Context,
) -> Option<Markup> {
None
/*

View file

@ -148,7 +148,7 @@ pub mod service;
// Tipos de respuestas a peticiones web.
pub mod response;
// Funciones útiles y macros declarativas.
// Funciones y macros útiles.
pub mod util;
// Prepara y ejecuta la aplicación.

View file

@ -6,14 +6,13 @@ pub use crate::{
concat_string, fn_builder, paste, Handle, HashMapResources, LazyStatic, ResultExt,
};
// Macros declarativas globales.
pub use crate::{args, serve_static_files, use_config, use_handle, use_locale, use_static};
// Traducciones globales.
pub use crate::LOCALE_PAGETOP;
// Funciones útiles.
// Funciones y macros útiles.
pub use crate::util;
pub use crate::{action, action_after_prepare_component, action_before_prepare_component};
pub use crate::{args, serve_static_files, use_config, use_handle, use_locale, use_static};
// *************************************************************************************************
@ -30,8 +29,6 @@ pub use crate::{db, db::*, migration_item, pub_migration};
pub use crate::core::{action::*, component::*, module::*, theme::*};
pub use crate::{action, action_after_prepare_component, action_before_prepare_component};
pub use crate::base::actions;
pub use crate::base::components::*;
pub use crate::base::themes;

View file

@ -1,4 +1,4 @@
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
use crate::core::component::{AnyComponent, ComponentTrait, Context};
use crate::html::{html, PrepareMarkup};
use crate::{use_handle, Handle};
@ -15,7 +15,7 @@ impl ComponentTrait for Error403 {
ERROR_403
}
fn prepare_component(&self, _rcx: &mut RenderContext) -> PrepareMarkup {
fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup {
PrepareMarkup::With(html! {
div {
h1 { ("FORBIDDEN ACCESS") }

View file

@ -1,4 +1,4 @@
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
use crate::core::component::{AnyComponent, ComponentTrait, Context};
use crate::html::{html, PrepareMarkup};
use crate::{use_handle, Handle};
@ -15,7 +15,7 @@ impl ComponentTrait for Error404 {
ERROR_404
}
fn prepare_component(&self, _rcx: &mut RenderContext) -> PrepareMarkup {
fn prepare_component(&self, _cx: &mut Context) -> PrepareMarkup {
PrepareMarkup::With(html! {
div {
h1 { ("RESOURCE NOT FOUND") }

View file

@ -1,6 +1,6 @@
use crate::base::actions;
use crate::base::components::L10n;
use crate::core::component::{ComponentTrait, ContextOp, OneComponent, RenderContext};
use crate::core::component::{ComponentTrait, Context, ContextOp, OneComponent};
use crate::core::theme::ComponentsRegions;
use crate::html::{html, Classes, ClassesOp, Favicon, Markup, DOCTYPE};
use crate::response::fatal_error::FatalError;
@ -20,35 +20,27 @@ pub struct Page {
metadata : Vec<(&'static str, &'static str)>,
properties : Vec<(&'static str, &'static str)>,
favicon : Option<Favicon>,
context : RenderContext,
context : Context,
body_classes: Classes,
regions : ComponentsRegions,
template : String,
}
impl Default for Page {
impl Page {
#[rustfmt::skip]
fn default() -> Self {
pub fn new(request: service::HttpRequest) -> Self {
Page {
title : PageTitle::new(),
description : PageDescription::new(),
metadata : Vec::new(),
properties : Vec::new(),
favicon : None,
context : RenderContext::new(),
context : Context::new(request),
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.
@ -128,7 +120,7 @@ impl Page {
&self.favicon
}
pub fn context(&mut self) -> &mut RenderContext {
pub fn context(&mut self) -> &mut Context {
&mut self.context
}