Libera la versión de desarrollo 0.0.2
This commit is contained in:
parent
516d9683da
commit
fbc6ab2adf
77 changed files with 651 additions and 161 deletions
|
|
@ -2,4 +2,7 @@
|
|||
members = [
|
||||
"drust",
|
||||
"pagetop",
|
||||
"pagetop-admin",
|
||||
"pagetop-user",
|
||||
"pagetop-node",
|
||||
]
|
||||
|
|
@ -19,3 +19,6 @@ default-features = false
|
|||
|
||||
[dependencies]
|
||||
actix-web = "3.3.3"
|
||||
pagetop-admin = { path = "../pagetop-admin" }
|
||||
pagetop-user = { path = "../pagetop-user" }
|
||||
pagetop-node = { path = "../pagetop-node" }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
fn bootstrap() {
|
||||
register_module(&pagetop_admin::AdminModule);
|
||||
register_module(&pagetop_user::UserModule);
|
||||
register_module(&pagetop_node::NodeModule);
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
Application::prepare(essence).await?.run()?.await
|
||||
Application::prepare(bootstrap).await?.run()?.await
|
||||
}
|
||||
|
|
|
|||
17
pagetop-admin/Cargo.toml
Normal file
17
pagetop-admin/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "pagetop-admin"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
description = """\
|
||||
Allows content to be submitted to the site and displayed on pages.\
|
||||
"""
|
||||
homepage = "https://suitepro.cillero.es/projects/drust"
|
||||
repository = "https://gitlab.com/manuelcillero/drust"
|
||||
|
||||
[dependencies]
|
||||
pagetop = { path = "../pagetop" }
|
||||
maud = { version = "0.23.0" }
|
||||
24
pagetop-admin/src/lib.rs
Normal file
24
pagetop-admin/src/lib.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
localize!("src/locales");
|
||||
|
||||
mod summary;
|
||||
|
||||
pub struct AdminModule;
|
||||
|
||||
impl ModuleTrait for AdminModule {
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
cfg.service(
|
||||
app::web::scope("/admin")
|
||||
.route("", app::web::get().to(summary::summary))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::prelude::*;
|
||||
use pagetop::prelude::*;
|
||||
use super::l;
|
||||
|
||||
pub async fn summary() -> server::Result<Markup> {
|
||||
pub async fn summary() -> app::Result<Markup> {
|
||||
let top_menu = Menu::prepare()
|
||||
.add(MenuItem::label(l("module_fullname").as_str()))
|
||||
.add(MenuItem::link("Opción 2", "https://www.google.es"))
|
||||
16
pagetop-node/Cargo.toml
Normal file
16
pagetop-node/Cargo.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "pagetop-node"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
description = """\
|
||||
Allows content to be submitted to the site and displayed on pages.\
|
||||
"""
|
||||
homepage = "https://suitepro.cillero.es/projects/drust"
|
||||
repository = "https://gitlab.com/manuelcillero/drust"
|
||||
|
||||
[dependencies]
|
||||
pagetop = { path = "../pagetop" }
|
||||
39
pagetop-node/src/lib.rs
Normal file
39
pagetop-node/src/lib.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
localize!("src/locales");
|
||||
|
||||
//mod entity;
|
||||
mod migration;
|
||||
|
||||
pub struct NodeModule;
|
||||
|
||||
impl ModuleTrait for NodeModule {
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
cfg.route("/node", app::web::get().to(node));
|
||||
}
|
||||
|
||||
fn migrations(&self) -> Vec<Box<dyn db::migration::MigrationTrait>> {
|
||||
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),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
async fn node() -> app::Result<Markup> {
|
||||
Page::prepare()
|
||||
.with_title(
|
||||
"Nodo"
|
||||
)
|
||||
.render()
|
||||
}
|
||||
2
pagetop-node/src/locales/en-US/homepage.ftl
Normal file
2
pagetop-node/src/locales/en-US/homepage.ftl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
module_fullname = Node
|
||||
module_description = Allows content to be submitted to the site and displayed on pages.
|
||||
2
pagetop-node/src/locales/es-ES/homepage.ftl
Normal file
2
pagetop-node/src/locales/es-ES/homepage.ftl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
module_fullname = Nodo
|
||||
module_description = Permite enviar contenidos al sitio y mostrarlos en páginas.
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
use pagetop::db::migration::*;
|
||||
|
||||
/// Stores information about all defined {node} types.
|
||||
#[derive(Iden)]
|
||||
enum NodeType {
|
||||
Table, // Nombre de la tabla: node_type (Tipo de nodo).
|
||||
Type, // The machine-readable name of this type
|
||||
Name, // The human-readable name of this type
|
||||
Description, // Descripción breve del tipo.
|
||||
Help, // Help information shown to the user when creating a {node} of this type
|
||||
HasTitle, // Boolean indicating whether this type uses the {node}.title field
|
||||
TitleLabel, // The label displayed for the title field on the edit form
|
||||
Custom, // A boolean indicating whether this type is defined by a module (FALSE) or by a user via Add content type (TRUE)
|
||||
Locked, // A boolean indicating whether the administrator can change the machine name of this type
|
||||
Disabled, // A boolean indicating whether the node type is disabled
|
||||
OrigType, // The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220316_000001_create_table_node_type"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(NodeType::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(NodeType::Type)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::Name)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::Description)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::Help)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::HasTitle)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::TitleLabel)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::Custom)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::Locked)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::Disabled)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::OrigType)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop()
|
||||
.table(NodeType::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
110
pagetop-node/src/migration/m20220316_000002_create_table_node.rs
Normal file
110
pagetop-node/src/migration/m20220316_000002_create_table_node.rs
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
use pagetop::db::migration::*;
|
||||
|
||||
/// The base table for nodes.
|
||||
#[derive(Iden)]
|
||||
enum Node {
|
||||
Table, // Nombre de la tabla: node (Nodo).
|
||||
Nid, // The primary identifier for a node
|
||||
Vid, // The current {node_revision}.vid version identifier
|
||||
Type, // The {node_type}.type of this node
|
||||
Language, // The {languages}.language of this node
|
||||
Title, // The title of this node, always treated as non-markup plain text
|
||||
Uid, // The {users}.uid that owns this node; initially, this is the user that created it
|
||||
Status, // Boolean indicating whether the node is published (visible to non-administrators)
|
||||
Created, // The Unix timestamp when the node was created
|
||||
Changed, // The Unix timestamp when the node was most recently saved
|
||||
Comment, // Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write)
|
||||
Promote, // Boolean indicating whether the node should be displayed on the front page
|
||||
Sticky, // Boolean indicating whether the node should be displayed at the top of lists in which it appears
|
||||
Tnid, // The translation set id for this node, which equals the node id of the source post in each set
|
||||
Translate, // A boolean indicating whether this translation page needs to be updated
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220316_000002_create_table_node"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Node::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(Node::Nid)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Node::Vid)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Type)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Language)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Title)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Uid)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Status)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Created)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Changed)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Comment)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Promote)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Sticky)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Tnid)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(Node::Translate)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop()
|
||||
.table(Node::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
use pagetop::db::migration::*;
|
||||
|
||||
// Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.
|
||||
#[derive(Iden)]
|
||||
enum NodeAccess {
|
||||
Table, // Nombre de la tabla: node_access (Acceso a nodos).
|
||||
Nid, // The {node}.nid this record affects
|
||||
Gid, // The grant ID a user must possess in the specified realm to gain this row's privileges on the node
|
||||
Realm, // The realm in which the user must possess the grant ID. Each node access node can define one or more realms
|
||||
GrantView, // Boolean indicating whether a user with the realm/grant pair can view this node
|
||||
GrantUpdate, // Boolean indicating whether a user with the realm/grant pair can edit this node
|
||||
GrantDelete, // Boolean indicating whether a user with the realm/grant pair can delete this node
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220316_000003_create_table_node_access"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(NodeAccess::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(NodeAccess::Nid)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(NodeAccess::Gid)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeAccess::Realm)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeAccess::GrantView)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeAccess::GrantUpdate)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeAccess::GrantDelete)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop()
|
||||
.table(NodeAccess::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
use pagetop::db::migration::*;
|
||||
|
||||
// Stores information about each saved version of a {node}.
|
||||
#[derive(Iden)]
|
||||
enum NodeRevision {
|
||||
Table, // Nombre de la tabla: node_revisión (Versiones de nodos).
|
||||
Nid, // The {node} this version belongs to
|
||||
Vid, // The primary identifier for this version
|
||||
Uid, // The {users}.uid that created this version
|
||||
Title, // The title of this version
|
||||
Log, // The log entry explaining the changes in this version
|
||||
Timestamp, // A Unix timestamp indicating when this version was created
|
||||
Status, // Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators)
|
||||
Comment, // Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write)
|
||||
Promote, // Boolean indicating whether the node (at the time of this revision) should be displayed on the front page
|
||||
Sticky, // Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220316_000004_create_table_node_revision"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(NodeRevision::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(NodeRevision::Nid)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Vid)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Uid)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Title)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Log)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Timestamp)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Status)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Comment)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Promote)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Sticky)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop()
|
||||
.table(NodeRevision::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
4
pagetop-node/src/migration/mod.rs
Normal file
4
pagetop-node/src/migration/mod.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
pub mod m20220316_000001_create_table_node_type;
|
||||
pub mod m20220316_000002_create_table_node;
|
||||
pub mod m20220316_000003_create_table_node_access;
|
||||
pub mod m20220316_000004_create_table_node_revision;
|
||||
22
pagetop-user/Cargo.toml
Normal file
22
pagetop-user/Cargo.toml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "pagetop-user"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
description = """\
|
||||
Allows content to be submitted to the site and displayed on pages.\
|
||||
"""
|
||||
homepage = "https://suitepro.cillero.es/projects/drust"
|
||||
repository = "https://gitlab.com/manuelcillero/drust"
|
||||
|
||||
[dependencies]
|
||||
pagetop = { path = "../pagetop" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "0.6.0"
|
||||
features = ["debug-print", "macros"]
|
||||
default-features = false
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::prelude::*;
|
||||
use pagetop::prelude::*;
|
||||
|
||||
localize!("src/base/module/user/locales");
|
||||
localize!("src/locales");
|
||||
|
||||
mod entity;
|
||||
mod migration;
|
||||
|
|
@ -8,10 +8,6 @@ mod migration;
|
|||
pub struct UserModule;
|
||||
|
||||
impl ModuleTrait for UserModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"user"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
|
@ -20,8 +16,8 @@ impl ModuleTrait for UserModule {
|
|||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.route("/user/login", server::web::get().to(login));
|
||||
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
cfg.route("/user/login", app::web::get().to(login));
|
||||
}
|
||||
|
||||
fn migrations(&self) -> Vec<Box<dyn db::migration::MigrationTrait>> {
|
||||
|
|
@ -50,7 +46,7 @@ fn form_login() -> impl PageComponent {
|
|||
.add(form::Button::submit(l("login").as_str()))
|
||||
}
|
||||
|
||||
async fn login() -> server::Result<Markup> {
|
||||
async fn login() -> app::Result<Markup> {
|
||||
Page::prepare()
|
||||
.with_title(
|
||||
"Identificación del usuario"
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pagetop"
|
||||
version = "0.0.1"
|
||||
version = "0.0.2"
|
||||
edition = "2021"
|
||||
|
||||
authors = [
|
||||
|
|
|
|||
|
|
@ -24,3 +24,8 @@ actix-web = "3.3.3"
|
|||
maud = { version = "0.23.0" }
|
||||
# Opcional. Si se requiere serialización de estructuras de datos.
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "0.6.0"
|
||||
features = ["debug-print", "macros"]
|
||||
default-features = false
|
||||
29
pagetop/STARTER.lib.Cargo.toml
Normal file
29
pagetop/STARTER.lib.Cargo.toml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
[package]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# Ver más claves y sus definiciones en
|
||||
# https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies.pagetop]
|
||||
path = "../pagetop"
|
||||
# Opcional. Por defecto se puede usar PageTop sin base de datos.
|
||||
features = ["mysql"]
|
||||
# features = ["postgres"]
|
||||
# features = ["sqlite"]
|
||||
# PageTop puede dar soporte a todas las bases de datos.
|
||||
# features = ["mysql", "postgres", "sqlite"]
|
||||
# Sólo cuando no se usen las características predeterminadas.
|
||||
default-features = false
|
||||
|
||||
[dependencies]
|
||||
# Opcional. Sólo si se usa la macro html!.
|
||||
maud = { version = "0.23.0" }
|
||||
# Opcional. Si se requiere serialización de estructuras de datos.
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "0.6.0"
|
||||
features = ["debug-print", "macros"]
|
||||
default-features = false
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
use crate::{Lazy, run_now};
|
||||
use crate::{Lazy, run_now, app};
|
||||
use crate::db::migration::*;
|
||||
use crate::core::theme::ThemeTrait;
|
||||
use crate::core::module::ModuleTrait;
|
||||
use crate::core::server;
|
||||
use crate::theme::ThemeTrait;
|
||||
use crate::module::ModuleTrait;
|
||||
|
||||
use std::sync::RwLock;
|
||||
|
||||
|
|
@ -16,7 +15,7 @@ pub static THEMES: Lazy<RwLock<Vec<&dyn ThemeTrait>>> = Lazy::new(
|
|||
|| { RwLock::new(Vec::new()) }
|
||||
);
|
||||
|
||||
pub fn themes(cfg: &mut server::web::ServiceConfig) {
|
||||
pub fn themes(cfg: &mut app::web::ServiceConfig) {
|
||||
cfg.service(actix_web_static_files::ResourceFiles::new(
|
||||
"/theme",
|
||||
assets()
|
||||
|
|
@ -35,7 +34,7 @@ pub static MODULES: Lazy<RwLock<Vec<&dyn ModuleTrait>>> = Lazy::new(
|
|||
|| { RwLock::new(Vec::new()) }
|
||||
);
|
||||
|
||||
pub fn modules(cfg: &mut server::web::ServiceConfig) {
|
||||
pub fn modules(cfg: &mut app::web::ServiceConfig) {
|
||||
for m in MODULES.read().unwrap().iter() {
|
||||
m.configure_module(cfg);
|
||||
}
|
||||
|
|
@ -54,6 +53,6 @@ pub fn run_migrations() {
|
|||
migrations
|
||||
}
|
||||
}
|
||||
Migrator::up(&server::db::DBCONN, None)
|
||||
Migrator::up(&app::db::DBCONN, None)
|
||||
}).unwrap();
|
||||
}
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
use crate::{Lazy, base, trace};
|
||||
use crate::{Lazy, all, app, trace};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::{Server, all, server};
|
||||
use crate::core::theme::register_theme;
|
||||
use crate::core::module::register_module;
|
||||
use crate::theme::*;
|
||||
use crate::module::*;
|
||||
|
||||
use std::io::Error;
|
||||
use actix_web::middleware::normalize::{NormalizePath, TrailingSlash};
|
||||
|
||||
pub struct Application {
|
||||
server: Server,
|
||||
server: app::Server,
|
||||
}
|
||||
|
||||
pub fn essence() {
|
||||
|
|
@ -44,25 +43,19 @@ impl Application {
|
|||
}
|
||||
|
||||
// Inicia registro de trazas y eventos.
|
||||
Lazy::force(&server::tracing::TRACING);
|
||||
Lazy::force(&app::tracing::TRACING);
|
||||
|
||||
// Valida el identificador de idioma.
|
||||
Lazy::force(&server::locale::LANGID);
|
||||
Lazy::force(&app::locale::LANGID);
|
||||
|
||||
// Conecta con la base de datos (opcional).
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
Lazy::force(&server::db::DBCONN);
|
||||
Lazy::force(&app::db::DBCONN);
|
||||
|
||||
// Registra los temas predefinidos.
|
||||
register_theme(&base::theme::aliner::AlinerTheme);
|
||||
register_theme(&base::theme::minimal::MinimalTheme);
|
||||
register_theme(&base::theme::bootsier::BootsierTheme);
|
||||
|
||||
// Registra los módulos predeterminados.
|
||||
register_module(&base::module::admin::AdminModule);
|
||||
// Registra los módulos que requieren base de datos.
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
register_module(&base::module::user::UserModule);
|
||||
register_theme(&aliner::AlinerTheme);
|
||||
register_theme(&minimal::MinimalTheme);
|
||||
register_theme(&bootsier::BootsierTheme);
|
||||
|
||||
// Ejecuta la función de inicio de la aplicación.
|
||||
trace::info!("Calling application bootstrap");
|
||||
|
|
@ -70,15 +63,15 @@ impl Application {
|
|||
|
||||
// Registra el módulo para la página de inicio de PageTop.
|
||||
// Al ser el último, puede sobrecargarse con la función de inicio.
|
||||
register_module(&base::module::homepage::HomepageModule);
|
||||
register_module(&homepage::HomepageModule);
|
||||
|
||||
// Comprueba actualizaciones pendientes de la base de datos (opcional).
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
all::run_migrations();
|
||||
|
||||
// Prepara el servidor web.
|
||||
let server = server::HttpServer::new(move || {
|
||||
server::App::new()
|
||||
let server = app::HttpServer::new(move || {
|
||||
app::App::new()
|
||||
.wrap(tracing_actix_web::TracingLogger)
|
||||
.wrap(NormalizePath::new(TrailingSlash::Trim))
|
||||
.configure(&all::themes)
|
||||
|
|
@ -93,7 +86,7 @@ impl Application {
|
|||
Ok(Self { server })
|
||||
}
|
||||
|
||||
pub fn run(self) -> Result<Server, Error> {
|
||||
pub fn run(self) -> Result<app::Server, Error> {
|
||||
Ok(self.server)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
pub use actix_web::{
|
||||
App, HttpRequest, HttpResponse, HttpServer, Responder, Result, http, web
|
||||
};
|
||||
use actix_web::dev::Server;
|
||||
|
||||
mod tracing;
|
||||
|
||||
|
|
@ -9,4 +10,4 @@ pub mod locale;
|
|||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub mod db;
|
||||
|
||||
pub mod app;
|
||||
pub mod application;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
//! Temas, Módulos y Componentes base.
|
||||
|
||||
pub mod theme;
|
||||
pub mod module;
|
||||
pub mod component;
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
localize!("src/base/module/admin/locales");
|
||||
|
||||
mod summary;
|
||||
|
||||
pub struct AdminModule;
|
||||
|
||||
impl ModuleTrait for AdminModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"admin"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.service(
|
||||
server::web::scope("/admin")
|
||||
.route("", server::web::get().to(summary::summary))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
pub mod admin;
|
||||
pub mod homepage;
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub mod user;
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
pub mod aliner;
|
||||
pub mod minimal;
|
||||
pub mod bootsier;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
pub use actix_web::dev::Server;
|
||||
|
||||
mod all;
|
||||
|
||||
pub mod html;
|
||||
pub mod theme;
|
||||
pub mod module;
|
||||
pub mod response;
|
||||
pub mod server;
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
use crate::core::all;
|
||||
|
||||
mod definition;
|
||||
pub use definition::ModuleTrait;
|
||||
|
||||
pub fn register_module(m: &'static (dyn ModuleTrait + 'static)) {
|
||||
all::MODULES.write().unwrap().push(m);
|
||||
}
|
||||
|
||||
pub fn find_module(name: &str) -> Option<&'static (dyn ModuleTrait + 'static)> {
|
||||
let modules = all::MODULES.write().unwrap();
|
||||
match modules.iter().find(|t| t.name() == name) {
|
||||
Some(module) => Some(*module),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ pub use futures::executor::block_on as run_now;
|
|||
// APIs públicas.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
mod all; // Variables globales privadas.
|
||||
|
||||
pub mod config; // Gestión de la configuración.
|
||||
pub mod trace; // Registro de trazas y eventos de la aplicación.
|
||||
pub mod locale; // Localización.
|
||||
|
|
@ -15,8 +17,14 @@ pub mod locale; // Localización.
|
|||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub mod db; // Acceso a la base de datos.
|
||||
|
||||
pub mod core; // Servidor web y APIs para Temas, Módulos y Respuestas web.
|
||||
pub mod base; // Temas, Módulos y Componentes base.
|
||||
pub mod html; // Publicación de código HTML desde el código.
|
||||
pub mod theme; // API para crear temas y temas predeterminados.
|
||||
pub mod module; // API para crear módulos con nuevas funcionalidades.
|
||||
pub mod response; // Tipos de respuestas web.
|
||||
pub mod app; // Aplicación y servidor web.
|
||||
|
||||
pub mod component; // Componentes base.
|
||||
|
||||
pub mod util; // Macros y funciones útiles.
|
||||
|
||||
pub mod prelude; // Re-exporta recursos comunes.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub use fluent_templates::fluent_bundle::FluentValue;
|
|||
macro_rules! localize {
|
||||
( $dir_locales:literal $(, $core_locales:literal)? ) => {
|
||||
use $crate::locale::*;
|
||||
use $crate::core::server::locale::LANGID;
|
||||
use $crate::app::locale::LANGID;
|
||||
|
||||
static_locale! {
|
||||
static LOCALES = {
|
||||
|
|
@ -37,8 +37,8 @@ macro_rules! localize {
|
|||
fn e(
|
||||
key: &str,
|
||||
args: &std::collections::HashMap<String, FluentValue>
|
||||
) -> $crate::core::html::PreEscaped<String> {
|
||||
$crate::core::html::PreEscaped(
|
||||
) -> $crate::html::PreEscaped<String> {
|
||||
$crate::html::PreEscaped(
|
||||
LOCALES.lookup_with_args(&LANGID, key, args)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,31 @@
|
|||
use crate::core::server;
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
use crate::db;
|
||||
use crate::app;
|
||||
|
||||
use std::any::type_name;
|
||||
|
||||
/// Los módulos deben implementar este *trait*.
|
||||
pub trait ModuleTrait: Send + Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
fn name(&self) -> &'static str {
|
||||
let name = type_name::<Self>();
|
||||
match name.rfind("::") {
|
||||
Some(position) => &name[(position + 2)..],
|
||||
None => name
|
||||
}
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String;
|
||||
|
||||
fn dependencies(&self) -> Vec<&'static dyn ModuleTrait> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
|
|
@ -1,14 +1,10 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
localize!("src/base/module/homepage/locales");
|
||||
localize!("src/module/homepage/locales");
|
||||
|
||||
pub struct HomepageModule;
|
||||
|
||||
impl ModuleTrait for HomepageModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"homepage"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
|
@ -17,12 +13,12 @@ impl ModuleTrait for HomepageModule {
|
|||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.route("/", server::web::get().to(home));
|
||||
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
cfg.route("/", app::web::get().to(home));
|
||||
}
|
||||
}
|
||||
|
||||
async fn home() -> server::Result<Markup> {
|
||||
async fn home() -> app::Result<Markup> {
|
||||
Page::prepare()
|
||||
.with_title(
|
||||
l("page_title").as_str()
|
||||
17
pagetop/src/module/mod.rs
Normal file
17
pagetop/src/module/mod.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
use crate::{all, trace};
|
||||
|
||||
mod definition;
|
||||
pub use definition::ModuleTrait;
|
||||
|
||||
pub mod homepage;
|
||||
|
||||
pub fn register_module(m: &'static dyn ModuleTrait) {
|
||||
let mut modules = all::MODULES.write().unwrap();
|
||||
match modules.iter().find(|t| t.name() == m.name()) {
|
||||
None => {
|
||||
trace::info!("{}", m.name());
|
||||
modules.push(m);
|
||||
},
|
||||
Some(_) => {},
|
||||
}
|
||||
}
|
||||
|
|
@ -8,13 +8,14 @@ pub use crate::localize;
|
|||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub use crate::{db, boxed_migration};
|
||||
|
||||
pub use crate::core::html::*;
|
||||
pub use crate::core::theme::*;
|
||||
pub use crate::core::module::*;
|
||||
pub use crate::core::response::page::*;
|
||||
pub use crate::core::server;
|
||||
pub use crate::core::server::app::{Application, essence};
|
||||
pub use crate::html::*;
|
||||
pub use crate::theme::*;
|
||||
pub use crate::module::*;
|
||||
pub use crate::response::page::*;
|
||||
|
||||
pub use crate::base::component::*;
|
||||
pub use crate::app;
|
||||
pub use crate::app::application::{Application, essence};
|
||||
|
||||
pub use crate::component::*;
|
||||
|
||||
pub use crate::util;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use crate::{Lazy, base};
|
||||
use crate::{Lazy, all};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::all;
|
||||
use crate::core::html::{Markup, PreEscaped, html};
|
||||
use crate::core::theme::*;
|
||||
use crate::html::{Markup, PreEscaped, html};
|
||||
use crate::theme::*;
|
||||
|
||||
static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| {
|
||||
for t in all::THEMES.read().unwrap().iter() {
|
||||
|
|
@ -10,7 +9,7 @@ static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| {
|
|||
return *t;
|
||||
}
|
||||
}
|
||||
&base::theme::bootsier::BootsierTheme
|
||||
&bootsier::BootsierTheme
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::core::html::{Markup, html};
|
||||
use crate::core::response::page::PageAssets;
|
||||
use crate::html::{Markup, html};
|
||||
use crate::response::page::PageAssets;
|
||||
|
||||
use downcast_rs::{Downcast, impl_downcast};
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::core::html::{Markup, html};
|
||||
use crate::core::response::page::{PageAssets, PageComponent, render_component};
|
||||
use crate::html::{Markup, html};
|
||||
use crate::response::page::{PageAssets, PageComponent, render_component};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
use crate::{Lazy, trace, util};
|
||||
use crate::{Lazy, app, trace, util};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::html::{DOCTYPE, Markup, html};
|
||||
use crate::core::response::page::{PageAssets, PageComponent, PageContainer};
|
||||
use crate::core::server;
|
||||
use crate::html::{DOCTYPE, Markup, html};
|
||||
use crate::response::page::{PageAssets, PageComponent, PageContainer};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::sync::RwLock;
|
||||
|
|
@ -164,7 +163,7 @@ impl<'a> Page<'a> {
|
|||
|
||||
// Page RENDER.
|
||||
|
||||
pub fn render(&mut self) -> server::Result<Markup> {
|
||||
pub fn render(&mut self) -> app::Result<Markup> {
|
||||
// Acciones del tema antes de renderizar la página.
|
||||
self.assets.theme().before_render_page(self);
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ impl ThemeTrait for AlinerTheme {
|
|||
"Aliner".to_owned()
|
||||
}
|
||||
|
||||
fn configure_theme(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
fn configure_theme(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
cfg.service(actix_web_static_files::ResourceFiles::new(
|
||||
"/aliner",
|
||||
assets()
|
||||
|
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
|||
|
||||
include!(concat!(env!("OUT_DIR"), "/bootsier.rs"));
|
||||
|
||||
localize!("src/base/theme/bootsier/locales");
|
||||
localize!("src/theme/bootsier/locales");
|
||||
|
||||
pub struct BootsierTheme;
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ impl ThemeTrait for BootsierTheme {
|
|||
"Bootsier".to_owned()
|
||||
}
|
||||
|
||||
fn configure_theme(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
fn configure_theme(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
cfg.service(actix_web_static_files::ResourceFiles::new(
|
||||
"/bootsier",
|
||||
assets()
|
||||
|
|
@ -43,16 +43,16 @@ impl ThemeTrait for BootsierTheme {
|
|||
.add_jquery();
|
||||
}
|
||||
|
||||
fn render_error_page(&self, mut s: server::http::StatusCode) -> server::Result<Markup> {
|
||||
fn render_error_page(&self, mut s: app::http::StatusCode) -> app::Result<Markup> {
|
||||
let mut description = "e500-description";
|
||||
let mut message = "e500-description";
|
||||
match s {
|
||||
server::http::StatusCode::NOT_FOUND => {
|
||||
app::http::StatusCode::NOT_FOUND => {
|
||||
description = "e404-description";
|
||||
message = "e404-message";
|
||||
},
|
||||
_ => {
|
||||
s = server::http::StatusCode::INTERNAL_SERVER_ERROR;
|
||||
s = app::http::StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
Page::prepare()
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::config::SETTINGS;
|
||||
use crate::core::html::{Markup, html};
|
||||
use crate::core::response::page::{Page, PageAssets, PageComponent};
|
||||
use crate::core::server;
|
||||
use crate::base::component::Chunck;
|
||||
use crate::html::{Markup, html};
|
||||
use crate::response::page::{Page, PageAssets, PageComponent};
|
||||
use crate::app;
|
||||
use crate::component::Chunck;
|
||||
|
||||
/// Los temas deben implementar este "trait".
|
||||
pub trait ThemeTrait: Send + Sync {
|
||||
|
|
@ -15,7 +15,7 @@ pub trait ThemeTrait: Send + Sync {
|
|||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn configure_theme(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
fn configure_theme(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
|
|
@ -93,7 +93,7 @@ pub trait ThemeTrait: Send + Sync {
|
|||
*/
|
||||
}
|
||||
|
||||
fn render_error_page(&self, s: server::http::StatusCode) -> server::Result<Markup> {
|
||||
fn render_error_page(&self, s: app::http::StatusCode) -> app::Result<Markup> {
|
||||
Page::prepare()
|
||||
.with_title(format!("Error {}", s.as_str()).as_str())
|
||||
.add_to("content", Chunck::markup(html! {
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
use crate::core::all;
|
||||
use crate::all;
|
||||
|
||||
mod definition;
|
||||
pub use definition::ThemeTrait;
|
||||
|
||||
pub fn register_theme(t: &'static (dyn ThemeTrait + 'static)) {
|
||||
pub mod aliner;
|
||||
pub mod minimal;
|
||||
pub mod bootsier;
|
||||
|
||||
pub fn register_theme(t: &'static dyn ThemeTrait) {
|
||||
all::THEMES.write().unwrap().push(t);
|
||||
}
|
||||
|
||||
pub fn find_theme(name: &str) -> Option<&'static (dyn ThemeTrait + 'static)> {
|
||||
pub fn find_theme(name: &str) -> Option<&'static dyn ThemeTrait> {
|
||||
let themes = all::THEMES.write().unwrap();
|
||||
match themes.iter().find(|t| t.name() == name) {
|
||||
Some(theme) => Some(*theme),
|
||||
Loading…
Add table
Add a link
Reference in a new issue