Mejora y simplifica la gestión global de acciones
This commit is contained in:
parent
7c8f51ba86
commit
67ddb8d899
29 changed files with 184 additions and 206 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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::{
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
if let UsingBootstrap::Fn(bootstrap) = bootstrap {
|
||||||
let _ = &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 || {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}};
|
}};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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::*;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue