🍻 Primera revista a las traducciones por contexto
This commit is contained in:
parent
71b0b0889d
commit
0de26a4737
28 changed files with 307 additions and 187 deletions
|
|
@ -14,11 +14,11 @@ impl ModuleTrait for Admin {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
t("module_name", Locale::From(&LOCALE_ADMIN))
|
_t("module_name", Locale::From(&LOCALE_ADMIN))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn description(&self) -> Option<String> {
|
fn description(&self) -> Option<String> {
|
||||||
Some(t("module_description", Locale::From(&LOCALE_ADMIN)))
|
Some(_t("module_description", Locale::From(&LOCALE_ADMIN)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use pagetop_minimal::component::*;
|
||||||
pub async fn summary(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
pub async fn summary(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
||||||
let top_menu = MegaMenu::new()
|
let top_menu = MegaMenu::new()
|
||||||
.with_item(MegaMenuItem::label(
|
.with_item(MegaMenuItem::label(
|
||||||
t("module_name", Locale::From(&LOCALE_ADMIN)).as_str(),
|
_t("module_name", Locale::From(&LOCALE_ADMIN)).as_str(),
|
||||||
))
|
))
|
||||||
.with_item(MegaMenuItem::link("Opción 2", "https://www.google.es"))
|
.with_item(MegaMenuItem::link("Opción 2", "https://www.google.es"))
|
||||||
.with_item(MegaMenuItem::link_blank(
|
.with_item(MegaMenuItem::link_blank(
|
||||||
|
|
|
||||||
|
|
@ -42,30 +42,37 @@ impl ThemeTrait for Bootsier {
|
||||||
pagetop_jquery::JQuery::add_jquery(page.context());
|
pagetop_jquery::JQuery::add_jquery(page.context());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_404_not_found(&self) -> HtmlMarkup {
|
fn render_component(
|
||||||
HtmlMarkup::new().with(html! {
|
&self,
|
||||||
div class="jumbotron" {
|
component: &dyn ComponentTrait,
|
||||||
div class="media" {
|
_rcx: &mut RenderContext,
|
||||||
img
|
) -> Option<Markup> {
|
||||||
src="/bootsier/images/caution.png"
|
match component.handle() {
|
||||||
class="mr-4"
|
ERROR_404 => Some(html! {
|
||||||
style="width: 20%; max-width: 188px"
|
div class="jumbotron" {
|
||||||
alt="Caution!";
|
div class="media" {
|
||||||
div class="media-body" {
|
img
|
||||||
h1 class="display-4" { ("RESOURCE NOT FOUND") }
|
src="/bootsier/images/caution.png"
|
||||||
p class="lead" { (t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
class="mr-4"
|
||||||
hr class="my-4";
|
style="width: 20%; max-width: 188px"
|
||||||
p { (t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
alt="Caution!";
|
||||||
a
|
div class="media-body" {
|
||||||
class="btn btn-primary btn-lg"
|
h1 class="display-4" { ("RESOURCE NOT FOUND") }
|
||||||
href="/"
|
p class="lead" { (_t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
||||||
role="button"
|
hr class="my-4";
|
||||||
{
|
p { (_t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
||||||
(t("back-homepage", Locale::From(&LOCALE_BOOTSIER)))
|
a
|
||||||
|
class="btn btn-primary btn-lg"
|
||||||
|
href="/"
|
||||||
|
role="button"
|
||||||
|
{
|
||||||
|
(_t("back-homepage", Locale::From(&LOCALE_BOOTSIER)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}),
|
||||||
})
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ impl ModuleTrait for HomeDemo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
t("module_name", Locale::From(&LOCALE_DEMOHOME))
|
_t("module_name", Locale::From(&LOCALE_DEMOHOME))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn description(&self) -> Option<String> {
|
fn description(&self) -> Option<String> {
|
||||||
Some(t("module_description", Locale::From(&LOCALE_DEMOHOME)))
|
Some(_t("module_description", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dependencies(&self) -> Vec<ModuleStaticRef> {
|
fn dependencies(&self) -> Vec<ModuleStaticRef> {
|
||||||
|
|
@ -34,7 +34,7 @@ impl ModuleTrait for HomeDemo {
|
||||||
|
|
||||||
async fn demo(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
async fn demo(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
||||||
Page::new(request)
|
Page::new(request)
|
||||||
.with_title(t("page_title", Locale::From(&LOCALE_DEMOHOME)).as_str())
|
.with_title(_t("page_title", Locale::From(&LOCALE_DEMOHOME)).as_str())
|
||||||
.with_context(ContextOp::AddStyleSheet(StyleSheet::located(
|
.with_context(ContextOp::AddStyleSheet(StyleSheet::located(
|
||||||
"/homedemo/css/styles.css",
|
"/homedemo/css/styles.css",
|
||||||
)))
|
)))
|
||||||
|
|
@ -56,13 +56,13 @@ fn hello_world() -> Container {
|
||||||
.with_size(grid::ColumnSize::Is5of12)
|
.with_size(grid::ColumnSize::Is5of12)
|
||||||
.with_component(
|
.with_component(
|
||||||
Heading::h1(html! {
|
Heading::h1(html! {
|
||||||
(t("page_title", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("page_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
})
|
})
|
||||||
.with_display(HeadingDisplay::Medium),
|
.with_display(HeadingDisplay::Medium),
|
||||||
)
|
)
|
||||||
.with_component(
|
.with_component(
|
||||||
Paragraph::with(html! {
|
Paragraph::with(html! {
|
||||||
(e("hello_intro", Locale::With(&LOCALE_DEMOHOME, &args![
|
(_e("hello_intro", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||||
"app" => format!(
|
"app" => format!(
|
||||||
"<span class=\"app-name\">{}</span>",
|
"<span class=\"app-name\">{}</span>",
|
||||||
&config::SETTINGS.app.name,
|
&config::SETTINGS.app.name,
|
||||||
|
|
@ -72,7 +72,7 @@ fn hello_world() -> Container {
|
||||||
.with_display(ParagraphDisplay::Small),
|
.with_display(ParagraphDisplay::Small),
|
||||||
)
|
)
|
||||||
.with_component(Paragraph::with(html! {
|
.with_component(Paragraph::with(html! {
|
||||||
(e("hello_powered", Locale::With(&LOCALE_DEMOHOME, &args![
|
(_e("hello_powered", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||||
"pagetop" => format!(
|
"pagetop" => format!(
|
||||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||||
"https://pagetop.cillero.es",
|
"https://pagetop.cillero.es",
|
||||||
|
|
@ -83,7 +83,7 @@ fn hello_world() -> Container {
|
||||||
.with_component(
|
.with_component(
|
||||||
Anchor::button(
|
Anchor::button(
|
||||||
"https://github.com/manuelcillero/pagetop",
|
"https://github.com/manuelcillero/pagetop",
|
||||||
html! { (t("hello_code", Locale::From(&LOCALE_DEMOHOME))) },
|
html! { (_t("hello_code", Locale::From(&LOCALE_DEMOHOME))) },
|
||||||
)
|
)
|
||||||
.with_target(AnchorTarget::Blank)
|
.with_target(AnchorTarget::Blank)
|
||||||
.with_left_icon(Icon::with("git"))
|
.with_left_icon(Icon::with("git"))
|
||||||
|
|
@ -92,7 +92,7 @@ fn hello_world() -> Container {
|
||||||
.with_component(
|
.with_component(
|
||||||
Anchor::link(
|
Anchor::link(
|
||||||
"#welcome",
|
"#welcome",
|
||||||
html! { (t("hello_welcome", Locale::From(&LOCALE_DEMOHOME))) },
|
html! { (_t("hello_welcome", Locale::From(&LOCALE_DEMOHOME))) },
|
||||||
)
|
)
|
||||||
.with_left_icon(Icon::with("arrow-down-circle-fill"))
|
.with_left_icon(Icon::with("arrow-down-circle-fill"))
|
||||||
.with_classes(ClassesOp::Add, "welcome-link"),
|
.with_classes(ClassesOp::Add, "welcome-link"),
|
||||||
|
|
@ -111,11 +111,11 @@ fn welcome() -> Container {
|
||||||
.with_id("welcome")
|
.with_id("welcome")
|
||||||
.with_classes(ClassesOp::Add, "welcome-col-text")
|
.with_classes(ClassesOp::Add, "welcome-col-text")
|
||||||
.with_component(Heading::h2(html! {
|
.with_component(Heading::h2(html! {
|
||||||
(t("welcome_page", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("welcome_page", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
}))
|
}))
|
||||||
.with_component(
|
.with_component(
|
||||||
Heading::h3(html! {
|
Heading::h3(html! {
|
||||||
(e("welcome_subtitle", Locale::With(&LOCALE_DEMOHOME, &args![
|
(_e("welcome_subtitle", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||||
"app" => format!(
|
"app" => format!(
|
||||||
"<span class=\"app-name\">{}</span>",
|
"<span class=\"app-name\">{}</span>",
|
||||||
&config::SETTINGS.app.name
|
&config::SETTINGS.app.name
|
||||||
|
|
@ -126,12 +126,12 @@ fn welcome() -> Container {
|
||||||
)
|
)
|
||||||
.with_component(
|
.with_component(
|
||||||
Paragraph::with(html! {
|
Paragraph::with(html! {
|
||||||
(t("welcome_text1", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("welcome_text1", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
})
|
})
|
||||||
.with_display(ParagraphDisplay::Small),
|
.with_display(ParagraphDisplay::Small),
|
||||||
)
|
)
|
||||||
.with_component(Paragraph::with(
|
.with_component(Paragraph::with(
|
||||||
html! { (t("welcome_text2", Locale::From(&LOCALE_DEMOHOME))) },
|
html! { (_t("welcome_text2", Locale::From(&LOCALE_DEMOHOME))) },
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,23 +148,23 @@ fn about_pagetop() -> Container {
|
||||||
grid::Column::new()
|
grid::Column::new()
|
||||||
.with_classes(ClassesOp::Add, "pagetop-col-text")
|
.with_classes(ClassesOp::Add, "pagetop-col-text")
|
||||||
.with_component(Heading::h2(html! {
|
.with_component(Heading::h2(html! {
|
||||||
(t("pagetop_title", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("pagetop_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
}))
|
}))
|
||||||
.with_component(
|
.with_component(
|
||||||
Paragraph::with(html! {
|
Paragraph::with(html! {
|
||||||
(t("pagetop_text1", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("pagetop_text1", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
})
|
})
|
||||||
.with_display(ParagraphDisplay::Small),
|
.with_display(ParagraphDisplay::Small),
|
||||||
)
|
)
|
||||||
.with_component(Paragraph::with(html! {
|
.with_component(Paragraph::with(html! {
|
||||||
(t("pagetop_text2", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("pagetop_text2", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
}))
|
}))
|
||||||
.with_component(Paragraph::with(html! {
|
.with_component(Paragraph::with(html! {
|
||||||
(e("pagetop_text3", Locale::With(&LOCALE_DEMOHOME, &args![
|
(_e("pagetop_text3", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||||
"pagetop_website" => format!(
|
"pagetop_website" => format!(
|
||||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||||
"https://docs.rs/pagetop/latest/pagetop",
|
"https://docs.rs/pagetop/latest/pagetop",
|
||||||
t("pagetop_website", Locale::From(&LOCALE_DEMOHOME)),
|
_t("pagetop_website", Locale::From(&LOCALE_DEMOHOME)),
|
||||||
)
|
)
|
||||||
])))
|
])))
|
||||||
})),
|
})),
|
||||||
|
|
@ -179,11 +179,11 @@ fn promo_pagetop() -> Container {
|
||||||
grid::Column::new()
|
grid::Column::new()
|
||||||
.with_classes(ClassesOp::Add, "promo-col-text")
|
.with_classes(ClassesOp::Add, "promo-col-text")
|
||||||
.with_component(Heading::h2(html! {
|
.with_component(Heading::h2(html! {
|
||||||
(t("pagetop_promo_title", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("pagetop_promo_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
}))
|
}))
|
||||||
.with_component(
|
.with_component(
|
||||||
Paragraph::with(html! {
|
Paragraph::with(html! {
|
||||||
(e("pagetop_promo_text1", Locale::With(&LOCALE_DEMOHOME, &args![
|
(_e("pagetop_promo_text1", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||||
"pagetop" => format!(
|
"pagetop" => format!(
|
||||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||||
"https://crates.io/crates/pagetop",
|
"https://crates.io/crates/pagetop",
|
||||||
|
|
@ -216,16 +216,16 @@ fn reporting_issues() -> Container {
|
||||||
.with_classes(ClassesOp::Add, "reporting-col-text")
|
.with_classes(ClassesOp::Add, "reporting-col-text")
|
||||||
.with_size(grid::ColumnSize::Is6of12)
|
.with_size(grid::ColumnSize::Is6of12)
|
||||||
.with_component(Heading::h2(html! {
|
.with_component(Heading::h2(html! {
|
||||||
(t("report_problems_title", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("report_problems_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
}))
|
}))
|
||||||
.with_component(
|
.with_component(
|
||||||
Paragraph::with(html! {
|
Paragraph::with(html! {
|
||||||
(t("report_problems_text1", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("report_problems_text1", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
})
|
})
|
||||||
.with_display(ParagraphDisplay::Small),
|
.with_display(ParagraphDisplay::Small),
|
||||||
)
|
)
|
||||||
.with_component(Paragraph::with(html! {
|
.with_component(Paragraph::with(html! {
|
||||||
(t("report_problems_text2", Locale::From(&LOCALE_DEMOHOME)))
|
(_t("report_problems_text2", Locale::From(&LOCALE_DEMOHOME)))
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub enum AnchorTarget {
|
||||||
Context(String),
|
Context(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type AnchorIcon = ComponentsBundle;
|
pub type AnchorIcon = ComponentArc;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -74,7 +74,7 @@ impl ComponentTrait for Anchor {
|
||||||
target=[target]
|
target=[target]
|
||||||
{
|
{
|
||||||
(self.left_icon().render(rcx))
|
(self.left_icon().render(rcx))
|
||||||
span { (*self.html()) }
|
(" ") span { (*self.html()) } (" ")
|
||||||
(self.right_icon().render(rcx))
|
(self.right_icon().render(rcx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -158,15 +158,13 @@ impl Anchor {
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_left_icon(&mut self, icon: Icon) -> &mut Self {
|
pub fn alter_left_icon(&mut self, icon: Icon) -> &mut Self {
|
||||||
self.left_icon.clear();
|
self.left_icon.replace(icon);
|
||||||
self.left_icon.add(icon);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_right_icon(&mut self, icon: Icon) -> &mut Self {
|
pub fn alter_right_icon(&mut self, icon: Icon) -> &mut Self {
|
||||||
self.right_icon.clear();
|
self.right_icon.replace(icon);
|
||||||
self.right_icon.add(icon);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ impl ModuleTrait for Menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
t("module_name", Locale::From(&LOCALE_MENU))
|
_t("module_name", Locale::From(&LOCALE_MENU))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn description(&self) -> Option<String> {
|
fn description(&self) -> Option<String> {
|
||||||
Some(t("module_description", Locale::From(&LOCALE_MENU)))
|
Some(_t("module_description", Locale::From(&LOCALE_MENU)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ impl ModuleTrait for Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
t("module_name", Locale::From(&LOCALE_NODE))
|
_t("module_name", Locale::From(&LOCALE_NODE))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn description(&self) -> Option<String> {
|
fn description(&self) -> Option<String> {
|
||||||
Some(t("module_description", Locale::From(&LOCALE_NODE)))
|
Some(_t("module_description", Locale::From(&LOCALE_NODE)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_service(&self, cfg: &mut server::web::ServiceConfig) {
|
fn configure_service(&self, cfg: &mut server::web::ServiceConfig) {
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ impl ModuleTrait for User {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
t("module_name", Locale::From(&LOCALE_USER))
|
_t("module_name", Locale::From(&LOCALE_USER))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn description(&self) -> Option<String> {
|
fn description(&self) -> Option<String> {
|
||||||
Some(t("module_description", Locale::From(&LOCALE_USER)))
|
Some(_t("module_description", Locale::From(&LOCALE_USER)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dependencies(&self) -> Vec<ModuleStaticRef> {
|
fn dependencies(&self) -> Vec<ModuleStaticRef> {
|
||||||
|
|
@ -58,9 +58,9 @@ fn form_login() -> Form {
|
||||||
.with_element(
|
.with_element(
|
||||||
form_element::Input::textfield()
|
form_element::Input::textfield()
|
||||||
.with_name("name")
|
.with_name("name")
|
||||||
.with_label(t("username", Locale::From(&LOCALE_USER)).as_str())
|
.with_label(_t("username", Locale::From(&LOCALE_USER)).as_str())
|
||||||
.with_help_text(
|
.with_help_text(
|
||||||
t(
|
_t(
|
||||||
"username_help",
|
"username_help",
|
||||||
Locale::With(
|
Locale::With(
|
||||||
&LOCALE_USER,
|
&LOCALE_USER,
|
||||||
|
|
@ -74,10 +74,10 @@ fn form_login() -> Form {
|
||||||
.with_element(
|
.with_element(
|
||||||
form_element::Input::password()
|
form_element::Input::password()
|
||||||
.with_name("pass")
|
.with_name("pass")
|
||||||
.with_label(t("password", Locale::From(&LOCALE_USER)).as_str())
|
.with_label(_t("password", Locale::From(&LOCALE_USER)).as_str())
|
||||||
.with_help_text(t("password_help", Locale::From(&LOCALE_USER)).as_str()),
|
.with_help_text(_t("password_help", Locale::From(&LOCALE_USER)).as_str()),
|
||||||
)
|
)
|
||||||
.with_element(form_element::Button::submit(
|
.with_element(form_element::Button::submit(
|
||||||
t("login", Locale::From(&LOCALE_USER)).as_str(),
|
_t("login", Locale::From(&LOCALE_USER)).as_str(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ tracing-unwrap = { version = "0.10.0", default-features = false }
|
||||||
tracing-actix-web = "0.7.4"
|
tracing-actix-web = "0.7.4"
|
||||||
|
|
||||||
fluent-templates = "0.8.0"
|
fluent-templates = "0.8.0"
|
||||||
unic-langid = "0.9.1"
|
unic-langid = { version = "0.9.1", features = ["macros"] }
|
||||||
|
|
||||||
actix-web = "4"
|
actix-web = "4"
|
||||||
actix-session = { version = "0.7.2", features = ["cookie-session"] }
|
actix-session = { version = "0.7.2", features = ["cookie-session"] }
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ mod figfont;
|
||||||
|
|
||||||
use crate::core::{module, module::ModuleStaticRef};
|
use crate::core::{module, module::ModuleStaticRef};
|
||||||
use crate::html::Markup;
|
use crate::html::Markup;
|
||||||
|
use crate::response::fatal_error::FatalError;
|
||||||
use crate::response::page::ResultPage;
|
use crate::response::page::ResultPage;
|
||||||
use crate::response::FatalError;
|
|
||||||
use crate::{config, locale, server, trace, LazyStatic};
|
use crate::{config, locale, server, trace, LazyStatic};
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
|
mod context;
|
||||||
|
pub use context::{ContextOp, RenderContext};
|
||||||
|
|
||||||
mod definition;
|
mod definition;
|
||||||
pub use definition::{component_mut, component_ref, AnyComponent, BaseComponent, ComponentTrait};
|
pub use definition::{component_mut, component_ref, AnyComponent, BaseComponent, ComponentTrait};
|
||||||
|
|
||||||
|
mod arc;
|
||||||
|
pub use arc::ComponentArc;
|
||||||
|
|
||||||
mod bundle;
|
mod bundle;
|
||||||
pub use bundle::ComponentsBundle;
|
pub use bundle::ComponentsBundle;
|
||||||
|
|
||||||
|
|
|
||||||
32
pagetop/src/core/component/arc.rs
Normal file
32
pagetop/src/core/component/arc.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
use crate::core::component::{ComponentTrait, RenderContext};
|
||||||
|
use crate::html::{html, Markup};
|
||||||
|
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub struct ComponentArc(Option<Arc<RwLock<dyn ComponentTrait>>>);
|
||||||
|
|
||||||
|
impl ComponentArc {
|
||||||
|
pub fn new(component: impl ComponentTrait) -> Self {
|
||||||
|
ComponentArc(Some(Arc::new(RwLock::new(component))))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace(&mut self, component: impl ComponentTrait) {
|
||||||
|
self.0 = Some(Arc::new(RwLock::new(component)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn weight(&self) -> isize {
|
||||||
|
match &self.0 {
|
||||||
|
Some(component) => component.read().unwrap().weight(),
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(&self, rcx: &mut RenderContext) -> Markup {
|
||||||
|
html! {
|
||||||
|
@if let Some(component) = &self.0 {
|
||||||
|
(component.write().unwrap().render(rcx))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
use crate::core::component::ComponentTrait;
|
use crate::core::component::{ComponentArc, ComponentTrait, RenderContext};
|
||||||
use crate::html::{html, Markup, RenderContext};
|
use crate::html::{html, Markup};
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct ComponentsBundle(Vec<Arc<RwLock<dyn ComponentTrait>>>);
|
pub struct ComponentsBundle(Vec<ComponentArc>);
|
||||||
|
|
||||||
impl ComponentsBundle {
|
impl ComponentsBundle {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
|
@ -12,13 +10,13 @@ impl ComponentsBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with(component: impl ComponentTrait) -> Self {
|
pub fn new_with(component: impl ComponentTrait) -> Self {
|
||||||
let mut container = ComponentsBundle::new();
|
let mut bundle = ComponentsBundle::new();
|
||||||
container.add(component);
|
bundle.add(component);
|
||||||
container
|
bundle
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, component: impl ComponentTrait) {
|
pub fn add(&mut self, component: impl ComponentTrait) {
|
||||||
self.0.push(Arc::new(RwLock::new(component)));
|
self.0.push(ComponentArc::new(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
|
|
@ -27,10 +25,10 @@ impl ComponentsBundle {
|
||||||
|
|
||||||
pub fn render(&self, rcx: &mut RenderContext) -> Markup {
|
pub fn render(&self, rcx: &mut RenderContext) -> Markup {
|
||||||
let mut components = self.0.clone();
|
let mut components = self.0.clone();
|
||||||
components.sort_by_key(|c| c.read().unwrap().weight());
|
components.sort_by_key(|c| c.weight());
|
||||||
html! {
|
html! {
|
||||||
@for c in components.iter() {
|
@for c in components.iter() {
|
||||||
(" ")(c.write().unwrap().render(rcx))(" ")
|
(" ")(c.render(rcx))(" ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::core::module::{all::theme_by_single_name, ThemeStaticRef};
|
use crate::core::module::{all::theme_by_single_name, ThemeStaticRef};
|
||||||
use crate::html::{html, Assets, IdentifierValue, JavaScript, Markup, StyleSheet};
|
use crate::html::{html, Assets, IdentifierValue, JavaScript, Markup, StyleSheet};
|
||||||
|
use crate::locale::{LanguageIdentifier, LANGID};
|
||||||
use crate::server::HttpRequest;
|
use crate::server::HttpRequest;
|
||||||
use crate::{concat_string, config, util, LazyStatic};
|
use crate::{concat_string, config, util, LazyStatic};
|
||||||
|
|
||||||
|
|
@ -23,6 +24,7 @@ pub enum ContextOp {
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub struct RenderContext {
|
pub struct RenderContext {
|
||||||
|
language : &'static LanguageIdentifier,
|
||||||
theme : ThemeStaticRef,
|
theme : ThemeStaticRef,
|
||||||
request : Option<HttpRequest>,
|
request : Option<HttpRequest>,
|
||||||
stylesheets: Assets<StyleSheet>,
|
stylesheets: Assets<StyleSheet>,
|
||||||
|
|
@ -35,6 +37,7 @@ impl Default for RenderContext {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
RenderContext {
|
RenderContext {
|
||||||
|
language : &LANGID,
|
||||||
theme : *DEFAULT_THEME,
|
theme : *DEFAULT_THEME,
|
||||||
request : None,
|
request : None,
|
||||||
stylesheets: Assets::<StyleSheet>::new(),
|
stylesheets: Assets::<StyleSheet>::new(),
|
||||||
|
|
@ -81,6 +84,10 @@ impl RenderContext {
|
||||||
|
|
||||||
/// Context GETTERS.
|
/// Context GETTERS.
|
||||||
|
|
||||||
|
pub(crate) fn language(&self) -> &LanguageIdentifier {
|
||||||
|
self.language
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn theme(&self) -> ThemeStaticRef {
|
pub(crate) fn theme(&self) -> ThemeStaticRef {
|
||||||
self.theme
|
self.theme
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
use crate::html::{html, Markup, RenderContext};
|
use crate::core::component::RenderContext;
|
||||||
|
use crate::html::{html, Markup};
|
||||||
use crate::util::single_type_name;
|
use crate::util::single_type_name;
|
||||||
use crate::Handle;
|
use crate::{define_handle, Handle};
|
||||||
|
|
||||||
pub use std::any::Any as AnyComponent;
|
pub use std::any::Any as AnyComponent;
|
||||||
|
|
||||||
|
define_handle!(COMPONENT_UNDEFINED);
|
||||||
|
|
||||||
pub trait BaseComponent {
|
pub trait BaseComponent {
|
||||||
fn render(&mut self, rcx: &mut RenderContext) -> Markup;
|
fn render(&mut self, rcx: &mut RenderContext) -> Markup;
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +16,9 @@ pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
fn handle(&self) -> Handle;
|
fn handle(&self) -> Handle {
|
||||||
|
COMPONENT_UNDEFINED
|
||||||
|
}
|
||||||
|
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
single_type_name::<Self>().to_owned()
|
single_type_name::<Self>().to_owned()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::core::component::{AnyComponent, ComponentTrait};
|
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
|
||||||
use crate::html::{html, Markup, RenderContext};
|
use crate::html::{html, Markup};
|
||||||
use crate::{define_handle, Handle};
|
use crate::{define_handle, Handle};
|
||||||
|
|
||||||
define_handle!(HTML_MARKUP);
|
define_handle!(HTML_MARKUP);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::html::RenderContext;
|
use crate::core::component::RenderContext;
|
||||||
|
|
||||||
pub type IsRenderable = fn(&RenderContext) -> bool;
|
pub type IsRenderable = fn(&RenderContext) -> bool;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use super::ModuleTrait;
|
use super::ModuleTrait;
|
||||||
|
|
||||||
use crate::core::component::{ComponentTrait, HtmlMarkup};
|
use crate::core::component::{ComponentTrait, RenderContext};
|
||||||
use crate::html::{html, Favicon, Markup, RenderContext};
|
use crate::html::{html, Favicon, Markup};
|
||||||
use crate::response::page::Page;
|
use crate::response::page::Page;
|
||||||
use crate::{concat_string, config};
|
use crate::{concat_string, config};
|
||||||
|
|
||||||
|
|
@ -118,20 +118,4 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_404_not_found(&self) -> HtmlMarkup {
|
|
||||||
HtmlMarkup::new().with(html! {
|
|
||||||
div {
|
|
||||||
h1 { ("RESOURCE NOT FOUND") }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn error_403_access_denied(&self) -> HtmlMarkup {
|
|
||||||
HtmlMarkup::new().with(html! {
|
|
||||||
div {
|
|
||||||
h1 { ("FORBIDDEN ACCESS") }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@ pub use assets::javascript::{JavaScript, ModeJS};
|
||||||
pub use assets::stylesheet::{StyleSheet, TargetMedia};
|
pub use assets::stylesheet::{StyleSheet, TargetMedia};
|
||||||
pub use assets::Assets;
|
pub use assets::Assets;
|
||||||
|
|
||||||
mod context;
|
|
||||||
pub use context::{ContextOp, RenderContext};
|
|
||||||
|
|
||||||
mod favicon;
|
mod favicon;
|
||||||
pub use favicon::Favicon;
|
pub use favicon::Favicon;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,59 +85,12 @@ pub mod server;
|
||||||
// Tipos de respuestas a peticiones web.
|
// Tipos de respuestas a peticiones web.
|
||||||
pub mod response;
|
pub mod response;
|
||||||
|
|
||||||
// Funciones útiles.
|
// Funciones útiles y macros declarativas.
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
// Prepara y ejecuta la aplicación.
|
// Prepara y ejecuta la aplicación.
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
|
||||||
// *************************************************************************************************
|
|
||||||
// MACROS DECLARATIVAS.
|
|
||||||
// *************************************************************************************************
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
/// Macro para construir grupos de pares clave-valor.
|
|
||||||
///
|
|
||||||
/// ```rust#ignore
|
|
||||||
/// let args = args![
|
|
||||||
/// "userName" => "Roberto",
|
|
||||||
/// "photoCount" => 3,
|
|
||||||
/// "userGender" => "male"
|
|
||||||
/// ];
|
|
||||||
/// ```
|
|
||||||
macro_rules! args {
|
|
||||||
( $($key:expr => $value:expr),* ) => {{
|
|
||||||
let mut a = std::collections::HashMap::new();
|
|
||||||
$(
|
|
||||||
a.insert(String::from($key), $value.into());
|
|
||||||
)*
|
|
||||||
a
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! define_handle {
|
|
||||||
( $HANDLE:ident ) => {
|
|
||||||
pub const $HANDLE: $crate::Handle =
|
|
||||||
$crate::util::handle(module_path!(), file!(), line!(), column!());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! serve_static_files {
|
|
||||||
( $cfg:ident, $dir:expr, $embed:ident ) => {{
|
|
||||||
let static_files = &$crate::config::SETTINGS.dev.static_files;
|
|
||||||
if static_files.is_empty() {
|
|
||||||
$cfg.service($crate::server::ResourceFiles::new($dir, $embed()));
|
|
||||||
} else {
|
|
||||||
$cfg.service(
|
|
||||||
$crate::server::ActixFiles::new($dir, $crate::concat_string!(static_files, $dir))
|
|
||||||
.show_files_listing(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// RE-EXPORTA API ÚNICA.
|
// RE-EXPORTA API ÚNICA.
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -92,34 +92,49 @@
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::html::{Markup, PreEscaped};
|
use crate::html::{Markup, PreEscaped};
|
||||||
use crate::{config, trace, LazyStatic};
|
use crate::{args, config, trace, LazyStatic};
|
||||||
|
|
||||||
use unic_langid::LanguageIdentifier;
|
use unic_langid::langid;
|
||||||
|
|
||||||
pub use fluent_templates;
|
pub use fluent_templates;
|
||||||
pub use fluent_templates::fluent_bundle::FluentValue;
|
pub use fluent_templates::fluent_bundle::FluentValue;
|
||||||
pub use fluent_templates::{static_loader as static_locale, Loader, StaticLoader as Locales};
|
pub use fluent_templates::{static_loader as static_locale, Loader, StaticLoader as Locales};
|
||||||
|
|
||||||
|
pub use unic_langid::LanguageIdentifier;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
static LANGUAGES: LazyStatic<HashMap<String, (LanguageIdentifier, &str)>> = LazyStatic::new(|| {
|
||||||
|
args![
|
||||||
|
"en" => (langid!("en-US"), "English"),
|
||||||
|
"en-US" => (langid!("en-US"), "English (...)"),
|
||||||
|
"es" => (langid!("es-ES"), "Spanish"),
|
||||||
|
"es-ES" => (langid!("es-ES"), "Spanish (Spain)")
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
static DEFAULT_LANGID: LazyStatic<LanguageIdentifier> = LazyStatic::new(|| langid!("en-US"));
|
||||||
|
|
||||||
/// Almacena el Identificador de Idioma Unicode
|
/// Almacena el Identificador de Idioma Unicode
|
||||||
/// ([Unicode Language Identifier](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier))
|
/// ([Unicode Language Identifier](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier))
|
||||||
/// para la aplicación, obtenido de `SETTINGS.app.language`.
|
/// para la aplicación, obtenido de `SETTINGS.app.language`.
|
||||||
pub static LANGID: LazyStatic<LanguageIdentifier> =
|
pub static LANGID: LazyStatic<&LanguageIdentifier> =
|
||||||
LazyStatic::new(|| match config::SETTINGS.app.language.parse() {
|
LazyStatic::new(
|
||||||
Ok(language) => language,
|
|| match LANGUAGES.get(config::SETTINGS.app.language.as_str()) {
|
||||||
Err(_) => {
|
Some((langid, _)) => langid,
|
||||||
trace::warn!(
|
_ => {
|
||||||
"{}, {} \"{}\"! {}, {}",
|
trace::warn!(
|
||||||
"Failed to parse language",
|
"{}, {} \"{}\"! {}, {}",
|
||||||
"unrecognized Unicode Language Identifier",
|
"Failed to parse language",
|
||||||
config::SETTINGS.app.language,
|
"unrecognized Unicode Language Identifier",
|
||||||
"Using \"en-US\"",
|
config::SETTINGS.app.language,
|
||||||
"check the settings file",
|
"Using \"en-US\"",
|
||||||
);
|
"check the settings file",
|
||||||
"en-US".parse().unwrap()
|
);
|
||||||
}
|
&*DEFAULT_LANGID
|
||||||
});
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
/// Define un conjunto de elementos de localización y funciones locales de traducción.
|
/// Define un conjunto de elementos de localización y funciones locales de traducción.
|
||||||
|
|
@ -128,7 +143,7 @@ macro_rules! define_locale {
|
||||||
use $crate::locale::*;
|
use $crate::locale::*;
|
||||||
|
|
||||||
static_locale! {
|
static_locale! {
|
||||||
static $LOCALES = {
|
pub static $LOCALES = {
|
||||||
locales: $dir_locales,
|
locales: $dir_locales,
|
||||||
$( core_locales: $core_locales, )?
|
$( core_locales: $core_locales, )?
|
||||||
fallback_language: "en-US",
|
fallback_language: "en-US",
|
||||||
|
|
@ -151,7 +166,7 @@ pub enum Locale<'a> {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn t(key: &str, locale: Locale) -> String {
|
pub fn _t(key: &str, locale: Locale) -> String {
|
||||||
match locale {
|
match locale {
|
||||||
Locale::From(locales) => locales.lookup(&LANGID, key).unwrap_or(key.to_string()),
|
Locale::From(locales) => locales.lookup(&LANGID, key).unwrap_or(key.to_string()),
|
||||||
Locale::With(locales, args) => locales
|
Locale::With(locales, args) => locales
|
||||||
|
|
@ -164,6 +179,6 @@ pub fn t(key: &str, locale: Locale) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn e(key: &str, locale: Locale) -> Markup {
|
pub fn _e(key: &str, locale: Locale) -> Markup {
|
||||||
PreEscaped(t(key, locale))
|
PreEscaped(_t(key, locale))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ pub use crate::{hook_action, hook_before_render_component};
|
||||||
pub use crate::server;
|
pub use crate::server;
|
||||||
pub use crate::server::HttpMessage;
|
pub use crate::server::HttpMessage;
|
||||||
|
|
||||||
pub use crate::response::{page::*, FatalError, ResponseError};
|
pub use crate::response::fatal_error::*;
|
||||||
|
pub use crate::response::{page::*, ResponseError};
|
||||||
|
|
||||||
pub use crate::app::Application;
|
pub use crate::app::Application;
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,4 @@ pub use actix_web::ResponseError;
|
||||||
|
|
||||||
pub mod page;
|
pub mod page;
|
||||||
|
|
||||||
mod fatal_error;
|
pub mod fatal_error;
|
||||||
pub use fatal_error::FatalError;
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
mod error403;
|
||||||
|
pub use error403::ERROR_403;
|
||||||
|
mod error404;
|
||||||
|
pub use error404::ERROR_404;
|
||||||
|
|
||||||
use crate::response::{page::Page, ResponseError};
|
use crate::response::{page::Page, ResponseError};
|
||||||
use crate::server::http::{header::ContentType, StatusCode};
|
use crate::server::http::{header::ContentType, StatusCode};
|
||||||
use crate::server::{HttpRequest, HttpResponse};
|
use crate::server::{HttpRequest, HttpResponse};
|
||||||
|
|
@ -24,11 +29,10 @@ impl fmt::Display for FatalError {
|
||||||
FatalError::BadRequest(_) => write!(f, "Bad Client Data"),
|
FatalError::BadRequest(_) => write!(f, "Bad Client Data"),
|
||||||
// Error 403.
|
// Error 403.
|
||||||
FatalError::AccessDenied(request) => {
|
FatalError::AccessDenied(request) => {
|
||||||
let mut error_page = Page::new(request.clone());
|
let error_page = Page::new(request.clone());
|
||||||
let error_content = error_page.context().theme().error_403_access_denied();
|
|
||||||
if let Ok(page) = error_page
|
if let Ok(page) = error_page
|
||||||
.with_title("Error FORBIDDEN")
|
.with_title("Error FORBIDDEN")
|
||||||
.with_this_in("region-content", error_content)
|
.with_this_in("region-content", error403::Error403)
|
||||||
.with_template("error")
|
.with_template("error")
|
||||||
.render()
|
.render()
|
||||||
{
|
{
|
||||||
|
|
@ -39,11 +43,10 @@ impl fmt::Display for FatalError {
|
||||||
}
|
}
|
||||||
// Error 404.
|
// Error 404.
|
||||||
FatalError::NotFound(request) => {
|
FatalError::NotFound(request) => {
|
||||||
let mut error_page = Page::new(request.clone());
|
let error_page = Page::new(request.clone());
|
||||||
let error_content = error_page.context().theme().error_404_not_found();
|
|
||||||
if let Ok(page) = error_page
|
if let Ok(page) = error_page
|
||||||
.with_title("Error RESOURCE NOT FOUND")
|
.with_title("Error RESOURCE NOT FOUND")
|
||||||
.with_this_in("region-content", error_content)
|
.with_this_in("region-content", error404::Error404)
|
||||||
.with_template("error")
|
.with_template("error")
|
||||||
.render()
|
.render()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
33
pagetop/src/response/fatal_error/error403.rs
Normal file
33
pagetop/src/response/fatal_error/error403.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
|
||||||
|
use crate::html::{html, Markup};
|
||||||
|
use crate::{define_handle, Handle};
|
||||||
|
|
||||||
|
define_handle!(ERROR_403);
|
||||||
|
|
||||||
|
pub struct Error403;
|
||||||
|
|
||||||
|
impl ComponentTrait for Error403 {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle(&self) -> Handle {
|
||||||
|
ERROR_403
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_render(&self, _rcx: &mut RenderContext) -> Markup {
|
||||||
|
html! {
|
||||||
|
div {
|
||||||
|
h1 { ("FORBIDDEN ACCESS") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_ref_any(&self) -> &dyn AnyComponent {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_mut_any(&mut self) -> &mut dyn AnyComponent {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
33
pagetop/src/response/fatal_error/error404.rs
Normal file
33
pagetop/src/response/fatal_error/error404.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
|
||||||
|
use crate::html::{html, Markup};
|
||||||
|
use crate::{define_handle, Handle};
|
||||||
|
|
||||||
|
define_handle!(ERROR_404);
|
||||||
|
|
||||||
|
pub struct Error404;
|
||||||
|
|
||||||
|
impl ComponentTrait for Error404 {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle(&self) -> Handle {
|
||||||
|
ERROR_404
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_render(&self, _rcx: &mut RenderContext) -> Markup {
|
||||||
|
html! {
|
||||||
|
div {
|
||||||
|
h1 { ("RESOURCE NOT FOUND") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_ref_any(&self) -> &dyn AnyComponent {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_mut_any(&mut self) -> &mut dyn AnyComponent {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,8 @@ use super::{BeforeRenderPageHook, ResultPage, HOOK_BEFORE_RENDER_PAGE};
|
||||||
|
|
||||||
use crate::core::component::*;
|
use crate::core::component::*;
|
||||||
use crate::core::hook::{action_ref, run_actions};
|
use crate::core::hook::{action_ref, run_actions};
|
||||||
use crate::html::{
|
use crate::html::{html, AttributeValue, Classes, ClassesOp, Favicon, Markup, DOCTYPE};
|
||||||
html, AttributeValue, Classes, ClassesOp, ContextOp, Favicon, Markup, RenderContext, DOCTYPE,
|
use crate::response::fatal_error::FatalError;
|
||||||
};
|
|
||||||
use crate::response::FatalError;
|
|
||||||
use crate::{config, fn_builder, locale, server, trace, LazyStatic};
|
use crate::{config, fn_builder, locale, server, trace, LazyStatic};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
//! Funciones útiles.
|
//! Funciones útiles y macros declarativas.
|
||||||
|
|
||||||
use crate::Handle;
|
use crate::Handle;
|
||||||
|
|
||||||
|
// *************************************************************************************************
|
||||||
|
// FUNCIONES ÚTILES.
|
||||||
|
// *************************************************************************************************
|
||||||
|
|
||||||
// https://stackoverflow.com/a/71464396
|
// https://stackoverflow.com/a/71464396
|
||||||
pub const fn handle(
|
pub const fn handle(
|
||||||
module_path: &'static str,
|
module_path: &'static str,
|
||||||
|
|
@ -50,3 +54,50 @@ pub fn partial_type_name(type_name: &'static str, last: usize) -> &'static str {
|
||||||
pub fn single_type_name<T: ?Sized>() -> &'static str {
|
pub fn single_type_name<T: ?Sized>() -> &'static str {
|
||||||
partial_type_name(std::any::type_name::<T>(), 1)
|
partial_type_name(std::any::type_name::<T>(), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************************
|
||||||
|
// MACROS DECLARATIVAS.
|
||||||
|
// *************************************************************************************************
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
/// Macro para construir grupos de pares clave-valor.
|
||||||
|
///
|
||||||
|
/// ```rust#ignore
|
||||||
|
/// let args = args![
|
||||||
|
/// "userName" => "Roberto",
|
||||||
|
/// "photoCount" => 3,
|
||||||
|
/// "userGender" => "male"
|
||||||
|
/// ];
|
||||||
|
/// ```
|
||||||
|
macro_rules! args {
|
||||||
|
( $($key:expr => $value:expr),* ) => {{
|
||||||
|
let mut a = std::collections::HashMap::new();
|
||||||
|
$(
|
||||||
|
a.insert(String::from($key), $value.into());
|
||||||
|
)*
|
||||||
|
a
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! define_handle {
|
||||||
|
( $HANDLE:ident ) => {
|
||||||
|
pub const $HANDLE: $crate::Handle =
|
||||||
|
$crate::util::handle(module_path!(), file!(), line!(), column!());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serve_static_files {
|
||||||
|
( $cfg:ident, $dir:expr, $embed:ident ) => {{
|
||||||
|
let static_files = &$crate::config::SETTINGS.dev.static_files;
|
||||||
|
if static_files.is_empty() {
|
||||||
|
$cfg.service($crate::server::ResourceFiles::new($dir, $embed()));
|
||||||
|
} else {
|
||||||
|
$cfg.service(
|
||||||
|
$crate::server::ActixFiles::new($dir, $crate::concat_string!(static_files, $dir))
|
||||||
|
.show_files_listing(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue