🎨 Revisa acciones de página y estructura de base
This commit is contained in:
parent
8aef379973
commit
7bf89ca90d
13 changed files with 247 additions and 167 deletions
|
|
@ -2,6 +2,8 @@ use crate::prelude::*;
|
|||
|
||||
pub type FnActionWithComponent<C> = fn(component: &mut C, cx: &mut Context);
|
||||
|
||||
pub type FnActionWithPage = fn(page: &mut Page);
|
||||
|
||||
pub mod component;
|
||||
|
||||
pub mod layout;
|
||||
|
|
|
|||
|
|
@ -6,3 +6,9 @@ pub use after_render_component::*;
|
|||
|
||||
mod render_component;
|
||||
pub use render_component::*;
|
||||
|
||||
mod before_render_page_body;
|
||||
pub use before_render_page_body::*;
|
||||
|
||||
mod after_render_page_body;
|
||||
pub use after_render_page_body::*;
|
||||
|
|
|
|||
37
pagetop/src/base/action/layout/after_render_page_body.rs
Normal file
37
pagetop/src/base/action/layout/after_render_page_body.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
use crate::base::action::FnActionWithPage;
|
||||
|
||||
pub struct AfterRenderBody {
|
||||
f: FnActionWithPage,
|
||||
layout_type_id: Option<TypeId>,
|
||||
}
|
||||
|
||||
impl ActionTrait for AfterRenderBody {
|
||||
fn layout_type_id(&self) -> Option<TypeId> {
|
||||
self.layout_type_id
|
||||
}
|
||||
}
|
||||
|
||||
impl AfterRenderBody {
|
||||
pub fn new(layout: LayoutRef, f: FnActionWithPage) -> Self {
|
||||
AfterRenderBody {
|
||||
f,
|
||||
layout_type_id: Some(layout.type_id()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(clippy::inline_always)]
|
||||
pub(crate) fn dispatch(page: &mut Page) {
|
||||
dispatch_actions(
|
||||
&ActionKey::new(
|
||||
TypeId::of::<Self>(),
|
||||
Some(page.context().layout().type_id()),
|
||||
None,
|
||||
None,
|
||||
),
|
||||
|action: &Self| (action.f)(page),
|
||||
);
|
||||
}
|
||||
}
|
||||
37
pagetop/src/base/action/layout/before_render_page_body.rs
Normal file
37
pagetop/src/base/action/layout/before_render_page_body.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
use crate::base::action::FnActionWithPage;
|
||||
|
||||
pub struct BeforeRenderBody {
|
||||
f: FnActionWithPage,
|
||||
layout_type_id: Option<TypeId>,
|
||||
}
|
||||
|
||||
impl ActionTrait for BeforeRenderBody {
|
||||
fn layout_type_id(&self) -> Option<TypeId> {
|
||||
self.layout_type_id
|
||||
}
|
||||
}
|
||||
|
||||
impl BeforeRenderBody {
|
||||
pub fn new(layout: LayoutRef, f: FnActionWithPage) -> Self {
|
||||
BeforeRenderBody {
|
||||
f,
|
||||
layout_type_id: Some(layout.type_id()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(clippy::inline_always)]
|
||||
pub(crate) fn dispatch(page: &mut Page) {
|
||||
dispatch_actions(
|
||||
&ActionKey::new(
|
||||
TypeId::of::<Self>(),
|
||||
Some(page.context().layout().type_id()),
|
||||
None,
|
||||
None,
|
||||
),
|
||||
|action: &Self| (action.f)(page),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub type FnAfterRenderBody = fn(page: &mut Page);
|
||||
use crate::base::action::FnActionWithPage;
|
||||
|
||||
pub struct AfterRenderBody {
|
||||
f: FnAfterRenderBody,
|
||||
f: FnActionWithPage,
|
||||
weight: Weight,
|
||||
}
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ impl ActionTrait for AfterRenderBody {
|
|||
}
|
||||
|
||||
impl AfterRenderBody {
|
||||
pub fn new(f: FnAfterRenderBody) -> Self {
|
||||
pub fn new(f: FnActionWithPage) -> Self {
|
||||
AfterRenderBody { f, weight: 0 }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub type FnBeforeRenderBody = fn(page: &mut Page);
|
||||
use crate::base::action::FnActionWithPage;
|
||||
|
||||
pub struct BeforeRenderBody {
|
||||
f: FnBeforeRenderBody,
|
||||
f: FnActionWithPage,
|
||||
weight: Weight,
|
||||
}
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ impl ActionTrait for BeforeRenderBody {
|
|||
}
|
||||
|
||||
impl BeforeRenderBody {
|
||||
pub fn new(f: FnBeforeRenderBody) -> Self {
|
||||
pub fn new(f: FnActionWithPage) -> Self {
|
||||
BeforeRenderBody { f, weight: 0 }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,2 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Basic;
|
||||
|
||||
impl PackageTrait for Basic {
|
||||
fn layout(&self) -> Option<LayoutRef> {
|
||||
Some(&Basic)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayoutTrait for Basic {}
|
||||
mod basic;
|
||||
pub use basic::Basic;
|
||||
|
|
|
|||
11
pagetop/src/base/layout/basic.rs
Normal file
11
pagetop/src/base/layout/basic.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Basic;
|
||||
|
||||
impl PackageTrait for Basic {
|
||||
fn layout(&self) -> Option<LayoutRef> {
|
||||
Some(&Basic)
|
||||
}
|
||||
}
|
||||
|
||||
impl LayoutTrait for Basic {}
|
||||
|
|
@ -1,133 +1,2 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Welcome;
|
||||
|
||||
impl PackageTrait for Welcome {
|
||||
fn name(&self) -> L10n {
|
||||
L10n::l("welcome_package_name")
|
||||
}
|
||||
|
||||
fn description(&self) -> L10n {
|
||||
L10n::l("welcome_package_description")
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
scfg.route("/", service::web::get().to(homepage));
|
||||
}
|
||||
}
|
||||
|
||||
async fn homepage(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
|
||||
Page::new(request)
|
||||
.with_title(L10n::l("welcome_page"))
|
||||
.with_assets(AssetsOp::Layout("Basic"))
|
||||
.with_assets(AssetsOp::AddStyleSheet(StyleSheet::inline("styles", r##"
|
||||
body {
|
||||
background-color: #f3d060;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 20px;
|
||||
}
|
||||
.skip__to_content {
|
||||
display: none;
|
||||
}
|
||||
.wrapper {
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
.container {
|
||||
padding: 0 16px;
|
||||
}
|
||||
.title {
|
||||
font-size: clamp(3rem, 10vw, 10rem);
|
||||
letter-spacing: -0.05em;
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: clamp(1.8rem, 2vw, 3rem);
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
}
|
||||
.powered {
|
||||
margin: .5em 0 1em;
|
||||
}
|
||||
.box-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
gap: 1.5em;
|
||||
}
|
||||
.box {
|
||||
flex: 1 1 280px;
|
||||
border: 3px solid #25282a;
|
||||
box-shadow: 5px 5px 0px #25282a;
|
||||
box-sizing: border-box;
|
||||
padding: 0 16px;
|
||||
}
|
||||
footer {
|
||||
margin-top: 5em;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #a5282c;
|
||||
}
|
||||
"##)))
|
||||
.with_component(Html::with(html! {
|
||||
div class="wrapper" {
|
||||
div class="container" {
|
||||
h1 class="title" { (L10n::l("welcome_title").markup()) }
|
||||
|
||||
p class="subtitle" {
|
||||
(L10n::l("welcome_intro").with_arg("app", format!(
|
||||
"<span style=\"font-weight: bold;\">{}</span>",
|
||||
&global::SETTINGS.app.name
|
||||
)).markup())
|
||||
}
|
||||
p class="powered" {
|
||||
(L10n::l("welcome_powered").with_arg("pagetop", format!(
|
||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||
"https://crates.io/crates/pagetop", "PageTop"
|
||||
)).markup())
|
||||
}
|
||||
|
||||
h2 { (L10n::l("welcome_page").markup()) }
|
||||
|
||||
div class="box-container" {
|
||||
section class="box" style="background-color: #5eb0e5;" {
|
||||
h3 {
|
||||
(L10n::l("welcome_subtitle")
|
||||
.with_arg("app", &global::SETTINGS.app.name)
|
||||
.markup())
|
||||
}
|
||||
p { (L10n::l("welcome_text1").markup()) }
|
||||
p { (L10n::l("welcome_text2").markup()) }
|
||||
}
|
||||
section class="box" style="background-color: #aee1cd;" {
|
||||
h3 {
|
||||
(L10n::l("welcome_pagetop_title").markup())
|
||||
}
|
||||
p { (L10n::l("welcome_pagetop_text1").markup()) }
|
||||
p { (L10n::l("welcome_pagetop_text2").markup()) }
|
||||
p { (L10n::l("welcome_pagetop_text3").markup()) }
|
||||
}
|
||||
section class="box" style="background-color: #ebebe3;" {
|
||||
h3 {
|
||||
(L10n::l("welcome_issues_title").markup())
|
||||
}
|
||||
p { (L10n::l("welcome_issues_text1").markup()) }
|
||||
p {
|
||||
(L10n::l("welcome_issues_text2")
|
||||
.with_arg("app", &global::SETTINGS.app.name)
|
||||
.markup())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer { "[ " (L10n::l("welcome_have_fun").markup()) " ]" }
|
||||
}
|
||||
}
|
||||
}))
|
||||
.render()
|
||||
}
|
||||
mod welcome;
|
||||
pub use welcome::Welcome;
|
||||
|
|
|
|||
133
pagetop/src/base/package/welcome.rs
Normal file
133
pagetop/src/base/package/welcome.rs
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Welcome;
|
||||
|
||||
impl PackageTrait for Welcome {
|
||||
fn name(&self) -> L10n {
|
||||
L10n::l("welcome_package_name")
|
||||
}
|
||||
|
||||
fn description(&self) -> L10n {
|
||||
L10n::l("welcome_package_description")
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
scfg.route("/", service::web::get().to(homepage));
|
||||
}
|
||||
}
|
||||
|
||||
async fn homepage(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
|
||||
Page::new(request)
|
||||
.with_title(L10n::l("welcome_page"))
|
||||
.with_assets(AssetsOp::Layout("Basic"))
|
||||
.with_assets(AssetsOp::AddStyleSheet(StyleSheet::inline("styles", r##"
|
||||
body {
|
||||
background-color: #f3d060;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 20px;
|
||||
}
|
||||
.skip__to_content {
|
||||
display: none;
|
||||
}
|
||||
.wrapper {
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
.container {
|
||||
padding: 0 16px;
|
||||
}
|
||||
.title {
|
||||
font-size: clamp(3rem, 10vw, 10rem);
|
||||
letter-spacing: -0.05em;
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: clamp(1.8rem, 2vw, 3rem);
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
}
|
||||
.powered {
|
||||
margin: .5em 0 1em;
|
||||
}
|
||||
.box-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
gap: 1.5em;
|
||||
}
|
||||
.box {
|
||||
flex: 1 1 280px;
|
||||
border: 3px solid #25282a;
|
||||
box-shadow: 5px 5px 0px #25282a;
|
||||
box-sizing: border-box;
|
||||
padding: 0 16px;
|
||||
}
|
||||
footer {
|
||||
margin-top: 5em;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #a5282c;
|
||||
}
|
||||
"##)))
|
||||
.with_component(Html::with(html! {
|
||||
div class="wrapper" {
|
||||
div class="container" {
|
||||
h1 class="title" { (L10n::l("welcome_title").markup()) }
|
||||
|
||||
p class="subtitle" {
|
||||
(L10n::l("welcome_intro").with_arg("app", format!(
|
||||
"<span style=\"font-weight: bold;\">{}</span>",
|
||||
&global::SETTINGS.app.name
|
||||
)).markup())
|
||||
}
|
||||
p class="powered" {
|
||||
(L10n::l("welcome_powered").with_arg("pagetop", format!(
|
||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||
"https://crates.io/crates/pagetop", "PageTop"
|
||||
)).markup())
|
||||
}
|
||||
|
||||
h2 { (L10n::l("welcome_page").markup()) }
|
||||
|
||||
div class="box-container" {
|
||||
section class="box" style="background-color: #5eb0e5;" {
|
||||
h3 {
|
||||
(L10n::l("welcome_subtitle")
|
||||
.with_arg("app", &global::SETTINGS.app.name)
|
||||
.markup())
|
||||
}
|
||||
p { (L10n::l("welcome_text1").markup()) }
|
||||
p { (L10n::l("welcome_text2").markup()) }
|
||||
}
|
||||
section class="box" style="background-color: #aee1cd;" {
|
||||
h3 {
|
||||
(L10n::l("welcome_pagetop_title").markup())
|
||||
}
|
||||
p { (L10n::l("welcome_pagetop_text1").markup()) }
|
||||
p { (L10n::l("welcome_pagetop_text2").markup()) }
|
||||
p { (L10n::l("welcome_pagetop_text3").markup()) }
|
||||
}
|
||||
section class="box" style="background-color: #ebebe3;" {
|
||||
h3 {
|
||||
(L10n::l("welcome_issues_title").markup())
|
||||
}
|
||||
p { (L10n::l("welcome_issues_text1").markup()) }
|
||||
p {
|
||||
(L10n::l("welcome_issues_text2")
|
||||
.with_arg("app", &global::SETTINGS.app.name)
|
||||
.markup())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer { "[ " (L10n::l("welcome_have_fun").markup()) " ]" }
|
||||
}
|
||||
}
|
||||
}))
|
||||
.render()
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ impl<C: ComponentTrait> ComponentBase for C {
|
|||
// Comprueba el componente antes de prepararlo.
|
||||
self.setup_before_prepare(cx);
|
||||
|
||||
// Acciones del diseño antes de renderizar el componente.
|
||||
// Acciones específicas del diseño antes de renderizar el componente.
|
||||
action::layout::BeforeRender::dispatch(self, cx);
|
||||
|
||||
// Acciones de los paquetes antes de renderizar el componente.
|
||||
|
|
@ -52,7 +52,7 @@ impl<C: ComponentTrait> ComponentBase for C {
|
|||
None => self.prepare_component(cx).render(),
|
||||
};
|
||||
|
||||
// Acciones del diseño después de renderizar el componente.
|
||||
// Acciones específicas del diseño después de renderizar el componente.
|
||||
action::layout::AfterRender::dispatch(self, cx);
|
||||
|
||||
// Acciones de los paquetes después de renderizar el componente.
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@ pub trait LayoutTrait: PackageTrait + Send + Sync {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn before_render_body(&self, page: &mut Page) {}
|
||||
|
||||
fn render_body(&self, page: &mut Page) -> Markup {
|
||||
html! {
|
||||
body id=[page.body_id().get()] class=[page.body_classes().get()] {
|
||||
|
|
@ -53,7 +50,4 @@ pub trait LayoutTrait: PackageTrait + Send + Sync {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn after_render_body(&self, page: &mut Page) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,25 +156,25 @@ impl Page {
|
|||
// Page RENDER.
|
||||
|
||||
pub fn render(&mut self) -> ResultPage<Markup, ErrorPage> {
|
||||
// Layout-specific operations before rendering the page body.
|
||||
self.context.layout().before_render_body(self);
|
||||
// Acciones específicas del diseño antes de renderizar el <body>.
|
||||
action::layout::BeforeRenderBody::dispatch(self);
|
||||
|
||||
// Execute package actions before rendering the page body.
|
||||
// Acciones de los paquetes antes de renderizar el <body>.
|
||||
action::page::BeforeRenderBody::dispatch(self);
|
||||
|
||||
// Render the page body.
|
||||
// Renderiza el <body>.
|
||||
let body = self.context.layout().render_body(self);
|
||||
|
||||
// Layout-specific operations after rendering the page body.
|
||||
self.context.layout().after_render_body(self);
|
||||
// Acciones específicas del diseño después de renderizar el <body>.
|
||||
action::layout::AfterRenderBody::dispatch(self);
|
||||
|
||||
// Execute package actions after rendering the page body.
|
||||
// Acciones de los paquetes después de renderizar el <body>.
|
||||
action::page::AfterRenderBody::dispatch(self);
|
||||
|
||||
// Render the page head.
|
||||
// Renderiza el <head>.
|
||||
let head = self.context.layout().render_head(self);
|
||||
|
||||
// Render the full page with language and direction attributes.
|
||||
// Compone la página completa incluyendo los atributos de idioma y dirección del texto.
|
||||
let lang = &self.context.langid().language;
|
||||
let dir = match self.context.langid().character_direction() {
|
||||
CharacterDirection::LTR => "ltr",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue