Modifica Assets por Context

This commit is contained in:
Manuel Cillero 2022-05-15 18:32:56 +02:00
parent 9e5d6e1a72
commit 72f5144b75
29 changed files with 375 additions and 372 deletions

View file

@ -55,7 +55,7 @@ impl ComponentTrait for Anchor {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
let target = match &self.target() {
AnchorTarget::Blank => Some("_blank"),
AnchorTarget::Context(name) => Some(name.as_str()),

View file

@ -37,8 +37,8 @@ impl ComponentTrait for Block {
self.weight
}
fn default_render(&self, assets: &mut Assets) -> Markup {
let id = assets.required_id::<Block>(self.id());
fn default_render(&self, context: &mut Context) -> Markup {
let id = context.required_id::<Block>(self.id());
html! {
div id=(id) class=[self.classes()] {
@match self.title() {
@ -46,7 +46,7 @@ impl ComponentTrait for Block {
None => {}
}
div class="block-body" {
(self.components().render(assets))
(self.components().render(context))
}
}
}

View file

@ -31,7 +31,7 @@ impl ComponentTrait for Chunck {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
html! { (*self.html()) }
}

View file

@ -41,39 +41,39 @@ impl ComponentTrait for Container {
self.weight
}
fn default_render(&self, assets: &mut Assets) -> Markup {
fn default_render(&self, context: &mut Context) -> Markup {
match self.container_type() {
ContainerType::Header => html! {
header id=[self.id()] class=[self.classes()] {
div class=[self.inner_classes()] {
(self.components().render(assets))
(self.components().render(context))
}
}
},
ContainerType::Footer => html! {
footer id=[self.id()] class=[self.classes()] {
div class=[self.inner_classes()] {
(self.components().render(assets))
(self.components().render(context))
}
}
},
ContainerType::Main => html! {
main id=[self.id()] class=[self.classes()] {
div class=[self.inner_classes()] {
(self.components().render(assets))
(self.components().render(context))
}
}
},
ContainerType::Section => html! {
section id=[self.id()] class=[self.classes()] {
div class=[self.inner_classes()] {
(self.components().render(assets))
(self.components().render(context))
}
}
},
_ => html! {
div id=[self.id()] class=[self.classes()] {
(self.components().render(assets))
(self.components().render(context))
}
}
}

View file

@ -44,7 +44,7 @@ impl ComponentTrait for Button {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
let button_type = match self.button_type() {
ButtonType::Button => "button",
ButtonType::Reset => "reset",

View file

@ -52,7 +52,7 @@ impl ComponentTrait for Date {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
let id = match self.name() {
Some(name) => Some(concat_string!("edit-", name)),
None => None,

View file

@ -43,7 +43,7 @@ impl ComponentTrait for Form {
self.weight
}
fn default_render(&self, assets: &mut Assets) -> Markup {
fn default_render(&self, context: &mut Context) -> Markup {
let method = match self.method() {
FormMethod::Get => None,
FormMethod::Post => Some("post".to_owned())
@ -56,7 +56,7 @@ impl ComponentTrait for Form {
method=[method]
accept-charset=[self.charset()]
{
div { (self.elements().render(assets)) }
div { (self.elements().render(context)) }
}
}
}

View file

@ -25,7 +25,7 @@ impl ComponentTrait for Hidden {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
let id = match self.name() {
Some(name) => Some(concat_string!("value-", name)),
_ => None

View file

@ -62,14 +62,14 @@ impl ComponentTrait for Input {
self.weight
}
fn before_render(&mut self, _: &mut Assets) {
fn before_render(&mut self, _: &mut Context) {
if let Some(name) = self.name() {
let class = concat_string!("form-item-", name);
self.alter_classes(class.as_str(), ClassesOp::AddFirst);
}
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
let type_input = match self.input_type() {
InputType::Email => "email",
InputType::Password => "password",

View file

@ -35,10 +35,10 @@ impl ComponentTrait for Column {
self.weight
}
fn default_render(&self, assets: &mut Assets) -> Markup {
fn default_render(&self, context: &mut Context) -> Markup {
html! {
div id=[self.id()] class=[self.classes()] {
(self.components().render(assets))
(self.components().render(context))
}
}
}

View file

@ -35,10 +35,10 @@ impl ComponentTrait for Row {
self.weight
}
fn default_render(&self, assets: &mut Assets) -> Markup {
fn default_render(&self, context: &mut Context) -> Markup {
html! {
div id=[self.id()] class=[self.classes()] {
(self.columns().render(assets))
(self.columns().render(context))
}
}
}

View file

@ -50,7 +50,7 @@ impl ComponentTrait for Heading {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
html! { @match &self.heading() {
HeadingType::H1 => h1 id=[self.id()] class=[self.classes()] { (*self.html()) },
HeadingType::H2 => h2 id=[self.id()] class=[self.classes()] { (*self.html()) },

View file

@ -35,7 +35,7 @@ impl ComponentTrait for Image {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
html! {
img
src=[self.source()]

View file

@ -42,7 +42,7 @@ impl ComponentTrait for MenuItem {
self.weight
}
fn default_render(&self, assets: &mut Assets) -> Markup {
fn default_render(&self, context: &mut Context) -> Markup {
match self.item_type() {
MenuItemType::Label(label) => html! {
li class="label" { a href="#" { (label) } }
@ -62,7 +62,7 @@ impl ComponentTrait for MenuItem {
li class="submenu" {
a href="#" { (label) }
ul {
(menu.items().render(assets))
(menu.items().render(context))
}
}
},
@ -206,8 +206,8 @@ impl ComponentTrait for Menu {
self.weight
}
fn default_render(&self, assets: &mut Assets) -> Markup {
assets
fn default_render(&self, context: &mut Context) -> Markup {
context
.add_stylesheet(StyleSheet::source(
"/theme/menu/css/menu.css?ver=1.1.1"
))
@ -219,10 +219,10 @@ impl ComponentTrait for Menu {
))
.add_jquery();
let id = assets.required_id::<Menu>(self.id());
let id = context.required_id::<Menu>(self.id());
html! {
ul id=(id) class=[self.classes()] {
(self.items().render(assets))
(self.items().render(context))
}
script type="text/javascript" defer {
"jQuery(function(){jQuery('#" (id) "').smartmenus({"

View file

@ -46,7 +46,7 @@ impl ComponentTrait for Paragraph {
self.weight
}
fn default_render(&self, _: &mut Assets) -> Markup {
fn default_render(&self, _: &mut Context) -> Markup {
html! {
p id=[self.id()] class=[self.classes()] { (*self.html()) }
}

View file

@ -16,7 +16,7 @@ impl ThemeTrait for Aliner {
}
fn before_render_page(&self, page: &mut Page) {
page.assets()
page.context()
.with_favicon(
Favicon::new()
.with_icon("/theme/favicon.png")

View file

@ -18,7 +18,7 @@ impl ThemeTrait for Bootsier {
}
fn before_render_page(&self, page: &mut Page) {
page.assets()
page.context()
.with_favicon(
Favicon::new()
.with_icon("/theme/favicon.png")

View file

@ -16,7 +16,7 @@ impl ThemeTrait for Bulmix {
}
fn before_render_page(&self, page: &mut Page) {
page.assets()
page.context()
.with_favicon(
Favicon::new()
.with_icon("/theme/favicon.png")
@ -33,7 +33,7 @@ impl ThemeTrait for Bulmix {
fn before_render_component(
&self,
component: &mut dyn ComponentTrait,
_assets: &mut Assets
_context: &mut Context
) {
match component.handler() {
HEADING_COMPONENT => {

View file

@ -4,9 +4,9 @@ pub use hook::{
BeforeRenderComponentHook,
};
mod assets;
pub use assets::{
Assets,
mod context;
pub use context::{
Context,
Favicon,
JavaScript, JSMode,
StyleSheet,

View file

@ -1,302 +0,0 @@
use crate::{Lazy, base, concat_string, util};
use crate::config::SETTINGS;
use crate::html::{Markup, PreEscaped, html};
use crate::core::theme::*;
static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| {
match all::theme_by_single_name(&SETTINGS.app.theme) {
Some(theme) => theme,
None => &base::theme::bootsier::Bootsier,
}
});
// Favicon.
pub struct Favicon(Vec<String>);
impl Favicon {
pub fn new() -> Self {
Favicon(Vec::new())
}
pub fn with_icon(self, image: &str) -> Self {
self.add_item("icon", image, "", "")
}
pub fn with_icon_for_sizes(self, image: &str, sizes: &str) -> Self {
self.add_item("icon", image, sizes, "")
}
pub fn with_apple_touch_icon(self, image: &str, sizes: &str) -> Self {
self.add_item("apple-touch-icon", image, sizes, "")
}
pub fn with_mask_icon(self, image: &str, color: &str) -> Self {
self.add_item("mask-icon", image, "", color)
}
pub fn with_manifest(self, file: &str) -> Self {
self.add_item("manifest", file, "", "")
}
pub fn with_theme_color(mut self, color: &str) -> Self {
self.0.push(format!(
"<meta name=\"theme-color\" content=\"{}\">", color
));
self
}
pub fn with_ms_tile_color(mut self, color: &str) -> Self {
self.0.push(format!(
"<meta name=\"msapplication-TileColor\" content=\"{}\">", color
));
self
}
pub fn with_ms_tile_image(mut self, image: &str) -> Self {
self.0.push(format!(
"<meta name=\"msapplication-TileImage\" content=\"{}\">", image
));
self
}
fn add_item(
mut self,
rel : &str,
source: &str,
sizes : &str,
color : &str
) -> Self {
let mut link: String = format!("<link rel=\"{}\"", rel);
if let Some(i) = source.rfind('.') {
link = match source[i..].to_owned().to_lowercase().as_str() {
".gif" => format!("{} type=\"image/gif\"", link),
".ico" => format!("{} type=\"image/x-icon\"", link),
".jpg" => format!("{} type=\"image/jpg\"", link),
".png" => format!("{} type=\"image/png\"", link),
".svg" => format!("{} type=\"image/svg+xml\"", link),
_ => link
};
}
if !sizes.is_empty() {
link = format!("{} sizes=\"{}\"", link, sizes);
}
if !color.is_empty() {
link = format!("{} color=\"{}\"", link, color);
}
self.0.push(format!("{} href=\"{}\">", link, source));
self
}
fn render(&self) -> Markup {
html! {
@for item in &self.0 {
(PreEscaped(item))
}
}
}
}
// JavaScript.
#[derive(PartialEq)]
pub enum JSMode { Async, Defer, Normal }
pub struct JavaScript {
source: &'static str,
weight: isize,
mode : JSMode,
}
impl JavaScript {
pub fn source(s: &'static str) -> Self {
JavaScript {
source: s,
weight: 0,
mode : JSMode::Defer,
}
}
pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight;
self
}
pub fn with_mode(mut self, mode: JSMode) -> Self {
self.mode = mode;
self
}
pub fn weight(self) -> isize {
self.weight
}
fn render(&self) -> Markup {
html! {
script type="text/javascript"
src=(self.source)
async[self.mode == JSMode::Async]
defer[self.mode == JSMode::Defer]
{};
}
}
}
// StyleSheet.
pub struct StyleSheet {
source: &'static str,
weight: isize,
}
impl StyleSheet {
pub fn source(s: &'static str) -> Self {
StyleSheet {
source: s,
weight: 0,
}
}
pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight;
self
}
pub fn weight(self) -> isize {
self.weight
}
fn render(&self) -> Markup {
html! {
link rel="stylesheet" href=(self.source);
}
}
}
// Page assets.
pub struct Assets {
theme : &'static dyn ThemeTrait,
favicon : Option<Favicon>,
metadata : Vec<(String, String)>,
stylesheets: Vec<StyleSheet>,
javascripts: Vec<JavaScript>,
with_jquery: bool,
id_counter : usize,
}
impl Assets {
pub fn new() -> Self {
Assets {
theme : *DEFAULT_THEME,
favicon : None,
metadata : Vec::new(),
stylesheets: Vec::new(),
javascripts: Vec::new(),
with_jquery: false,
id_counter : 0,
}
}
pub fn using_theme(&mut self, theme_name: &str) -> &mut Self {
self.theme = all::theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME);
self
}
pub fn with_favicon(&mut self, favicon: Favicon) -> &mut Self {
self.favicon = Some(favicon);
self
}
pub fn add_metadata(&mut self, name: String, content: String) -> &mut Self {
self.metadata.push((name, content));
self
}
pub fn add_stylesheet(&mut self, css: StyleSheet) -> &mut Self {
match self.stylesheets.iter().position(|x| x.source == css.source) {
Some(index) => if self.stylesheets[index].weight > css.weight {
self.stylesheets.remove(index);
self.stylesheets.push(css);
},
_ => self.stylesheets.push(css)
}
self
}
pub fn add_javascript(&mut self, js: JavaScript) -> &mut Self {
match self.javascripts.iter().position(|x| x.source == js.source) {
Some(index) => if self.javascripts[index].weight > js.weight {
self.javascripts.remove(index);
self.javascripts.push(js);
},
_ => self.javascripts.push(js)
}
self
}
pub fn add_jquery(&mut self) -> &mut Self {
if !self.with_jquery {
self.add_javascript(
JavaScript::source(
"/theme/js/jquery.min.js?ver=3.6.0"
)
.with_weight(isize::MIN)
.with_mode(JSMode::Normal)
);
self.with_jquery = true;
}
self
}
/// Assets GETTERS.
pub(crate) fn theme(&mut self) -> &'static dyn ThemeTrait {
self.theme
}
/// Assets RENDER.
pub fn render(&mut self) -> Markup {
let ordered_css = &mut self.stylesheets;
ordered_css.sort_by_key(|o| o.weight);
let ordered_js = &mut self.javascripts;
ordered_js.sort_by_key(|o| o.weight);
html! {
@match &self.favicon {
Some(favicon) => (favicon.render()),
None => "",
}
@for (name, content) in &self.metadata {
meta name=(name) content=(content) {}
}
@for css in ordered_css {
(css.render())
}
@for js in ordered_js {
(js.render())
}
}
}
// Assets EXTRAS.
pub fn required_id<T>(&mut self, id: &Option<String>) -> String {
match id {
Some(id) => id.to_string(),
None => {
let prefix = util::single_type_name::<T>()
.trim()
.replace(" ", "_")
.to_lowercase();
let prefix = if prefix.is_empty() {
"prefix".to_owned()
} else {
prefix
};
self.id_counter += 1;
concat_string!(prefix, "-", self.id_counter.to_string())
}
}
}
}

View file

@ -0,0 +1,148 @@
use crate::{Lazy, base, concat_string, util};
use crate::config::SETTINGS;
use crate::html::{Markup, html};
use crate::core::theme::*;
mod favicon;
pub use favicon::Favicon;
mod javascript;
pub use javascript::{JavaScript, JSMode};
mod stylesheet;
pub use stylesheet::StyleSheet;
static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| {
match all::theme_by_single_name(&SETTINGS.app.theme) {
Some(theme) => theme,
None => &base::theme::bootsier::Bootsier,
}
});
pub struct Context {
theme : &'static dyn ThemeTrait,
favicon : Option<Favicon>,
metadata : Vec<(String, String)>,
stylesheets: Vec<StyleSheet>,
javascripts: Vec<JavaScript>,
with_jquery: bool,
id_counter : usize,
}
impl Context {
pub fn new() -> Self {
Context {
theme : *DEFAULT_THEME,
favicon : None,
metadata : Vec::new(),
stylesheets: Vec::new(),
javascripts: Vec::new(),
with_jquery: false,
id_counter : 0,
}
}
pub fn using_theme(&mut self, theme_name: &str) -> &mut Self {
self.theme = all::theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME);
self
}
pub fn with_favicon(&mut self, favicon: Favicon) -> &mut Self {
self.favicon = Some(favicon);
self
}
pub fn add_metadata(&mut self, name: String, content: String) -> &mut Self {
self.metadata.push((name, content));
self
}
pub fn add_stylesheet(&mut self, css: StyleSheet) -> &mut Self {
match self.stylesheets.iter().position(|x| x.source == css.source) {
Some(index) => if self.stylesheets[index].weight > css.weight {
self.stylesheets.remove(index);
self.stylesheets.push(css);
},
_ => self.stylesheets.push(css)
}
self
}
pub fn add_javascript(&mut self, js: JavaScript) -> &mut Self {
match self.javascripts.iter().position(|x| x.source == js.source) {
Some(index) => if self.javascripts[index].weight > js.weight {
self.javascripts.remove(index);
self.javascripts.push(js);
},
_ => self.javascripts.push(js)
}
self
}
pub fn add_jquery(&mut self) -> &mut Self {
if !self.with_jquery {
self.add_javascript(
JavaScript::source(
"/theme/js/jquery.min.js?ver=3.6.0"
)
.with_weight(isize::MIN)
.with_mode(JSMode::Normal)
);
self.with_jquery = true;
}
self
}
/// Context GETTERS.
pub(crate) fn theme(&mut self) -> &'static dyn ThemeTrait {
self.theme
}
/// Context RENDER.
pub fn render(&mut self) -> Markup {
let ordered_css = &mut self.stylesheets;
ordered_css.sort_by_key(|o| o.weight);
let ordered_js = &mut self.javascripts;
ordered_js.sort_by_key(|o| o.weight);
html! {
@match &self.favicon {
Some(favicon) => (favicon.render()),
None => "",
}
@for (name, content) in &self.metadata {
meta name=(name) content=(content) {}
}
@for css in ordered_css {
(css.render())
}
@for js in ordered_js {
(js.render())
}
}
}
// Context EXTRAS.
pub fn required_id<T>(&mut self, id: &Option<String>) -> String {
match id {
Some(id) => id.to_string(),
None => {
let prefix = util::single_type_name::<T>()
.trim()
.replace(" ", "_")
.to_lowercase();
let prefix = if prefix.is_empty() {
"prefix".to_owned()
} else {
prefix
};
self.id_counter += 1;
concat_string!(prefix, "-", self.id_counter.to_string())
}
}
}
}

View file

@ -0,0 +1,86 @@
use crate::html::{Markup, PreEscaped, html};
pub struct Favicon(Vec<String>);
impl Favicon {
pub fn new() -> Self {
Favicon(Vec::new())
}
pub fn with_icon(self, image: &str) -> Self {
self.add_item("icon", image, "", "")
}
pub fn with_icon_for_sizes(self, image: &str, sizes: &str) -> Self {
self.add_item("icon", image, sizes, "")
}
pub fn with_apple_touch_icon(self, image: &str, sizes: &str) -> Self {
self.add_item("apple-touch-icon", image, sizes, "")
}
pub fn with_mask_icon(self, image: &str, color: &str) -> Self {
self.add_item("mask-icon", image, "", color)
}
pub fn with_manifest(self, file: &str) -> Self {
self.add_item("manifest", file, "", "")
}
pub fn with_theme_color(mut self, color: &str) -> Self {
self.0.push(format!(
"<meta name=\"theme-color\" content=\"{}\">", color
));
self
}
pub fn with_ms_tile_color(mut self, color: &str) -> Self {
self.0.push(format!(
"<meta name=\"msapplication-TileColor\" content=\"{}\">", color
));
self
}
pub fn with_ms_tile_image(mut self, image: &str) -> Self {
self.0.push(format!(
"<meta name=\"msapplication-TileImage\" content=\"{}\">", image
));
self
}
fn add_item(
mut self,
rel : &str,
source: &str,
sizes : &str,
color : &str
) -> Self {
let mut link: String = format!("<link rel=\"{}\"", rel);
if let Some(i) = source.rfind('.') {
link = match source[i..].to_owned().to_lowercase().as_str() {
".gif" => format!("{} type=\"image/gif\"", link),
".ico" => format!("{} type=\"image/x-icon\"", link),
".jpg" => format!("{} type=\"image/jpg\"", link),
".png" => format!("{} type=\"image/png\"", link),
".svg" => format!("{} type=\"image/svg+xml\"", link),
_ => link
};
}
if !sizes.is_empty() {
link = format!("{} sizes=\"{}\"", link, sizes);
}
if !color.is_empty() {
link = format!("{} color=\"{}\"", link, color);
}
self.0.push(format!("{} href=\"{}\">", link, source));
self
}
pub(super) fn render(&self) -> Markup {
html! {
@for item in &self.0 {
(PreEscaped(item))
}
}
}
}

View file

@ -0,0 +1,43 @@
use crate::html::{Markup, html};
#[derive(PartialEq)]
pub enum JSMode { Async, Defer, Normal }
pub struct JavaScript {
pub(super) source: &'static str,
pub(super) weight: isize,
pub(super) mode : JSMode,
}
impl JavaScript {
pub fn source(s: &'static str) -> Self {
JavaScript {
source: s,
weight: 0,
mode : JSMode::Defer,
}
}
pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight;
self
}
pub fn with_mode(mut self, mode: JSMode) -> Self {
self.mode = mode;
self
}
pub fn weight(self) -> isize {
self.weight
}
pub(super) fn render(&self) -> Markup {
html! {
script type="text/javascript"
src=(self.source)
async[self.mode == JSMode::Async]
defer[self.mode == JSMode::Defer]
{};
}
}
}

View file

@ -0,0 +1,29 @@
use crate::html::{Markup, html};
pub struct StyleSheet {
pub(super) source: &'static str,
pub(super) weight: isize,
}
impl StyleSheet {
pub fn source(s: &'static str) -> Self {
StyleSheet {
source: s,
weight: 0,
}
}
pub fn with_weight(mut self, weight: isize) -> Self {
self.weight = weight;
self
}
pub fn weight(self) -> isize {
self.weight
}
pub(super) fn render(&self) -> Markup {
html! {
link rel="stylesheet" href=(self.source);
}
}
}

View file

@ -1,8 +1,7 @@
use crate::util;
use crate::html::{Markup, html};
use crate::core::hook::{hook_ref, run_hooks};
use super::{BEFORE_RENDER_COMPONENT_HOOK, BeforeRenderComponentHook};
use super::Assets;
use super::{BEFORE_RENDER_COMPONENT_HOOK, BeforeRenderComponentHook, Context};
pub use std::any::Any as AnyComponent;
@ -28,11 +27,11 @@ pub trait ComponentTrait: AnyComponent + Send + Sync {
}
#[allow(unused_variables)]
fn before_render(&mut self, assets: &mut Assets) {
fn before_render(&mut self, context: &mut Context) {
}
#[allow(unused_variables)]
fn default_render(&self, assets: &mut Assets) -> Markup {
fn default_render(&self, context: &mut Context) -> Markup {
html! {}
}
@ -49,24 +48,24 @@ pub fn component_mut<C: 'static>(component: &mut dyn ComponentTrait) -> &mut C {
component.as_mut_any().downcast_mut::<C>().unwrap()
}
pub fn render_component(component: &mut dyn ComponentTrait, assets: &mut Assets) -> Markup {
pub fn render_component(component: &mut dyn ComponentTrait, context: &mut Context) -> Markup {
// Acciones del componente antes de renderizar.
component.before_render(assets);
component.before_render(context);
// Acciones de los módulos antes de renderizar el componente.
run_hooks(
BEFORE_RENDER_COMPONENT_HOOK,
|a| hook_ref::<BeforeRenderComponentHook>(&**a).run(component, assets)
|a| hook_ref::<BeforeRenderComponentHook>(&**a).run(component, context)
);
// Acciones del tema antes de renderizar el componente.
assets.theme().before_render_component(component, assets);
context.theme().before_render_component(component, context);
match component.is_renderable() {
true => {
match assets.theme().render_component(component, assets) {
match context.theme().render_component(component, context) {
Some(html) => html,
None => component.default_render(assets)
None => component.default_render(context)
}
},
false => html! {}

View file

@ -1,5 +1,5 @@
use crate::html::{Markup, html};
use super::{Assets, ComponentTrait};
use super::{Context, ComponentTrait};
use std::sync::{Arc, RwLock};
@ -21,12 +21,12 @@ impl ComponentsHolder {
self.0.push(Arc::new(RwLock::new(component)));
}
pub fn render(&self, assets: &mut Assets) -> Markup {
pub fn render(&self, context: &mut Context) -> Markup {
let mut components = self.0.clone();
components.sort_by_key(|c| c.read().unwrap().weight());
html! {
@for c in components.iter() {
(super::render_component(&mut *c.write().unwrap(), assets))
(super::render_component(&mut *c.write().unwrap(), context))
}
}
}

View file

@ -1,10 +1,10 @@
use crate::core::hook::{HookTrait, AnyHook};
use super::{Assets, ComponentTrait};
use super::{ComponentTrait, Context};
pub const BEFORE_RENDER_COMPONENT_HOOK: &str = "pagetop::hook::before_render_component";
pub struct BeforeRenderComponentHook {
hook: Option<fn(&mut dyn ComponentTrait, &mut Assets)>,
hook: Option<fn(&mut dyn ComponentTrait, &mut Context)>,
weight: isize,
}
@ -30,7 +30,7 @@ impl HookTrait for BeforeRenderComponentHook {
}
impl BeforeRenderComponentHook {
pub fn with_hook(mut self, hook: fn(&mut dyn ComponentTrait, &mut Assets)) -> Self {
pub fn with_hook(mut self, hook: fn(&mut dyn ComponentTrait, &mut Context)) -> Self {
self.hook = Some(hook);
self
}
@ -40,9 +40,9 @@ impl BeforeRenderComponentHook {
self
}
pub fn run(&self, component: &mut dyn ComponentTrait, assets: &mut Assets) {
pub fn run(&self, component: &mut dyn ComponentTrait, context: &mut Context) {
if let Some(hook) = self.hook {
hook(component, assets)
hook(component, context)
}
}
}

View file

@ -2,7 +2,7 @@ use crate::{concat_string, util};
use crate::config::SETTINGS;
use crate::html::{Markup, html};
use crate::core::app;
use crate::core::component::{Assets, ComponentTrait, Favicon};
use crate::core::component::{ComponentTrait, Context, Favicon};
use crate::response::page::Page;
use crate::base::component::Chunck;
@ -28,7 +28,7 @@ pub trait ThemeTrait: BaseTheme + Send + Sync {
#[allow(unused_variables)]
fn before_render_page(&self, page: &mut Page) {
page.assets()
page.context()
.with_favicon(
Favicon::new()
.with_icon("/theme/favicon.png")
@ -56,7 +56,7 @@ pub trait ThemeTrait: BaseTheme + Send + Sync {
meta http-equiv="X-UA-Compatible" content="IE=edge";
meta name="viewport" content=(viewport);
(page.assets().render())
(page.context().render())
}
}
}
@ -86,7 +86,7 @@ pub trait ThemeTrait: BaseTheme + Send + Sync {
fn before_render_component(
&self,
component: &mut dyn ComponentTrait,
assets: &mut Assets
context: &mut Context
) {
/*
Cómo usarlo:
@ -105,7 +105,7 @@ pub trait ThemeTrait: BaseTheme + Send + Sync {
fn render_component(
&self,
component: &dyn ComponentTrait,
assets: &mut Assets
context: &mut Context
) -> Option<Markup> {
None
/*

View file

@ -42,7 +42,7 @@ pub struct Page<'a> {
direction : OptAttr,
title : OptAttr,
description : OptAttr,
assets : Assets,
context : Context,
regions : HashMap<&'a str, ComponentsHolder>,
body_classes: Classes,
template : String,
@ -62,7 +62,7 @@ impl<'a> Page<'a> {
},
title : OptAttr::new(),
description : OptAttr::new(),
assets : Assets::new(),
context : Context::new(),
regions : common_components(),
body_classes: Classes::new_with_default("body"),
template : "default".to_owned(),
@ -136,8 +136,8 @@ impl<'a> Page<'a> {
self.description.option()
}
pub fn assets(&mut self) -> &mut Assets {
&mut self.assets
pub fn context(&mut self) -> &mut Context {
&mut self.context
}
pub fn body_classes(&self) -> &Option<String> {
@ -158,13 +158,13 @@ impl<'a> Page<'a> {
);
// Acciones del tema antes de renderizar la página.
self.assets.theme().before_render_page(self);
self.context.theme().before_render_page(self);
// Primero, renderizar el cuerpo.
let body = self.assets.theme().render_page_body(self);
let body = self.context.theme().render_page_body(self);
// Luego, renderizar la cabecera.
let head = self.assets.theme().render_page_head(self);
let head = self.context.theme().render_page_head(self);
// Finalmente, renderizar la página.
return Ok(html! {
@ -178,7 +178,7 @@ impl<'a> Page<'a> {
pub fn render_region(&mut self, region: &str) -> Markup {
match self.regions.get_mut(region) {
Some(components) => components.render(&mut self.assets),
Some(components) => components.render(&mut self.context),
None => html! {}
}
}
@ -186,7 +186,7 @@ impl<'a> Page<'a> {
// Page EXTRAS.
pub fn using_theme(&mut self, theme_name: &str) -> &mut Self {
self.assets.using_theme(theme_name);
self.context.using_theme(theme_name);
self
}
}