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]
|
||||
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))
|
||||
);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
|
||||
fn actions(&self) -> Vec<ActionItem> {
|
||||
vec![
|
||||
boxed_migration!(m20220316_000001_create_table_node_type),
|
||||
boxed_migration!(m20220316_000002_create_table_node),
|
||||
boxed_migration!(m20220316_000003_create_table_node_access),
|
||||
boxed_migration!(m20220316_000004_create_table_node_revision),
|
||||
action_item!(ActionBeforeRenderPage => before_render_page, -1)
|
||||
]
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -82,9 +82,3 @@ impl MigrationTrait for Migration {
|
|||
.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.
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -105,9 +105,3 @@ impl MigrationTrait for Migration {
|
|||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
module_name!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ enum NodeAccess {
|
|||
// this node.
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -65,9 +65,3 @@ impl MigrationTrait for Migration {
|
|||
.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.
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -83,9 +83,3 @@ impl MigrationTrait for Migration {
|
|||
.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));
|
||||
}
|
||||
|
||||
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
|
||||
fn migrations(&self) -> Vec<MigrationItem> {
|
||||
vec![
|
||||
boxed_migration!(m20220312_000001_create_table_role),
|
||||
boxed_migration!(m20220312_000002_create_table_role_permission),
|
||||
boxed_migration!(m20220312_000003_create_table_user),
|
||||
boxed_migration!(m20220312_000004_create_table_user_role),
|
||||
migration_item!(m20220312_000001_create_table_role),
|
||||
migration_item!(m20220312_000002_create_table_role_permission),
|
||||
migration_item!(m20220312_000003_create_table_user),
|
||||
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.
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -62,9 +62,3 @@ impl MigrationTrait for Migration {
|
|||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
module_name!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ enum RolePermission {
|
|||
#[derive(Iden)]
|
||||
enum Role { Table, Rid, /* ... */ }
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -56,9 +56,3 @@ impl MigrationTrait for Migration {
|
|||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
module_name!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ enum User {
|
|||
Timezone, // User's time zone.
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -77,9 +77,3 @@ impl MigrationTrait for Migration {
|
|||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
module_name!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ enum User { Table, Uid, /* ... */ }
|
|||
#[derive(Iden)]
|
||||
enum Role { Table, Rid, /* ... */ }
|
||||
|
||||
pub struct Migration;
|
||||
pub_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
|
|
@ -62,9 +62,3 @@ impl MigrationTrait for Migration {
|
|||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
module_name!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::Lazy;
|
||||
use super::{ActionItem, ActionsHolder, ActionTrait};
|
||||
use super::{ActionItem, ActionsHolder};
|
||||
|
||||
use std::sync::RwLock;
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -9,9 +9,9 @@ static ACTIONS: Lazy<RwLock<HashMap<&str, ActionsHolder>>> = Lazy::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 action_name = action.type_name();
|
||||
let action_name = action.machine_name();
|
||||
if let Some(actions) = hmap.get_mut(action_name) {
|
||||
actions.add(action);
|
||||
} 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 {
|
||||
let hmap = ACTIONS.read().unwrap();
|
||||
if let Some(actions) = hmap.get(type_name) {
|
||||
pub fn run_actions<B, F>(machine_name: &'static str, f: F)
|
||||
where
|
||||
F: FnMut(&ActionItem) -> B
|
||||
{
|
||||
if let Some(actions) = ACTIONS.read().unwrap().get(machine_name) {
|
||||
actions.iter_map(f)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,12 @@
|
|||
use crate::util;
|
||||
|
||||
pub use std::any::Any as AnyAction;
|
||||
|
||||
pub trait BaseAction {
|
||||
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 {
|
||||
pub trait ActionTrait: AnyAction + Send + Sync {
|
||||
fn new() -> Self where Self: Sized;
|
||||
|
||||
fn machine_name(&self) -> &'static str {
|
||||
std::any::type_name::<Self>()
|
||||
}
|
||||
|
||||
fn weight(&self) -> isize {
|
||||
0
|
||||
}
|
||||
|
|
@ -20,20 +14,6 @@ pub trait ActionTrait: AnyAction + BaseAction + Send + Sync {
|
|||
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 {
|
||||
action.as_ref_any().downcast_ref::<A>().unwrap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,13 @@ use std::sync::{Arc, RwLock};
|
|||
|
||||
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>>>);
|
||||
|
||||
impl ActionsHolder {
|
||||
|
|
@ -12,19 +18,23 @@ impl ActionsHolder {
|
|||
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();
|
||||
container.add(action);
|
||||
container
|
||||
}
|
||||
|
||||
pub fn add(&mut self, action: impl ActionTrait) {
|
||||
pub fn add(&mut self, action: ActionItem) {
|
||||
let mut actions = self.0.write().unwrap();
|
||||
actions.push(Box::new(action));
|
||||
actions.push(action);
|
||||
actions.sort_by_key(|a| a.weight());
|
||||
}
|
||||
|
||||
pub fn iter_map<B, F>(&self, f: F) where Self: Sized, F: FnMut(&ActionItem) -> B {
|
||||
let _ = self.0.read().unwrap().iter().map(f);
|
||||
pub fn iter_map<B, F>(&self, f: 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::{
|
||||
ActionTrait,
|
||||
AnyAction,
|
||||
BaseAction,
|
||||
action_ref,
|
||||
};
|
||||
|
||||
mod holder;
|
||||
pub use holder::{
|
||||
ActionItem,
|
||||
};
|
||||
pub(crate) use holder::{
|
||||
ActionsHolder,
|
||||
};
|
||||
|
||||
mod all;
|
||||
pub use all::{
|
||||
register_action,
|
||||
run_actions,
|
||||
};
|
||||
pub(crate) use all::{
|
||||
add_action,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,24 +1,25 @@
|
|||
use crate::api::action::{ActionTrait, AnyAction};
|
||||
use super::{ComponentTrait, PageAssets};
|
||||
|
||||
pub enum TypeAction {
|
||||
BeforeRenderComponent(fn(&mut dyn ComponentTrait, &mut PageAssets)),
|
||||
None,
|
||||
}
|
||||
pub const ACTION_BEFORE_RENDER_COMPONENT: &str = "pagetop::render::before_render_component";
|
||||
|
||||
pub struct ComponentAction {
|
||||
action: TypeAction,
|
||||
pub struct ActionBeforeRenderComponent {
|
||||
action: Option<fn(&mut dyn ComponentTrait, &mut PageAssets)>,
|
||||
weight: isize,
|
||||
}
|
||||
|
||||
impl ActionTrait for ComponentAction {
|
||||
impl ActionTrait for ActionBeforeRenderComponent {
|
||||
fn new() -> Self {
|
||||
ComponentAction {
|
||||
action: TypeAction::None,
|
||||
ActionBeforeRenderComponent {
|
||||
action: None,
|
||||
weight: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn machine_name(&self) -> &'static str {
|
||||
ACTION_BEFORE_RENDER_COMPONENT
|
||||
}
|
||||
|
||||
fn weight(&self) -> isize {
|
||||
self.weight
|
||||
}
|
||||
|
|
@ -28,28 +29,20 @@ impl ActionTrait for ComponentAction {
|
|||
}
|
||||
}
|
||||
|
||||
impl ComponentAction {
|
||||
pub fn new(action: TypeAction) -> Self {
|
||||
ComponentAction {
|
||||
action,
|
||||
weight: 0,
|
||||
}
|
||||
impl ActionBeforeRenderComponent {
|
||||
pub fn with_action(mut self, action: fn(&mut dyn ComponentTrait, &mut PageAssets)) -> Self {
|
||||
self.action = Some(action);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn new_with_weight(action: TypeAction, weight: isize) -> Self {
|
||||
ComponentAction {
|
||||
action,
|
||||
weight,
|
||||
}
|
||||
pub fn with_weight(mut self, weight: isize) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn before_render_component(
|
||||
&self,
|
||||
component: &mut dyn ComponentTrait,
|
||||
assets: &mut PageAssets)
|
||||
{
|
||||
if let TypeAction::BeforeRenderComponent(f) = self.action {
|
||||
f(component, assets)
|
||||
pub fn run(&self, component: &mut dyn ComponentTrait, assets: &mut PageAssets) {
|
||||
if let Some(action) = self.action {
|
||||
action(component, assets)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::html::{Markup, html};
|
|||
use crate::util;
|
||||
use crate::api::action::{action_ref, run_actions};
|
||||
use super::PageAssets;
|
||||
use super::action::ComponentAction;
|
||||
use super::{ACTION_BEFORE_RENDER_COMPONENT, ActionBeforeRenderComponent};
|
||||
|
||||
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.
|
||||
run_actions(
|
||||
"",
|
||||
|a| action_ref::<ComponentAction>(&**a).before_render_component(component, assets)
|
||||
ACTION_BEFORE_RENDER_COMPONENT,
|
||||
|a| action_ref::<ActionBeforeRenderComponent>(&**a).run(component, assets)
|
||||
);
|
||||
|
||||
// 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;
|
||||
pub use assets::{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{Lazy, app, run_now, trace};
|
||||
use crate::api::action::add_action;
|
||||
use crate::db::*;
|
||||
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"))]
|
||||
pub fn migrations() {
|
||||
pub fn run_migrations() {
|
||||
run_now({
|
||||
struct Migrator;
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
fn migrations() -> Vec<MigrationItem> {
|
||||
let mut migrations = vec![];
|
||||
for m in MODULES.read().unwrap().iter() {
|
||||
migrations.append(&mut m.migrations());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use crate::{app, util};
|
||||
use crate::api::action::ActionItem;
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
use crate::db;
|
||||
use crate::db::MigrationItem;
|
||||
|
||||
pub trait BaseModule {
|
||||
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 actions(&self) -> Vec<ActionItem> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
#[allow(unused_variables)]
|
||||
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
|
||||
fn migrations(&self) -> Vec<MigrationItem> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,10 @@ pub struct Application {
|
|||
server: app::Server,
|
||||
}
|
||||
|
||||
pub fn essence() {
|
||||
trace::info!("No bootstrap configured");
|
||||
}
|
||||
pub enum UsingBootstrap {Fn(fn()), No}
|
||||
|
||||
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.
|
||||
app::banner::print_on_startup();
|
||||
|
||||
|
|
@ -36,15 +34,20 @@ impl Application {
|
|||
|
||||
// Ejecuta la función de inicio de la aplicación.
|
||||
trace::info!("Calling application bootstrap");
|
||||
let _ = &bootstrap();
|
||||
if let UsingBootstrap::Fn(bootstrap) = bootstrap {
|
||||
let _ = &bootstrap();
|
||||
}
|
||||
|
||||
// Registra el módulo de presentación de PageTop.
|
||||
// Normalmente se sobrecargará en la función de inicio.
|
||||
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).
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
module::all::migrations();
|
||||
module::all::run_migrations();
|
||||
|
||||
// Prepara el servidor web.
|
||||
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 type MigrationItem = Box<dyn MigrationTrait>;
|
||||
|
||||
#[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 ) => {{
|
||||
Box::new(migration::$migration_module::Migration)
|
||||
}};
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ impl Classes {
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
pub use crate::{
|
||||
args,
|
||||
concat_string,
|
||||
module_name,
|
||||
theme_static_files,
|
||||
};
|
||||
|
||||
|
|
@ -14,19 +13,24 @@ pub use crate::localize;
|
|||
pub use crate::html::*;
|
||||
|
||||
#[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::*,
|
||||
component::*,
|
||||
module::*,
|
||||
theme::*,
|
||||
};
|
||||
}};
|
||||
|
||||
pub use crate::response::page::*;
|
||||
|
||||
pub use crate::app;
|
||||
pub use crate::app::application::{Application, essence};
|
||||
pub use crate::app::application::{Application, UsingBootstrap};
|
||||
|
||||
pub use crate::base::component::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,25 @@
|
|||
use crate::api::action::{ActionTrait, AnyAction};
|
||||
use crate::api::component::{ComponentTrait, PageAssets};
|
||||
use super::Page;
|
||||
|
||||
pub enum TypeAction {
|
||||
BeforeRenderPage(fn(&mut Page)),
|
||||
BeforeRenderComponent(fn(&mut dyn ComponentTrait, &mut PageAssets)),
|
||||
None,
|
||||
}
|
||||
pub const ACTION_BEFORE_RENDER_PAGE: &str = "pagetop::render::before_render_page";
|
||||
|
||||
pub struct PageAction {
|
||||
action: TypeAction,
|
||||
pub struct ActionBeforeRenderPage {
|
||||
action: Option<fn(&mut Page)>,
|
||||
weight: isize,
|
||||
}
|
||||
|
||||
impl ActionTrait for PageAction {
|
||||
impl ActionTrait for ActionBeforeRenderPage {
|
||||
fn new() -> Self {
|
||||
PageAction {
|
||||
action: TypeAction::None,
|
||||
ActionBeforeRenderPage {
|
||||
action: None,
|
||||
weight: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn machine_name(&self) -> &'static str {
|
||||
ACTION_BEFORE_RENDER_PAGE
|
||||
}
|
||||
|
||||
fn weight(&self) -> isize {
|
||||
self.weight
|
||||
}
|
||||
|
|
@ -30,34 +29,20 @@ impl ActionTrait for PageAction {
|
|||
}
|
||||
}
|
||||
|
||||
impl PageAction {
|
||||
pub fn new(action: TypeAction) -> Self {
|
||||
PageAction {
|
||||
action,
|
||||
weight: 0,
|
||||
}
|
||||
impl ActionBeforeRenderPage {
|
||||
pub fn with_action(mut self, action: fn(&mut Page)) -> Self {
|
||||
self.action = Some(action);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn new_with_weight(action: TypeAction, weight: isize) -> Self {
|
||||
PageAction {
|
||||
action,
|
||||
weight,
|
||||
}
|
||||
pub fn with_weight(mut self, weight: isize) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn before_render_page(&self, page: &mut Page) {
|
||||
if let TypeAction::BeforeRenderPage(f) = self.action {
|
||||
f(page)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn before_render_component(
|
||||
&self,
|
||||
component: &mut dyn ComponentTrait,
|
||||
assets: &mut PageAssets)
|
||||
{
|
||||
if let TypeAction::BeforeRenderComponent(f) = self.action {
|
||||
f(component, assets)
|
||||
pub fn run(&self, page: &mut Page) {
|
||||
if let Some(action) = self.action {
|
||||
action(page)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
pub mod action;
|
||||
mod action;
|
||||
pub use action::{
|
||||
ACTION_BEFORE_RENDER_PAGE,
|
||||
ActionBeforeRenderPage,
|
||||
};
|
||||
|
||||
mod page;
|
||||
pub use page::Page;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use crate::api::component::*;
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::action::PageAction;
|
||||
use super::{ACTION_BEFORE_RENDER_PAGE, ActionBeforeRenderPage};
|
||||
|
||||
static DEFAULT_LANGUAGE: Lazy<Option<String>> = Lazy::new(|| {
|
||||
let language = SETTINGS.app.language[..2].to_lowercase();
|
||||
|
|
@ -151,10 +151,10 @@ impl<'a> Page<'a> {
|
|||
// Page RENDER.
|
||||
|
||||
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(
|
||||
"",
|
||||
|a| action_ref::<PageAction>(&**a).before_render_page(self)
|
||||
ACTION_BEFORE_RENDER_PAGE,
|
||||
|a| action_ref::<ActionBeforeRenderPage>(&**a).run(self)
|
||||
);
|
||||
|
||||
// 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_rules! theme_static_files {
|
||||
( $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 {
|
||||
return type_name;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue