Mejora y simplifica la gestión global de acciones

This commit is contained in:
Manuel Cillero 2022-05-05 21:43:00 +02:00
parent 7c8f51ba86
commit 67ddb8d899
29 changed files with 184 additions and 206 deletions

View file

@ -8,5 +8,5 @@ fn bootstrap() {
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
Application::prepare(bootstrap).await?.run()?.await Application::prepare(UsingBootstrap::Fn(bootstrap)).await?.run()?.await
} }

View file

@ -21,4 +21,14 @@ impl ModuleTrait for Admin {
.route("", app::web::get().to(summary::summary)) .route("", app::web::get().to(summary::summary))
); );
} }
fn actions(&self) -> Vec<ActionItem> {
vec![
action_item!(ActionBeforeRenderPage => before_render_page)
]
}
}
fn before_render_page(page: &mut Page) {
page.alter_body_classes("test-admin", ClassesOp::Add);
} }

View file

@ -20,12 +20,18 @@ impl ModuleTrait for Node {
cfg.route("/node", app::web::get().to(node)); cfg.route("/node", app::web::get().to(node));
} }
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> { fn actions(&self) -> Vec<ActionItem> {
vec![ vec![
boxed_migration!(m20220316_000001_create_table_node_type), action_item!(ActionBeforeRenderPage => before_render_page, -1)
boxed_migration!(m20220316_000002_create_table_node), ]
boxed_migration!(m20220316_000003_create_table_node_access), }
boxed_migration!(m20220316_000004_create_table_node_revision),
fn migrations(&self) -> Vec<MigrationItem> {
vec![
migration_item!(m20220316_000001_create_table_node_type),
migration_item!(m20220316_000002_create_table_node),
migration_item!(m20220316_000003_create_table_node_access),
migration_item!(m20220316_000004_create_table_node_revision),
] ]
} }
} }
@ -37,3 +43,7 @@ async fn node() -> app::Result<Markup> {
) )
.render() .render()
} }
fn before_render_page(page: &mut Page) {
page.alter_body_classes("test-node", ClassesOp::Add);
}

View file

@ -19,7 +19,7 @@ enum NodeType {
// different from the current type name if the locked field is 0. // different from the current type name if the locked field is 0.
} }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -82,9 +82,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -26,7 +26,7 @@ enum Node {
Translate, // A boolean indicating whether this translation page needs to be updated. Translate, // A boolean indicating whether this translation page needs to be updated.
} }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -105,9 +105,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -18,7 +18,7 @@ enum NodeAccess {
// this node. // this node.
} }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -65,9 +65,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -20,7 +20,7 @@ enum NodeRevision {
// be displayed at the top of lists in which it appears. // be displayed at the top of lists in which it appears.
} }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -83,9 +83,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -19,12 +19,12 @@ impl ModuleTrait for User {
cfg.route("/user/login", app::web::get().to(login)); cfg.route("/user/login", app::web::get().to(login));
} }
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> { fn migrations(&self) -> Vec<MigrationItem> {
vec![ vec![
boxed_migration!(m20220312_000001_create_table_role), migration_item!(m20220312_000001_create_table_role),
boxed_migration!(m20220312_000002_create_table_role_permission), migration_item!(m20220312_000002_create_table_role_permission),
boxed_migration!(m20220312_000003_create_table_user), migration_item!(m20220312_000003_create_table_user),
boxed_migration!(m20220312_000004_create_table_user_role), migration_item!(m20220312_000004_create_table_user_role),
] ]
} }
} }

View file

@ -9,7 +9,7 @@ enum Role {
Weight, // The weight of this role in listings and the user interface. Weight, // The weight of this role in listings and the user interface.
} }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -62,9 +62,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -11,7 +11,7 @@ enum RolePermission {
#[derive(Iden)] #[derive(Iden)]
enum Role { Table, Rid, /* ... */ } enum Role { Table, Rid, /* ... */ }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -56,9 +56,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -16,7 +16,7 @@ enum User {
Timezone, // User's time zone. Timezone, // User's time zone.
} }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -77,9 +77,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -14,7 +14,7 @@ enum User { Table, Uid, /* ... */ }
#[derive(Iden)] #[derive(Iden)]
enum Role { Table, Rid, /* ... */ } enum Role { Table, Rid, /* ... */ }
pub struct Migration; pub_migration!(Migration);
#[async_trait::async_trait] #[async_trait::async_trait]
impl MigrationTrait for Migration { impl MigrationTrait for Migration {
@ -62,9 +62,3 @@ impl MigrationTrait for Migration {
.await .await
} }
} }
impl MigrationName for Migration {
fn name(&self) -> &str {
module_name!()
}
}

View file

@ -1,5 +1,5 @@
use crate::Lazy; use crate::Lazy;
use super::{ActionItem, ActionsHolder, ActionTrait}; use super::{ActionItem, ActionsHolder};
use std::sync::RwLock; use std::sync::RwLock;
use std::collections::HashMap; use std::collections::HashMap;
@ -9,9 +9,9 @@ static ACTIONS: Lazy<RwLock<HashMap<&str, ActionsHolder>>> = Lazy::new(|| {
RwLock::new(HashMap::new()) RwLock::new(HashMap::new())
}); });
pub fn register_action(action: impl ActionTrait) { pub fn add_action(action: ActionItem) {
let mut hmap = ACTIONS.write().unwrap(); let mut hmap = ACTIONS.write().unwrap();
let action_name = action.type_name(); let action_name = action.machine_name();
if let Some(actions) = hmap.get_mut(action_name) { if let Some(actions) = hmap.get_mut(action_name) {
actions.add(action); actions.add(action);
} else { } else {
@ -19,9 +19,11 @@ pub fn register_action(action: impl ActionTrait) {
} }
} }
pub fn run_actions<B, F>(type_name: &'static str, f: F) where F: FnMut(&ActionItem) -> B { pub fn run_actions<B, F>(machine_name: &'static str, f: F)
let hmap = ACTIONS.read().unwrap(); where
if let Some(actions) = hmap.get(type_name) { F: FnMut(&ActionItem) -> B
{
if let Some(actions) = ACTIONS.read().unwrap().get(machine_name) {
actions.iter_map(f) actions.iter_map(f)
} }
} }

View file

@ -1,18 +1,12 @@
use crate::util;
pub use std::any::Any as AnyAction; pub use std::any::Any as AnyAction;
pub trait BaseAction { pub trait ActionTrait: AnyAction + Send + Sync {
fn type_name(&self) -> &'static str;
fn single_name(&self) -> &'static str;
fn qualified_name(&self, last: usize) -> &'static str;
}
pub trait ActionTrait: AnyAction + BaseAction + Send + Sync {
fn new() -> Self where Self: Sized; fn new() -> Self where Self: Sized;
fn machine_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
fn weight(&self) -> isize { fn weight(&self) -> isize {
0 0
} }
@ -20,20 +14,6 @@ pub trait ActionTrait: AnyAction + BaseAction + Send + Sync {
fn as_ref_any(&self) -> &dyn AnyAction; fn as_ref_any(&self) -> &dyn AnyAction;
} }
impl<C: ?Sized + ActionTrait> BaseAction for C {
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
fn single_name(&self) -> &'static str {
util::partial_type_name(std::any::type_name::<Self>(), 1)
}
fn qualified_name(&self, last: usize) -> &'static str {
util::partial_type_name(std::any::type_name::<Self>(), last)
}
}
pub fn action_ref<A: 'static>(action: &dyn ActionTrait) -> &A { pub fn action_ref<A: 'static>(action: &dyn ActionTrait) -> &A {
action.as_ref_any().downcast_ref::<A>().unwrap() action.as_ref_any().downcast_ref::<A>().unwrap()
} }

View file

@ -4,7 +4,13 @@ use std::sync::{Arc, RwLock};
pub type ActionItem = Box<dyn ActionTrait>; pub type ActionItem = Box<dyn ActionTrait>;
#[derive(Clone)] #[macro_export]
macro_rules! action_item {
( $action:ident => $f:ident $(, $weight:expr)? ) => {{
Box::new($action::new().with_action($f)$(.with_weight($weight))?)
}};
}
pub struct ActionsHolder(Arc<RwLock<Vec<ActionItem>>>); pub struct ActionsHolder(Arc<RwLock<Vec<ActionItem>>>);
impl ActionsHolder { impl ActionsHolder {
@ -12,19 +18,23 @@ impl ActionsHolder {
ActionsHolder(Arc::new(RwLock::new(Vec::new()))) ActionsHolder(Arc::new(RwLock::new(Vec::new())))
} }
pub fn new_with(action: impl ActionTrait) -> Self { pub fn new_with(action: ActionItem) -> Self {
let mut container = ActionsHolder::new(); let mut container = ActionsHolder::new();
container.add(action); container.add(action);
container container
} }
pub fn add(&mut self, action: impl ActionTrait) { pub fn add(&mut self, action: ActionItem) {
let mut actions = self.0.write().unwrap(); let mut actions = self.0.write().unwrap();
actions.push(Box::new(action)); actions.push(action);
actions.sort_by_key(|a| a.weight()); actions.sort_by_key(|a| a.weight());
} }
pub fn iter_map<B, F>(&self, f: F) where Self: Sized, F: FnMut(&ActionItem) -> B { pub fn iter_map<B, F>(&self, f: F)
let _ = self.0.read().unwrap().iter().map(f); where
Self: Sized,
F: FnMut(&ActionItem) -> B,
{
let _: Vec<_> = self.0.read().unwrap().iter().map(f).collect();
} }
} }

View file

@ -2,18 +2,21 @@ mod definition;
pub use definition::{ pub use definition::{
ActionTrait, ActionTrait,
AnyAction, AnyAction,
BaseAction,
action_ref, action_ref,
}; };
mod holder; mod holder;
pub use holder::{ pub use holder::{
ActionItem, ActionItem,
};
pub(crate) use holder::{
ActionsHolder, ActionsHolder,
}; };
mod all; mod all;
pub use all::{ pub use all::{
register_action,
run_actions, run_actions,
}; };
pub(crate) use all::{
add_action,
};

View file

@ -1,24 +1,25 @@
use crate::api::action::{ActionTrait, AnyAction}; use crate::api::action::{ActionTrait, AnyAction};
use super::{ComponentTrait, PageAssets}; use super::{ComponentTrait, PageAssets};
pub enum TypeAction { pub const ACTION_BEFORE_RENDER_COMPONENT: &str = "pagetop::render::before_render_component";
BeforeRenderComponent(fn(&mut dyn ComponentTrait, &mut PageAssets)),
None,
}
pub struct ComponentAction { pub struct ActionBeforeRenderComponent {
action: TypeAction, action: Option<fn(&mut dyn ComponentTrait, &mut PageAssets)>,
weight: isize, weight: isize,
} }
impl ActionTrait for ComponentAction { impl ActionTrait for ActionBeforeRenderComponent {
fn new() -> Self { fn new() -> Self {
ComponentAction { ActionBeforeRenderComponent {
action: TypeAction::None, action: None,
weight: 0, weight: 0,
} }
} }
fn machine_name(&self) -> &'static str {
ACTION_BEFORE_RENDER_COMPONENT
}
fn weight(&self) -> isize { fn weight(&self) -> isize {
self.weight self.weight
} }
@ -28,28 +29,20 @@ impl ActionTrait for ComponentAction {
} }
} }
impl ComponentAction { impl ActionBeforeRenderComponent {
pub fn new(action: TypeAction) -> Self { pub fn with_action(mut self, action: fn(&mut dyn ComponentTrait, &mut PageAssets)) -> Self {
ComponentAction { self.action = Some(action);
action, self
weight: 0,
}
} }
pub fn new_with_weight(action: TypeAction, weight: isize) -> Self { pub fn with_weight(mut self, weight: isize) -> Self {
ComponentAction { self.weight = weight;
action, self
weight,
}
} }
pub fn before_render_component( pub fn run(&self, component: &mut dyn ComponentTrait, assets: &mut PageAssets) {
&self, if let Some(action) = self.action {
component: &mut dyn ComponentTrait, action(component, assets)
assets: &mut PageAssets)
{
if let TypeAction::BeforeRenderComponent(f) = self.action {
f(component, assets)
} }
} }
} }

View file

@ -2,7 +2,7 @@ use crate::html::{Markup, html};
use crate::util; use crate::util;
use crate::api::action::{action_ref, run_actions}; use crate::api::action::{action_ref, run_actions};
use super::PageAssets; use super::PageAssets;
use super::action::ComponentAction; use super::{ACTION_BEFORE_RENDER_COMPONENT, ActionBeforeRenderComponent};
pub use std::any::Any as AnyComponent; pub use std::any::Any as AnyComponent;
@ -76,8 +76,8 @@ pub fn render_component(component: &mut dyn ComponentTrait, assets: &mut PageAss
// Acciones de los módulos antes de renderizar el componente. // Acciones de los módulos antes de renderizar el componente.
run_actions( run_actions(
"", ACTION_BEFORE_RENDER_COMPONENT,
|a| action_ref::<ComponentAction>(&**a).before_render_component(component, assets) |a| action_ref::<ActionBeforeRenderComponent>(&**a).run(component, assets)
); );
// Acciones del tema antes de renderizar el componente. // Acciones del tema antes de renderizar el componente.

View file

@ -1,4 +1,8 @@
pub mod action; mod action;
pub use action::{
ACTION_BEFORE_RENDER_COMPONENT,
ActionBeforeRenderComponent,
};
mod assets; mod assets;
pub use assets::{ pub use assets::{

View file

@ -1,4 +1,5 @@
use crate::{Lazy, app, run_now, trace}; use crate::{Lazy, app, run_now, trace};
use crate::api::action::add_action;
use crate::db::*; use crate::db::*;
use super::ModuleTrait; use super::ModuleTrait;
@ -37,12 +38,20 @@ pub fn modules(cfg: &mut app::web::ServiceConfig) {
} }
} }
pub fn register_actions() {
for m in MODULES.read().unwrap().iter() {
for a in m.actions().into_iter() {
add_action(a);
}
}
}
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
pub fn migrations() { pub fn run_migrations() {
run_now({ run_now({
struct Migrator; struct Migrator;
impl MigratorTrait for Migrator { impl MigratorTrait for Migrator {
fn migrations() -> Vec<Box<dyn MigrationTrait>> { fn migrations() -> Vec<MigrationItem> {
let mut migrations = vec![]; let mut migrations = vec![];
for m in MODULES.read().unwrap().iter() { for m in MODULES.read().unwrap().iter() {
migrations.append(&mut m.migrations()); migrations.append(&mut m.migrations());

View file

@ -1,7 +1,8 @@
use crate::{app, util}; use crate::{app, util};
use crate::api::action::ActionItem;
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
use crate::db; use crate::db::MigrationItem;
pub trait BaseModule { pub trait BaseModule {
fn type_name(&self) -> &'static str; fn type_name(&self) -> &'static str;
@ -25,9 +26,13 @@ pub trait ModuleTrait: BaseModule + Send + Sync {
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) { fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
} }
fn actions(&self) -> Vec<ActionItem> {
vec![]
}
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
#[allow(unused_variables)] #[allow(unused_variables)]
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> { fn migrations(&self) -> Vec<MigrationItem> {
vec![] vec![]
} }

View file

@ -9,12 +9,10 @@ pub struct Application {
server: app::Server, server: app::Server,
} }
pub fn essence() { pub enum UsingBootstrap {Fn(fn()), No}
trace::info!("No bootstrap configured");
}
impl Application { impl Application {
pub async fn prepare(bootstrap: fn()) -> Result<Self, Error> { pub async fn prepare(bootstrap: UsingBootstrap) -> Result<Self, Error> {
// Rótulo de presentación. // Rótulo de presentación.
app::banner::print_on_startup(); app::banner::print_on_startup();
@ -36,15 +34,20 @@ impl Application {
// Ejecuta la función de inicio de la aplicación. // Ejecuta la función de inicio de la aplicación.
trace::info!("Calling application bootstrap"); trace::info!("Calling application bootstrap");
let _ = &bootstrap(); if let UsingBootstrap::Fn(bootstrap) = bootstrap {
let _ = &bootstrap();
}
// Registra el módulo de presentación de PageTop. // Registra el módulo de presentación de PageTop.
// Normalmente se sobrecargará en la función de inicio. // Normalmente se sobrecargará en la función de inicio.
module::register_module(&base::module::demopage::Demopage); module::register_module(&base::module::demopage::Demopage);
// Registra las acciones de todos los módulos.
module::all::register_actions();
// Actualizaciones pendientes de la base de datos (opcional). // Actualizaciones pendientes de la base de datos (opcional).
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
module::all::migrations(); module::all::run_migrations();
// Prepara el servidor web. // Prepara el servidor web.
let server = app::HttpServer::new(move || { let server = app::HttpServer::new(move || {

View file

@ -4,8 +4,23 @@ pub use sea_orm::{DatabaseConnection as DbConn, ExecResult, QueryResult};
pub use sea_schema::migration::prelude::*; pub use sea_schema::migration::prelude::*;
pub type MigrationItem = Box<dyn MigrationTrait>;
#[macro_export] #[macro_export]
macro_rules! boxed_migration { macro_rules! pub_migration {
( $migration:ident ) => {
pub struct $migration;
impl MigrationName for $migration {
fn name(&self) -> &str {
crate::util::partial_type_name(module_path!(), 1)
}
}
};
}
#[macro_export]
macro_rules! migration_item {
( $migration_module:ident ) => {{ ( $migration_module:ident ) => {{
Box::new(migration::$migration_module::Migration) Box::new(migration::$migration_module::Migration)
}}; }};

View file

@ -72,7 +72,7 @@ impl Classes {
ClassesOp::SetDefault => self.default = classes.to_owned(), ClassesOp::SetDefault => self.default = classes.to_owned(),
} }
self.option = Some(concat_string!(self.default, " ", self.added).trim().to_owned()); self.option = Some(concat_string!(self.default, " ", self.added.trim()).to_owned());
self self
} }

View file

@ -4,7 +4,6 @@
pub use crate::{ pub use crate::{
args, args,
concat_string, concat_string,
module_name,
theme_static_files, theme_static_files,
}; };
@ -14,19 +13,24 @@ pub use crate::localize;
pub use crate::html::*; pub use crate::html::*;
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
pub use crate::{db, db::*, boxed_migration}; pub use crate::{
db,
db::*,
pub_migration,
migration_item,
};
pub use crate::api::{ pub use crate::{action_item, api::{
action::*, action::*,
component::*, component::*,
module::*, module::*,
theme::*, theme::*,
}; }};
pub use crate::response::page::*; pub use crate::response::page::*;
pub use crate::app; pub use crate::app;
pub use crate::app::application::{Application, essence}; pub use crate::app::application::{Application, UsingBootstrap};
pub use crate::base::component::*; pub use crate::base::component::*;

View file

@ -1,26 +1,25 @@
use crate::api::action::{ActionTrait, AnyAction}; use crate::api::action::{ActionTrait, AnyAction};
use crate::api::component::{ComponentTrait, PageAssets};
use super::Page; use super::Page;
pub enum TypeAction { pub const ACTION_BEFORE_RENDER_PAGE: &str = "pagetop::render::before_render_page";
BeforeRenderPage(fn(&mut Page)),
BeforeRenderComponent(fn(&mut dyn ComponentTrait, &mut PageAssets)),
None,
}
pub struct PageAction { pub struct ActionBeforeRenderPage {
action: TypeAction, action: Option<fn(&mut Page)>,
weight: isize, weight: isize,
} }
impl ActionTrait for PageAction { impl ActionTrait for ActionBeforeRenderPage {
fn new() -> Self { fn new() -> Self {
PageAction { ActionBeforeRenderPage {
action: TypeAction::None, action: None,
weight: 0, weight: 0,
} }
} }
fn machine_name(&self) -> &'static str {
ACTION_BEFORE_RENDER_PAGE
}
fn weight(&self) -> isize { fn weight(&self) -> isize {
self.weight self.weight
} }
@ -30,34 +29,20 @@ impl ActionTrait for PageAction {
} }
} }
impl PageAction { impl ActionBeforeRenderPage {
pub fn new(action: TypeAction) -> Self { pub fn with_action(mut self, action: fn(&mut Page)) -> Self {
PageAction { self.action = Some(action);
action, self
weight: 0,
}
} }
pub fn new_with_weight(action: TypeAction, weight: isize) -> Self { pub fn with_weight(mut self, weight: isize) -> Self {
PageAction { self.weight = weight;
action, self
weight,
}
} }
pub fn before_render_page(&self, page: &mut Page) { pub fn run(&self, page: &mut Page) {
if let TypeAction::BeforeRenderPage(f) = self.action { if let Some(action) = self.action {
f(page) action(page)
}
}
pub fn before_render_component(
&self,
component: &mut dyn ComponentTrait,
assets: &mut PageAssets)
{
if let TypeAction::BeforeRenderComponent(f) = self.action {
f(component, assets)
} }
} }
} }

View file

@ -1,4 +1,8 @@
pub mod action; mod action;
pub use action::{
ACTION_BEFORE_RENDER_PAGE,
ActionBeforeRenderPage,
};
mod page; mod page;
pub use page::Page; pub use page::Page;

View file

@ -6,7 +6,7 @@ use crate::api::component::*;
use std::collections::HashMap; use std::collections::HashMap;
use super::action::PageAction; use super::{ACTION_BEFORE_RENDER_PAGE, ActionBeforeRenderPage};
static DEFAULT_LANGUAGE: Lazy<Option<String>> = Lazy::new(|| { static DEFAULT_LANGUAGE: Lazy<Option<String>> = Lazy::new(|| {
let language = SETTINGS.app.language[..2].to_lowercase(); let language = SETTINGS.app.language[..2].to_lowercase();
@ -151,10 +151,10 @@ impl<'a> Page<'a> {
// Page RENDER. // Page RENDER.
pub fn render(&mut self) -> app::Result<Markup> { pub fn render(&mut self) -> app::Result<Markup> {
// Acciones de los módulos antes de renderizar el tema. // Acciones de los módulos antes de renderizar la página.
run_actions( run_actions(
"", ACTION_BEFORE_RENDER_PAGE,
|a| action_ref::<PageAction>(&**a).before_render_page(self) |a| action_ref::<ActionBeforeRenderPage>(&**a).run(self)
); );
// Acciones del tema antes de renderizar la página. // Acciones del tema antes de renderizar la página.

View file

@ -18,17 +18,6 @@ macro_rules! args {
}}; }};
} }
#[macro_export]
macro_rules! module_name {
() => {{
let name = module_path!();
match name.rfind("::") {
Some(position) => &name[(position + 2)..],
None => name
}
}};
}
#[macro_export] #[macro_export]
macro_rules! theme_static_files { macro_rules! theme_static_files {
( $cfg:ident, $dir:expr ) => {{ ( $cfg:ident, $dir:expr ) => {{
@ -47,7 +36,7 @@ macro_rules! theme_static_files {
}}; }};
} }
pub(crate) fn partial_type_name(type_name: &'static str, last: usize) -> &'static str { pub fn partial_type_name(type_name: &'static str, last: usize) -> &'static str {
if last == 0 { if last == 0 {
return type_name; return type_name;
} }