🍻 Tercera revista a las traducciones por contexto
This commit is contained in:
parent
88d6ce2a72
commit
dd443ca375
21 changed files with 415 additions and 252 deletions
|
|
@ -14,11 +14,11 @@ impl ModuleTrait for Admin {
|
|||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
_t("module_name", Locale::From(&LOCALE_ADMIN))
|
||||
t("module_name", Locale::From(&LOCALE_ADMIN))
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
Some(_t("module_description", Locale::From(&LOCALE_ADMIN)))
|
||||
Some(t("module_description", Locale::From(&LOCALE_ADMIN)))
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
|
|
|||
|
|
@ -5,54 +5,58 @@ use pagetop_minimal::component::*;
|
|||
|
||||
pub async fn summary(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
||||
let top_menu = MegaMenu::new()
|
||||
.with_item(MegaMenuItem::label(
|
||||
_t("module_name", Locale::From(&LOCALE_ADMIN)).as_str(),
|
||||
.with_item(MegaMenuItem::label(L10n::t("module_name", &LOCALE_ADMIN)))
|
||||
.with_item(MegaMenuItem::link(
|
||||
L10n::n("Opción 2"),
|
||||
"https://www.google.es",
|
||||
))
|
||||
.with_item(MegaMenuItem::link("Opción 2", "https://www.google.es"))
|
||||
.with_item(MegaMenuItem::link_blank(
|
||||
"Opción 3",
|
||||
L10n::n("Opción 3"),
|
||||
"https://www.google.es",
|
||||
))
|
||||
.with_item(MegaMenuItem::submenu(
|
||||
"Submenú 1",
|
||||
L10n::n("Submenú 1"),
|
||||
MegaMenu::new()
|
||||
.with_item(MegaMenuItem::label("Opción 1"))
|
||||
.with_item(MegaMenuItem::label("Opción 2")),
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 1")))
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 2"))),
|
||||
))
|
||||
.with_item(MegaMenuItem::separator())
|
||||
.with_item(MegaMenuItem::submenu(
|
||||
"Submenú 2",
|
||||
L10n::n("Submenú 2"),
|
||||
MegaMenu::new()
|
||||
.with_item(MegaMenuItem::label("Opción 1"))
|
||||
.with_item(MegaMenuItem::label("Opción 2")),
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 1")))
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 2"))),
|
||||
))
|
||||
.with_item(MegaMenuItem::label("Opción 4"));
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 4")));
|
||||
|
||||
let side_menu = MegaMenu::new()
|
||||
.with_item(MegaMenuItem::label("Opción 1"))
|
||||
.with_item(MegaMenuItem::link("Opción 2", "https://www.google.es"))
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 1")))
|
||||
.with_item(MegaMenuItem::link(
|
||||
L10n::n("Opción 2"),
|
||||
"https://www.google.es",
|
||||
))
|
||||
.with_item(MegaMenuItem::link_blank(
|
||||
"Opción 3",
|
||||
L10n::n("Opción 3"),
|
||||
"https://www.google.es",
|
||||
))
|
||||
.with_item(MegaMenuItem::submenu(
|
||||
"Submenú 1",
|
||||
L10n::n("Submenú 1"),
|
||||
MegaMenu::new()
|
||||
.with_item(MegaMenuItem::label("Opción 1"))
|
||||
.with_item(MegaMenuItem::label("Opción 2")),
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 1")))
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 2"))),
|
||||
))
|
||||
.with_item(MegaMenuItem::separator())
|
||||
.with_item(MegaMenuItem::submenu(
|
||||
"Submenú 2",
|
||||
L10n::n("Submenú 2"),
|
||||
MegaMenu::new()
|
||||
.with_item(MegaMenuItem::label("Opción 1"))
|
||||
.with_item(MegaMenuItem::label("Opción 2")),
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 1")))
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 2"))),
|
||||
))
|
||||
.with_item(MegaMenuItem::label("Opción 4"));
|
||||
.with_item(MegaMenuItem::label(L10n::n("Opción 4")));
|
||||
|
||||
Page::new(request)
|
||||
.with_context(ContextOp::Theme("Bootsier"))
|
||||
.with_title("Admin")
|
||||
.with_title(L10n::n("Admin"))
|
||||
.with_this_in("top-menu", top_menu)
|
||||
.with_this_in(
|
||||
"region-content",
|
||||
|
|
|
|||
|
|
@ -58,15 +58,15 @@ impl ThemeTrait for Bootsier {
|
|||
alt="Caution!";
|
||||
div class="media-body" {
|
||||
h1 class="display-4" { ("RESOURCE NOT FOUND") }
|
||||
p class="lead" { (_t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
||||
p class="lead" { (t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
||||
hr class="my-4";
|
||||
p { (_t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
||||
p { (t("e404-description", Locale::From(&LOCALE_BOOTSIER))) }
|
||||
a
|
||||
class="btn btn-primary btn-lg"
|
||||
href="/"
|
||||
role="button"
|
||||
{
|
||||
(_t("back-homepage", Locale::From(&LOCALE_BOOTSIER)))
|
||||
(t("back-homepage", Locale::From(&LOCALE_BOOTSIER)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ impl ModuleTrait for HomeDemo {
|
|||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
_t("module_name", Locale::From(&LOCALE_DEMOHOME))
|
||||
t("module_name", Locale::From(&LOCALE_DEMOHOME))
|
||||
}
|
||||
|
||||
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> {
|
||||
|
|
@ -34,7 +34,7 @@ impl ModuleTrait for HomeDemo {
|
|||
|
||||
async fn demo(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
||||
Page::new(request)
|
||||
.with_title(_t("page_title", Locale::From(&LOCALE_DEMOHOME)).as_str())
|
||||
.with_title(L10n::t("page_title", &LOCALE_DEMOHOME))
|
||||
.with_context(ContextOp::AddStyleSheet(StyleSheet::located(
|
||||
"/homedemo/css/styles.css",
|
||||
)))
|
||||
|
|
@ -55,45 +55,39 @@ fn hello_world() -> Container {
|
|||
.with_classes(ClassesOp::Add, "hello-col-text")
|
||||
.with_size(grid::ColumnSize::Is5of12)
|
||||
.with_component(
|
||||
Heading::h1(html! {
|
||||
(_t("page_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||
})
|
||||
Heading::h1(L10n::t("page_title", &LOCALE_DEMOHOME))
|
||||
.with_display(HeadingDisplay::Medium),
|
||||
)
|
||||
.with_component(
|
||||
Paragraph::with(html! {
|
||||
(_e("hello_intro", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||
"app" => format!(
|
||||
Paragraph::with(L10n::e("hello_intro", &LOCALE_DEMOHOME).with_arg(
|
||||
"app",
|
||||
format!(
|
||||
"<span class=\"app-name\">{}</span>",
|
||||
&config::SETTINGS.app.name,
|
||||
)
|
||||
])))
|
||||
})
|
||||
),
|
||||
))
|
||||
.with_display(ParagraphDisplay::Small),
|
||||
)
|
||||
.with_component(Paragraph::with(html! {
|
||||
(_e("hello_powered", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||
"pagetop" => format!(
|
||||
.with_component(Paragraph::with(
|
||||
L10n::e("hello_powered", &LOCALE_DEMOHOME).with_arg(
|
||||
"pagetop",
|
||||
format!(
|
||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||
"https://pagetop.cillero.es",
|
||||
"PageTop",
|
||||
)
|
||||
])))
|
||||
}))
|
||||
"https://pagetop.cillero.es", "PageTop",
|
||||
),
|
||||
),
|
||||
))
|
||||
.with_component(
|
||||
Anchor::button(
|
||||
"https://github.com/manuelcillero/pagetop",
|
||||
html! { (_t("hello_code", Locale::From(&LOCALE_DEMOHOME))) },
|
||||
L10n::t("hello_code", &LOCALE_DEMOHOME),
|
||||
)
|
||||
.with_target(AnchorTarget::Blank)
|
||||
.with_left_icon(Icon::with("git"))
|
||||
.with_classes(ClassesOp::Add, "code-link"),
|
||||
)
|
||||
.with_component(
|
||||
Anchor::link(
|
||||
"#welcome",
|
||||
html! { (_t("hello_welcome", Locale::From(&LOCALE_DEMOHOME))) },
|
||||
)
|
||||
Anchor::link("#welcome", L10n::t("hello_welcome", &LOCALE_DEMOHOME))
|
||||
.with_left_icon(Icon::with("arrow-down-circle-fill"))
|
||||
.with_classes(ClassesOp::Add, "welcome-link"),
|
||||
),
|
||||
|
|
@ -110,29 +104,22 @@ fn welcome() -> Container {
|
|||
Container::section()
|
||||
.with_id("welcome")
|
||||
.with_classes(ClassesOp::Add, "welcome-col-text")
|
||||
.with_component(Heading::h2(html! {
|
||||
(_t("welcome_page", Locale::From(&LOCALE_DEMOHOME)))
|
||||
}))
|
||||
.with_component(Heading::h2(L10n::t("welcome_page", &LOCALE_DEMOHOME)))
|
||||
.with_component(
|
||||
Heading::h3(html! {
|
||||
(_e("welcome_subtitle", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||
"app" => format!(
|
||||
Heading::h3(L10n::e("welcome_subtitle", &LOCALE_DEMOHOME).with_arg(
|
||||
"app",
|
||||
format!(
|
||||
"<span class=\"app-name\">{}</span>",
|
||||
&config::SETTINGS.app.name
|
||||
)
|
||||
])))
|
||||
})
|
||||
),
|
||||
))
|
||||
.with_display(HeadingDisplay::Subtitle),
|
||||
)
|
||||
.with_component(
|
||||
Paragraph::with(html! {
|
||||
(_t("welcome_text1", Locale::From(&LOCALE_DEMOHOME)))
|
||||
})
|
||||
Paragraph::with(L10n::t("welcome_text1", &LOCALE_DEMOHOME))
|
||||
.with_display(ParagraphDisplay::Small),
|
||||
)
|
||||
.with_component(Paragraph::with(
|
||||
html! { (_t("welcome_text2", Locale::From(&LOCALE_DEMOHOME))) },
|
||||
))
|
||||
.with_component(Paragraph::with(L10n::t("welcome_text2", &LOCALE_DEMOHOME)))
|
||||
}
|
||||
|
||||
fn about_pagetop() -> Container {
|
||||
|
|
@ -147,27 +134,22 @@ fn about_pagetop() -> Container {
|
|||
.with_column(
|
||||
grid::Column::new()
|
||||
.with_classes(ClassesOp::Add, "pagetop-col-text")
|
||||
.with_component(Heading::h2(html! {
|
||||
(_t("pagetop_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||
}))
|
||||
.with_component(Heading::h2(L10n::t("pagetop_title", &LOCALE_DEMOHOME)))
|
||||
.with_component(
|
||||
Paragraph::with(html! {
|
||||
(_t("pagetop_text1", Locale::From(&LOCALE_DEMOHOME)))
|
||||
})
|
||||
Paragraph::with(L10n::t("pagetop_text1", &LOCALE_DEMOHOME))
|
||||
.with_display(ParagraphDisplay::Small),
|
||||
)
|
||||
.with_component(Paragraph::with(html! {
|
||||
(_t("pagetop_text2", Locale::From(&LOCALE_DEMOHOME)))
|
||||
}))
|
||||
.with_component(Paragraph::with(html! {
|
||||
(_e("pagetop_text3", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||
"pagetop_website" => format!(
|
||||
.with_component(Paragraph::with(L10n::t("pagetop_text2", &LOCALE_DEMOHOME)))
|
||||
.with_component(Paragraph::with(
|
||||
L10n::e("pagetop_text3", &LOCALE_DEMOHOME).with_arg(
|
||||
"pagetop_website",
|
||||
format!(
|
||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||
"https://docs.rs/pagetop/latest/pagetop",
|
||||
_t("pagetop_website", Locale::From(&LOCALE_DEMOHOME)),
|
||||
)
|
||||
])))
|
||||
})),
|
||||
t("pagetop_website", Locale::From(&LOCALE_DEMOHOME)),
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -178,19 +160,18 @@ fn promo_pagetop() -> Container {
|
|||
.with_column(
|
||||
grid::Column::new()
|
||||
.with_classes(ClassesOp::Add, "promo-col-text")
|
||||
.with_component(Heading::h2(html! {
|
||||
(_t("pagetop_promo_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||
}))
|
||||
.with_component(Heading::h2(L10n::t(
|
||||
"pagetop_promo_title",
|
||||
&LOCALE_DEMOHOME,
|
||||
)))
|
||||
.with_component(
|
||||
Paragraph::with(html! {
|
||||
(_e("pagetop_promo_text1", Locale::With(&LOCALE_DEMOHOME, &args![
|
||||
"pagetop" => format!(
|
||||
Paragraph::with(L10n::e("pagetop_promo_text1", &LOCALE_DEMOHOME).with_arg(
|
||||
"pagetop",
|
||||
format!(
|
||||
"<a href=\"{}\" target=\"_blank\">{}</a>",
|
||||
"https://crates.io/crates/pagetop",
|
||||
"PageTop",
|
||||
)
|
||||
])))
|
||||
})
|
||||
"https://crates.io/crates/pagetop", "PageTop",
|
||||
),
|
||||
))
|
||||
.with_display(ParagraphDisplay::Small),
|
||||
),
|
||||
)
|
||||
|
|
@ -215,18 +196,18 @@ fn reporting_issues() -> Container {
|
|||
grid::Column::new()
|
||||
.with_classes(ClassesOp::Add, "reporting-col-text")
|
||||
.with_size(grid::ColumnSize::Is6of12)
|
||||
.with_component(Heading::h2(html! {
|
||||
(_t("report_problems_title", Locale::From(&LOCALE_DEMOHOME)))
|
||||
}))
|
||||
.with_component(Heading::h2(L10n::t(
|
||||
"report_problems_title",
|
||||
&LOCALE_DEMOHOME,
|
||||
)))
|
||||
.with_component(
|
||||
Paragraph::with(html! {
|
||||
(_t("report_problems_text1", Locale::From(&LOCALE_DEMOHOME)))
|
||||
})
|
||||
Paragraph::with(L10n::t("report_problems_text1", &LOCALE_DEMOHOME))
|
||||
.with_display(ParagraphDisplay::Small),
|
||||
)
|
||||
.with_component(Paragraph::with(html! {
|
||||
(_t("report_problems_text2", Locale::From(&LOCALE_DEMOHOME)))
|
||||
})),
|
||||
.with_component(Paragraph::with(L10n::t(
|
||||
"report_problems_text2",
|
||||
&LOCALE_DEMOHOME,
|
||||
))),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ define_handle!(COMPONENT_MEGAMENUITEM);
|
|||
pub enum MegaMenuItemType {
|
||||
#[default]
|
||||
Void,
|
||||
Label(String),
|
||||
Link(String, String),
|
||||
LinkBlank(String, String),
|
||||
Label(ComponentArc),
|
||||
Link(ComponentArc, String),
|
||||
LinkBlank(ComponentArc, String),
|
||||
Html(Markup),
|
||||
Submenu(String, MegaMenu),
|
||||
Submenu(ComponentArc, MegaMenu),
|
||||
Separator,
|
||||
}
|
||||
|
||||
|
|
@ -46,14 +46,14 @@ impl ComponentTrait for MegaMenuItem {
|
|||
MegaMenuItemType::Void => html! {},
|
||||
|
||||
MegaMenuItemType::Label(label) => html! {
|
||||
li class="label" { a href="#" { (label) } }
|
||||
li class="label" { a href="#" { (label.render(rcx)) } }
|
||||
},
|
||||
MegaMenuItemType::Link(label, path) => html! {
|
||||
li class="link" { a href=(path) { (label) } }
|
||||
li class="link" { a href=(path) { (label.render(rcx)) } }
|
||||
},
|
||||
MegaMenuItemType::LinkBlank(label, path) => html! {
|
||||
li class="link_blank" {
|
||||
a href=(path) target="_blank" { (label) }
|
||||
a href=(path) target="_blank" { (label.render(rcx)) }
|
||||
}
|
||||
},
|
||||
MegaMenuItemType::Html(html) => html! {
|
||||
|
|
@ -61,7 +61,7 @@ impl ComponentTrait for MegaMenuItem {
|
|||
},
|
||||
MegaMenuItemType::Submenu(label, menu) => html! {
|
||||
li class="submenu" {
|
||||
a href="#" { (label) }
|
||||
a href="#" { (label.render(rcx)) }
|
||||
ul {
|
||||
(menu.items().render(rcx))
|
||||
}
|
||||
|
|
@ -83,23 +83,23 @@ impl ComponentTrait for MegaMenuItem {
|
|||
}
|
||||
|
||||
impl MegaMenuItem {
|
||||
pub fn label(label: &str) -> Self {
|
||||
pub fn label(label: L10n) -> Self {
|
||||
MegaMenuItem {
|
||||
item_type: MegaMenuItemType::Label(label.to_owned()),
|
||||
item_type: MegaMenuItemType::Label(ComponentArc::new_with(label)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link(label: &str, path: &str) -> Self {
|
||||
pub fn link(label: L10n, path: &str) -> Self {
|
||||
MegaMenuItem {
|
||||
item_type: MegaMenuItemType::Link(label.to_owned(), path.to_owned()),
|
||||
item_type: MegaMenuItemType::Link(ComponentArc::new_with(label), path.to_owned()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link_blank(label: &str, path: &str) -> Self {
|
||||
pub fn link_blank(label: L10n, path: &str) -> Self {
|
||||
MegaMenuItem {
|
||||
item_type: MegaMenuItemType::LinkBlank(label.to_owned(), path.to_owned()),
|
||||
item_type: MegaMenuItemType::LinkBlank(ComponentArc::new_with(label), path.to_owned()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
@ -111,9 +111,9 @@ impl MegaMenuItem {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn submenu(label: &str, menu: MegaMenu) -> Self {
|
||||
pub fn submenu(label: L10n, menu: MegaMenu) -> Self {
|
||||
MegaMenuItem {
|
||||
item_type: MegaMenuItemType::Submenu(label.to_owned(), menu),
|
||||
item_type: MegaMenuItemType::Submenu(ComponentArc::new_with(label), menu),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ pub enum AnchorTarget {
|
|||
}
|
||||
|
||||
pub type AnchorIcon = ComponentArc;
|
||||
pub type AnchorHtml = ComponentArc;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
|
|
@ -33,7 +34,7 @@ pub struct Anchor {
|
|||
classes : Classes,
|
||||
anchor_type: AnchorType,
|
||||
href : AttributeValue,
|
||||
html : HtmlMarkup,
|
||||
html10n : AnchorHtml,
|
||||
left_icon : AnchorIcon,
|
||||
right_icon : AnchorIcon,
|
||||
target : AnchorTarget,
|
||||
|
|
@ -74,7 +75,7 @@ impl ComponentTrait for Anchor {
|
|||
target=[target]
|
||||
{
|
||||
(self.left_icon().render(rcx))
|
||||
(" ") span { (*self.html()) } (" ")
|
||||
(" ") span { (self.html().render(rcx)) } (" ")
|
||||
(self.right_icon().render(rcx))
|
||||
}
|
||||
}
|
||||
|
|
@ -90,15 +91,15 @@ impl ComponentTrait for Anchor {
|
|||
}
|
||||
|
||||
impl Anchor {
|
||||
pub fn link(href: &str, html: Markup) -> Self {
|
||||
Anchor::new().with_href(href).with_html(html)
|
||||
pub fn link(href: &str, html10n: L10n) -> Self {
|
||||
Anchor::new().with_href(href).with_html(html10n)
|
||||
}
|
||||
|
||||
pub fn button(href: &str, html: Markup) -> Self {
|
||||
pub fn button(href: &str, html10n: L10n) -> Self {
|
||||
Anchor::new()
|
||||
.with_type(AnchorType::Button)
|
||||
.with_href(href)
|
||||
.with_html(html)
|
||||
.with_html(html10n)
|
||||
}
|
||||
|
||||
pub fn location(id: &str) -> Self {
|
||||
|
|
@ -151,20 +152,20 @@ impl Anchor {
|
|||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_html(&mut self, html: Markup) -> &mut Self {
|
||||
self.html.markup = html;
|
||||
pub fn alter_html(&mut self, html10n: L10n) -> &mut Self {
|
||||
self.html10n.set(html10n);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_left_icon(&mut self, icon: Icon) -> &mut Self {
|
||||
self.left_icon.replace(icon);
|
||||
self.left_icon.set(icon);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_right_icon(&mut self, icon: Icon) -> &mut Self {
|
||||
self.right_icon.replace(icon);
|
||||
self.right_icon.set(icon);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -198,8 +199,8 @@ impl Anchor {
|
|||
&self.href
|
||||
}
|
||||
|
||||
pub fn html(&self) -> &Markup {
|
||||
&self.html.markup
|
||||
pub fn html(&self) -> &AnchorHtml {
|
||||
&self.html10n
|
||||
}
|
||||
|
||||
pub fn left_icon(&self) -> &AnchorIcon {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ pub enum ButtonType {
|
|||
Reset,
|
||||
}
|
||||
|
||||
pub type ButtonValue = ComponentArc;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Button {
|
||||
|
|
@ -18,7 +20,7 @@ pub struct Button {
|
|||
classes : Classes,
|
||||
button_type: ButtonType,
|
||||
name : AttributeValue,
|
||||
value : AttributeValue,
|
||||
value : ButtonValue,
|
||||
autofocus : AttributeValue,
|
||||
disabled : AttributeValue,
|
||||
template : String,
|
||||
|
|
@ -43,7 +45,7 @@ impl ComponentTrait for Button {
|
|||
(self.renderable.check)(rcx)
|
||||
}
|
||||
|
||||
fn default_render(&self, _: &mut RenderContext) -> Markup {
|
||||
fn default_render(&self, rcx: &mut RenderContext) -> Markup {
|
||||
let button_type = match self.button_type() {
|
||||
ButtonType::Button => "button",
|
||||
ButtonType::Submit => "submit",
|
||||
|
|
@ -56,11 +58,11 @@ impl ComponentTrait for Button {
|
|||
id=[id]
|
||||
class=[self.classes().get()]
|
||||
name=[self.name().get()]
|
||||
value=[self.value().get()]
|
||||
value=(self.value().render(rcx))
|
||||
autofocus=[self.autofocus().get()]
|
||||
disabled=[self.disabled().get()]
|
||||
{
|
||||
@if let Some(value) = self.value().get() { (value) }
|
||||
(self.value().render(rcx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,11 +77,11 @@ impl ComponentTrait for Button {
|
|||
}
|
||||
|
||||
impl Button {
|
||||
pub fn with(value: &str) -> Self {
|
||||
pub fn with(value: L10n) -> Self {
|
||||
Button::new().with_value(value)
|
||||
}
|
||||
|
||||
pub fn submit(value: &str) -> Self {
|
||||
pub fn submit(value: L10n) -> Self {
|
||||
let mut button = Button::new()
|
||||
.with_classes(ClassesOp::Replace("form-button"), "form-submit")
|
||||
.with_value(value);
|
||||
|
|
@ -87,7 +89,7 @@ impl Button {
|
|||
button
|
||||
}
|
||||
|
||||
pub fn reset(value: &str) -> Self {
|
||||
pub fn reset(value: L10n) -> Self {
|
||||
let mut button = Button::new()
|
||||
.with_classes(ClassesOp::Replace("form-button"), "form-reset")
|
||||
.with_value(value);
|
||||
|
|
@ -122,8 +124,8 @@ impl Button {
|
|||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_value(&mut self, value: &str) -> &mut Self {
|
||||
self.value.alter_value(value);
|
||||
pub fn alter_value(&mut self, value: L10n) -> &mut Self {
|
||||
self.value.set(value);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +167,7 @@ impl Button {
|
|||
&self.name
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &AttributeValue {
|
||||
pub fn value(&self) -> &ButtonValue {
|
||||
&self.value
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ pub enum InputType {
|
|||
Url,
|
||||
}
|
||||
|
||||
pub type InputLabel = ComponentArc;
|
||||
pub type InputHelpText = ComponentArc;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Input {
|
||||
|
|
@ -22,7 +25,7 @@ pub struct Input {
|
|||
input_type : InputType,
|
||||
name : NameValue,
|
||||
value : AttributeValue,
|
||||
label : AttributeValue,
|
||||
label : InputLabel,
|
||||
size : Option<u16>,
|
||||
minlength : Option<u16>,
|
||||
maxlength : Option<u16>,
|
||||
|
|
@ -32,7 +35,7 @@ pub struct Input {
|
|||
disabled : AttributeValue,
|
||||
readonly : AttributeValue,
|
||||
required : AttributeValue,
|
||||
help_text : AttributeValue,
|
||||
help_text : InputHelpText,
|
||||
template : String,
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +61,7 @@ impl ComponentTrait for Input {
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn default_render(&self, _: &mut RenderContext) -> Markup {
|
||||
fn default_render(&self, rcx: &mut RenderContext) -> Markup {
|
||||
let type_input = match self.input_type() {
|
||||
InputType::Textfield => "text",
|
||||
InputType::Password => "password",
|
||||
|
|
@ -70,7 +73,7 @@ impl ComponentTrait for Input {
|
|||
let id = self.name().get().map(|name| concat_string!("edit-", name));
|
||||
html! {
|
||||
div class=[self.classes().get()] {
|
||||
@if let Some(label) = self.label().get() {
|
||||
@if let Some(label) = self.label().optional_render(rcx) {
|
||||
label class="form-label" for=[&id] {
|
||||
(label) " "
|
||||
@if self.required().get().is_some() {
|
||||
|
|
@ -95,8 +98,8 @@ impl ComponentTrait for Input {
|
|||
readonly=[self.readonly().get()]
|
||||
required=[self.required().get()]
|
||||
disabled=[self.disabled().get()];
|
||||
@if let Some(help_text) = self.help_text().get() {
|
||||
div class="form-text" { (help_text) }
|
||||
@if let Some(description) = self.help_text().optional_render(rcx) {
|
||||
div class="form-text" { (description) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -203,8 +206,8 @@ impl Input {
|
|||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_label(&mut self, label: &str) -> &mut Self {
|
||||
self.label.alter_value(label);
|
||||
pub fn alter_label(&mut self, label: L10n) -> &mut Self {
|
||||
self.label.set(label);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -278,8 +281,8 @@ impl Input {
|
|||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_help_text(&mut self, help_text: &str) -> &mut Self {
|
||||
self.help_text.alter_value(help_text);
|
||||
pub fn alter_help_text(&mut self, help_text: L10n) -> &mut Self {
|
||||
self.help_text.set(help_text);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +310,7 @@ impl Input {
|
|||
&self.value
|
||||
}
|
||||
|
||||
pub fn label(&self) -> &AttributeValue {
|
||||
pub fn label(&self) -> &InputLabel {
|
||||
&self.label
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +350,7 @@ impl Input {
|
|||
&self.required
|
||||
}
|
||||
|
||||
pub fn help_text(&self) -> &AttributeValue {
|
||||
pub fn help_text(&self) -> &InputHelpText {
|
||||
&self.help_text
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ pub enum HeadingDisplay {
|
|||
Subtitle,
|
||||
}
|
||||
|
||||
pub type HeadingText = ComponentArc;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Heading {
|
||||
|
|
@ -33,7 +35,7 @@ pub struct Heading {
|
|||
id : IdentifierValue,
|
||||
classes : Classes,
|
||||
heading_type: HeadingType,
|
||||
html : HtmlMarkup,
|
||||
text : HeadingText,
|
||||
display : HeadingDisplay,
|
||||
template : String,
|
||||
}
|
||||
|
|
@ -55,16 +57,16 @@ impl ComponentTrait for Heading {
|
|||
(self.renderable.check)(rcx)
|
||||
}
|
||||
|
||||
fn default_render(&self, _: &mut RenderContext) -> Markup {
|
||||
fn default_render(&self, rcx: &mut RenderContext) -> Markup {
|
||||
let id = self.id().get();
|
||||
let classes = self.classes().get();
|
||||
html! { @match &self.heading_type() {
|
||||
HeadingType::H1 => h1 id=[id] class=[classes] { (*self.html()) },
|
||||
HeadingType::H2 => h2 id=[id] class=[classes] { (*self.html()) },
|
||||
HeadingType::H3 => h3 id=[id] class=[classes] { (*self.html()) },
|
||||
HeadingType::H4 => h4 id=[id] class=[classes] { (*self.html()) },
|
||||
HeadingType::H5 => h5 id=[id] class=[classes] { (*self.html()) },
|
||||
HeadingType::H6 => h6 id=[id] class=[classes] { (*self.html()) },
|
||||
HeadingType::H1 => h1 id=[id] class=[classes] { (self.text().render(rcx)) },
|
||||
HeadingType::H2 => h2 id=[id] class=[classes] { (self.text().render(rcx)) },
|
||||
HeadingType::H3 => h3 id=[id] class=[classes] { (self.text().render(rcx)) },
|
||||
HeadingType::H4 => h4 id=[id] class=[classes] { (self.text().render(rcx)) },
|
||||
HeadingType::H5 => h5 id=[id] class=[classes] { (self.text().render(rcx)) },
|
||||
HeadingType::H6 => h6 id=[id] class=[classes] { (self.text().render(rcx)) },
|
||||
}}
|
||||
}
|
||||
|
||||
|
|
@ -78,40 +80,40 @@ impl ComponentTrait for Heading {
|
|||
}
|
||||
|
||||
impl Heading {
|
||||
pub fn h1(html: Markup) -> Self {
|
||||
pub fn h1(text: L10n) -> Self {
|
||||
Heading::new()
|
||||
.with_heading_type(HeadingType::H1)
|
||||
.with_html(html)
|
||||
.with_text(text)
|
||||
}
|
||||
|
||||
pub fn h2(html: Markup) -> Self {
|
||||
pub fn h2(text: L10n) -> Self {
|
||||
Heading::new()
|
||||
.with_heading_type(HeadingType::H2)
|
||||
.with_html(html)
|
||||
.with_text(text)
|
||||
}
|
||||
|
||||
pub fn h3(html: Markup) -> Self {
|
||||
pub fn h3(text: L10n) -> Self {
|
||||
Heading::new()
|
||||
.with_heading_type(HeadingType::H3)
|
||||
.with_html(html)
|
||||
.with_text(text)
|
||||
}
|
||||
|
||||
pub fn h4(html: Markup) -> Self {
|
||||
pub fn h4(text: L10n) -> Self {
|
||||
Heading::new()
|
||||
.with_heading_type(HeadingType::H4)
|
||||
.with_html(html)
|
||||
.with_text(text)
|
||||
}
|
||||
|
||||
pub fn h5(html: Markup) -> Self {
|
||||
pub fn h5(text: L10n) -> Self {
|
||||
Heading::new()
|
||||
.with_heading_type(HeadingType::H5)
|
||||
.with_html(html)
|
||||
.with_text(text)
|
||||
}
|
||||
|
||||
pub fn h6(html: Markup) -> Self {
|
||||
pub fn h6(text: L10n) -> Self {
|
||||
Heading::new()
|
||||
.with_heading_type(HeadingType::H6)
|
||||
.with_html(html)
|
||||
.with_text(text)
|
||||
}
|
||||
|
||||
// Heading BUILDER.
|
||||
|
|
@ -147,8 +149,8 @@ impl Heading {
|
|||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_html(&mut self, html: Markup) -> &mut Self {
|
||||
self.html.markup = html;
|
||||
pub fn alter_text(&mut self, text: L10n) -> &mut Self {
|
||||
self.text.set(text);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -191,8 +193,8 @@ impl Heading {
|
|||
&self.heading_type
|
||||
}
|
||||
|
||||
pub fn html(&self) -> &Markup {
|
||||
&self.html.markup
|
||||
pub fn text(&self) -> &HeadingText {
|
||||
&self.text
|
||||
}
|
||||
|
||||
pub fn display(&self) -> &HeadingDisplay {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::component::Html;
|
||||
|
||||
define_handle!(COMPONENT_PARAGRAPH);
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -65,8 +63,8 @@ impl ComponentTrait for Paragraph {
|
|||
}
|
||||
|
||||
impl Paragraph {
|
||||
pub fn with(html: Markup) -> Self {
|
||||
Paragraph::new().with_component(Html::with(html))
|
||||
pub fn with(component: impl ComponentTrait) -> Self {
|
||||
Paragraph::new().with_component(component)
|
||||
}
|
||||
|
||||
// Paragraph BUILDER.
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ impl ModuleTrait for Menu {
|
|||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
_t("module_name", Locale::From(&LOCALE_MENU))
|
||||
t("module_name", Locale::From(&LOCALE_MENU))
|
||||
}
|
||||
|
||||
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 {
|
||||
_t("module_name", Locale::From(&LOCALE_NODE))
|
||||
t("module_name", Locale::From(&LOCALE_NODE))
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -41,7 +41,7 @@ impl ModuleTrait for Node {
|
|||
}
|
||||
|
||||
async fn node(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
||||
Page::new(request).with_title("Nodo").render()
|
||||
Page::new(request).with_title(L10n::n("Nodo")).render()
|
||||
}
|
||||
|
||||
fn before_render_page(page: &mut Page) {
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ impl ModuleTrait for User {
|
|||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
_t("module_name", Locale::From(&LOCALE_USER))
|
||||
t("module_name", Locale::From(&LOCALE_USER))
|
||||
}
|
||||
|
||||
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> {
|
||||
|
|
@ -42,7 +42,7 @@ impl ModuleTrait for User {
|
|||
|
||||
async fn login(request: server::HttpRequest) -> ResultPage<Markup, FatalError> {
|
||||
Page::new(request)
|
||||
.with_title("Identificación del usuario")
|
||||
.with_title(L10n::n("Identificación del usuario"))
|
||||
.with_this_in(
|
||||
"region-content",
|
||||
Container::new()
|
||||
|
|
@ -58,26 +58,18 @@ fn form_login() -> Form {
|
|||
.with_element(
|
||||
form_element::Input::textfield()
|
||||
.with_name("name")
|
||||
.with_label(_t("username", Locale::From(&LOCALE_USER)).as_str())
|
||||
.with_label(L10n::t("username", &LOCALE_USER))
|
||||
.with_help_text(
|
||||
_t(
|
||||
"username_help",
|
||||
Locale::With(
|
||||
&LOCALE_USER,
|
||||
&args!["app" => config::SETTINGS.app.name.to_owned()],
|
||||
),
|
||||
)
|
||||
.as_str(),
|
||||
L10n::t("username_help", &LOCALE_USER)
|
||||
.with_arg("app", config::SETTINGS.app.name.to_owned()),
|
||||
)
|
||||
.with_autofocus(true),
|
||||
)
|
||||
.with_element(
|
||||
form_element::Input::password()
|
||||
.with_name("pass")
|
||||
.with_label(_t("password", Locale::From(&LOCALE_USER)).as_str())
|
||||
.with_help_text(_t("password_help", Locale::From(&LOCALE_USER)).as_str()),
|
||||
.with_label(L10n::t("password", &LOCALE_USER))
|
||||
.with_help_text(L10n::t("password_help", &LOCALE_USER)),
|
||||
)
|
||||
.with_element(form_element::Button::submit(
|
||||
_t("login", Locale::From(&LOCALE_USER)).as_str(),
|
||||
))
|
||||
.with_element(form_element::Button::submit(L10n::t("login", &LOCALE_USER)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ pub use context::{ContextOp, RenderContext};
|
|||
mod definition;
|
||||
pub use definition::{component_mut, component_ref, AnyComponent, BaseComponent, ComponentTrait};
|
||||
|
||||
mod default;
|
||||
pub(crate) use default::DefaultComponent;
|
||||
|
||||
mod arc;
|
||||
pub use arc::ComponentArc;
|
||||
|
||||
|
|
@ -19,3 +22,6 @@ pub use renderable::{IsRenderable, Renderable};
|
|||
|
||||
mod html_markup;
|
||||
pub use html_markup::HtmlMarkup;
|
||||
|
||||
mod l10n;
|
||||
pub use l10n::L10n;
|
||||
|
|
|
|||
|
|
@ -1,32 +1,45 @@
|
|||
use crate::core::component::{ComponentTrait, RenderContext};
|
||||
use crate::core::component::{ComponentTrait, DefaultComponent, RenderContext};
|
||||
use crate::html::{html, Markup};
|
||||
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ComponentArc(Option<Arc<RwLock<dyn ComponentTrait>>>);
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentArc(Arc<RwLock<dyn ComponentTrait>>);
|
||||
|
||||
impl Default for ComponentArc {
|
||||
fn default() -> Self {
|
||||
ComponentArc(Arc::new(RwLock::new(DefaultComponent)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentArc {
|
||||
pub fn new(component: impl ComponentTrait) -> Self {
|
||||
ComponentArc(Some(Arc::new(RwLock::new(component))))
|
||||
pub fn new() -> Self {
|
||||
ComponentArc::default()
|
||||
}
|
||||
|
||||
pub fn replace(&mut self, component: impl ComponentTrait) {
|
||||
self.0 = Some(Arc::new(RwLock::new(component)));
|
||||
pub fn new_with(component: impl ComponentTrait) -> Self {
|
||||
ComponentArc(Arc::new(RwLock::new(component)))
|
||||
}
|
||||
|
||||
pub fn set(&mut self, component: impl ComponentTrait) {
|
||||
self.0 = Arc::new(RwLock::new(component));
|
||||
}
|
||||
|
||||
pub fn weight(&self) -> isize {
|
||||
match &self.0 {
|
||||
Some(component) => component.read().unwrap().weight(),
|
||||
_ => 0,
|
||||
}
|
||||
self.0.read().unwrap().weight()
|
||||
}
|
||||
|
||||
// ComponentArc RENDER.
|
||||
|
||||
pub fn render(&self, rcx: &mut RenderContext) -> Markup {
|
||||
html! {
|
||||
@if let Some(component) = &self.0 {
|
||||
(component.write().unwrap().render(rcx))
|
||||
self.0.write().unwrap().render(rcx)
|
||||
}
|
||||
|
||||
pub fn optional_render(&self, rcx: &mut RenderContext) -> Option<Markup> {
|
||||
let render = self.0.write().unwrap().render(rcx).into_string();
|
||||
if !render.trim().is_empty() {
|
||||
return Some(html! { (render) });
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ impl ComponentsBundle {
|
|||
}
|
||||
|
||||
pub fn add(&mut self, component: impl ComponentTrait) {
|
||||
self.0.push(ComponentArc::new(component));
|
||||
self.0.push(ComponentArc::new_with(component));
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
|
|
|
|||
18
pagetop/src/core/component/default.rs
Normal file
18
pagetop/src/core/component/default.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
use crate::core::component::{AnyComponent, ComponentTrait};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DefaultComponent;
|
||||
|
||||
impl ComponentTrait for DefaultComponent {
|
||||
fn new() -> Self {
|
||||
DefaultComponent::default()
|
||||
}
|
||||
|
||||
fn as_ref_any(&self) -> &dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_any(&mut self) -> &mut dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
}
|
||||
138
pagetop/src/core/component/l10n.rs
Normal file
138
pagetop/src/core/component/l10n.rs
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
use crate::core::component::{AnyComponent, ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Markup, PreEscaped};
|
||||
use crate::locale::{translate, Locale, Locales};
|
||||
use crate::{define_handle, fn_builder, Handle};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
define_handle!(COMPONENT_L10N);
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct L10n {
|
||||
key : &'static str,
|
||||
locales: Option<&'static Locales>,
|
||||
args : HashMap<&'static str, String>,
|
||||
escaped: bool,
|
||||
}
|
||||
|
||||
impl ComponentTrait for L10n {
|
||||
fn new() -> Self {
|
||||
L10n::default()
|
||||
}
|
||||
|
||||
fn handle(&self) -> Handle {
|
||||
COMPONENT_L10N
|
||||
}
|
||||
|
||||
fn default_render(&self, rcx: &mut RenderContext) -> Markup {
|
||||
if let Some(locales) = self.locales() {
|
||||
html! {
|
||||
@if self.escaped() {
|
||||
(PreEscaped(translate(
|
||||
self.key(),
|
||||
Locale::Using(
|
||||
rcx.language(),
|
||||
locales,
|
||||
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
|
||||
args.insert(key.to_string(), value.to_owned().into());
|
||||
args
|
||||
})
|
||||
)
|
||||
)))
|
||||
} @else {
|
||||
(translate(
|
||||
self.key(),
|
||||
Locale::Using(
|
||||
rcx.language(),
|
||||
locales,
|
||||
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
|
||||
args.insert(key.to_string(), value.to_owned().into());
|
||||
args
|
||||
})
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
html! { (self.key()) }
|
||||
}
|
||||
}
|
||||
|
||||
fn as_ref_any(&self) -> &dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_any(&mut self) -> &mut dyn AnyComponent {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl L10n {
|
||||
pub fn n(text: &'static str) -> Self {
|
||||
L10n {
|
||||
key: text,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn t(key: &'static str, locales: &'static Locales) -> Self {
|
||||
L10n {
|
||||
key,
|
||||
locales: Some(locales),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn e(key: &'static str, locales: &'static Locales) -> Self {
|
||||
L10n {
|
||||
key,
|
||||
locales: Some(locales),
|
||||
escaped: true,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
// HtmL10n BUILDER.
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_key(&mut self, key: &'static str) -> &mut Self {
|
||||
self.key = key;
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_locales(&mut self, locales: &'static Locales) -> &mut Self {
|
||||
self.locales = Some(locales);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_arg(&mut self, arg: &'static str, value: String) -> &mut Self {
|
||||
self.args.insert(arg, value);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn clear_args(&mut self) -> &mut Self {
|
||||
self.args.drain();
|
||||
self
|
||||
}
|
||||
|
||||
// HtmL10n GETTERS.
|
||||
|
||||
pub fn key(&self) -> &str {
|
||||
self.key
|
||||
}
|
||||
|
||||
pub fn locales(&self) -> Option<&Locales> {
|
||||
self.locales
|
||||
}
|
||||
|
||||
pub fn args(&self) -> &HashMap<&str, String> {
|
||||
&self.args
|
||||
}
|
||||
|
||||
pub fn escaped(&self) -> bool {
|
||||
self.escaped
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
use super::ModuleTrait;
|
||||
|
||||
use crate::config;
|
||||
use crate::core::component::{ComponentTrait, RenderContext};
|
||||
use crate::html::{html, Favicon, Markup};
|
||||
use crate::response::page::Page;
|
||||
use crate::{concat_string, config};
|
||||
|
||||
pub type ThemeStaticRef = &'static dyn ThemeTrait;
|
||||
|
||||
|
|
@ -17,20 +17,21 @@ pub trait ThemeTrait: ModuleTrait + Send + Sync {
|
|||
}
|
||||
|
||||
fn render_page_head(&self, page: &mut Page) -> Markup {
|
||||
let title = page.title();
|
||||
let description = page.description();
|
||||
let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no";
|
||||
html! {
|
||||
head {
|
||||
meta charset="utf-8";
|
||||
|
||||
@match page.title().get() {
|
||||
Some(t) => title {
|
||||
(concat_string!(config::SETTINGS.app.name, " | ", t))
|
||||
},
|
||||
None => title { (config::SETTINGS.app.name) }
|
||||
@if !title.is_empty() {
|
||||
title { (config::SETTINGS.app.name) (" | ") (title) }
|
||||
} @else {
|
||||
title { (config::SETTINGS.app.name) }
|
||||
}
|
||||
|
||||
@if let Some(d) = page.description().get() {
|
||||
meta name="description" content=(d);
|
||||
@if !description.is_empty() {
|
||||
meta name="description" content=(description);
|
||||
}
|
||||
|
||||
meta name="viewport" content=(viewport);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ pub use error403::ERROR_403;
|
|||
mod error404;
|
||||
pub use error404::ERROR_404;
|
||||
|
||||
use crate::core::component::L10n;
|
||||
use crate::response::{page::Page, ResponseError};
|
||||
use crate::server::http::{header::ContentType, StatusCode};
|
||||
use crate::server::{HttpRequest, HttpResponse};
|
||||
|
|
@ -31,7 +32,7 @@ impl fmt::Display for FatalError {
|
|||
FatalError::AccessDenied(request) => {
|
||||
let error_page = Page::new(request.clone());
|
||||
if let Ok(page) = error_page
|
||||
.with_title("Error FORBIDDEN")
|
||||
.with_title(L10n::n("Error FORBIDDEN"))
|
||||
.with_this_in("region-content", error403::Error403)
|
||||
.with_template("error")
|
||||
.render()
|
||||
|
|
@ -45,7 +46,7 @@ impl fmt::Display for FatalError {
|
|||
FatalError::NotFound(request) => {
|
||||
let error_page = Page::new(request.clone());
|
||||
if let Ok(page) = error_page
|
||||
.with_title("Error RESOURCE NOT FOUND")
|
||||
.with_title(L10n::n("Error RESOURCE NOT FOUND"))
|
||||
.with_this_in("region-content", error404::Error404)
|
||||
.with_template("error")
|
||||
.render()
|
||||
|
|
|
|||
|
|
@ -32,12 +32,15 @@ pub enum TextDirection {
|
|||
RightToLeft,
|
||||
}
|
||||
|
||||
pub type PageTitle = ComponentArc;
|
||||
pub type PageDescription = ComponentArc;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub struct Page {
|
||||
language : AttributeValue,
|
||||
direction : AttributeValue,
|
||||
title : AttributeValue,
|
||||
description : AttributeValue,
|
||||
title : PageTitle,
|
||||
description : PageDescription,
|
||||
metadata : Vec<(&'static str, &'static str)>,
|
||||
properties : Vec<(&'static str, &'static str)>,
|
||||
favicon : Option<Favicon>,
|
||||
|
|
@ -56,8 +59,8 @@ impl Default for Page {
|
|||
Some(direction) => AttributeValue::new().with_value(direction),
|
||||
_ => AttributeValue::new(),
|
||||
},
|
||||
title : AttributeValue::new(),
|
||||
description : AttributeValue::new(),
|
||||
title : PageTitle::new(),
|
||||
description : PageDescription::new(),
|
||||
metadata : Vec::new(),
|
||||
properties : Vec::new(),
|
||||
favicon : None,
|
||||
|
|
@ -95,14 +98,14 @@ impl Page {
|
|||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_title(&mut self, title: &str) -> &mut Self {
|
||||
self.title.alter_value(title);
|
||||
pub fn alter_title(&mut self, title: L10n) -> &mut Self {
|
||||
self.title.set(title);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_description(&mut self, description: &str) -> &mut Self {
|
||||
self.description.alter_value(description);
|
||||
pub fn alter_description(&mut self, description: L10n) -> &mut Self {
|
||||
self.description.set(description);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -167,12 +170,12 @@ impl Page {
|
|||
&self.direction
|
||||
}
|
||||
|
||||
pub fn title(&self) -> &AttributeValue {
|
||||
&self.title
|
||||
pub fn title(&mut self) -> String {
|
||||
self.title.render(&mut self.context).into_string()
|
||||
}
|
||||
|
||||
pub fn description(&self) -> &AttributeValue {
|
||||
&self.description
|
||||
pub fn description(&mut self) -> String {
|
||||
self.description.render(&mut self.context).into_string()
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> &Vec<(&str, &str)> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue