🍻 Última revista a las traducciones por contexto
This commit is contained in:
parent
23a6f36f62
commit
805c670a53
5 changed files with 50 additions and 86 deletions
|
|
@ -33,8 +33,8 @@ impl Application {
|
||||||
// Inicia registro de trazas y eventos.
|
// Inicia registro de trazas y eventos.
|
||||||
LazyStatic::force(&trace::TRACING);
|
LazyStatic::force(&trace::TRACING);
|
||||||
|
|
||||||
// Valida el identificador de idioma.
|
// Valida el identificador global de idioma.
|
||||||
LazyStatic::force(&locale::LANGID);
|
LazyStatic::force(&locale::DEFAULT_LANGID);
|
||||||
|
|
||||||
#[cfg(feature = "database")]
|
#[cfg(feature = "database")]
|
||||||
// Conecta con la base de datos.
|
// Conecta con la base de datos.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +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::locale::{LanguageIdentifier, DEFAULT_LANGID};
|
||||||
use crate::server::HttpRequest;
|
use crate::server::HttpRequest;
|
||||||
use crate::{concat_string, config, util, LazyStatic};
|
use crate::{concat_string, config, util, LazyStatic};
|
||||||
|
|
||||||
|
|
@ -14,6 +14,7 @@ static DEFAULT_THEME: LazyStatic<ThemeStaticRef> =
|
||||||
});
|
});
|
||||||
|
|
||||||
pub enum ContextOp {
|
pub enum ContextOp {
|
||||||
|
LangId(&'static LanguageIdentifier),
|
||||||
Theme(&'static str),
|
Theme(&'static str),
|
||||||
Request(Option<HttpRequest>),
|
Request(Option<HttpRequest>),
|
||||||
AddStyleSheet(StyleSheet),
|
AddStyleSheet(StyleSheet),
|
||||||
|
|
@ -24,7 +25,7 @@ pub enum ContextOp {
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub struct RenderContext {
|
pub struct RenderContext {
|
||||||
language : &'static LanguageIdentifier,
|
langid : &'static LanguageIdentifier,
|
||||||
theme : ThemeStaticRef,
|
theme : ThemeStaticRef,
|
||||||
request : Option<HttpRequest>,
|
request : Option<HttpRequest>,
|
||||||
stylesheets: Assets<StyleSheet>,
|
stylesheets: Assets<StyleSheet>,
|
||||||
|
|
@ -37,7 +38,7 @@ impl Default for RenderContext {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
RenderContext {
|
RenderContext {
|
||||||
language : &LANGID,
|
langid : &DEFAULT_LANGID,
|
||||||
theme : *DEFAULT_THEME,
|
theme : *DEFAULT_THEME,
|
||||||
request : None,
|
request : None,
|
||||||
stylesheets: Assets::<StyleSheet>::new(),
|
stylesheets: Assets::<StyleSheet>::new(),
|
||||||
|
|
@ -55,6 +56,9 @@ impl RenderContext {
|
||||||
|
|
||||||
pub fn alter(&mut self, op: ContextOp) -> &mut Self {
|
pub fn alter(&mut self, op: ContextOp) -> &mut Self {
|
||||||
match op {
|
match op {
|
||||||
|
ContextOp::LangId(langid) => {
|
||||||
|
self.langid = langid;
|
||||||
|
}
|
||||||
ContextOp::Theme(theme_name) => {
|
ContextOp::Theme(theme_name) => {
|
||||||
self.theme = theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME);
|
self.theme = theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME);
|
||||||
}
|
}
|
||||||
|
|
@ -84,8 +88,8 @@ impl RenderContext {
|
||||||
|
|
||||||
/// Context GETTERS.
|
/// Context GETTERS.
|
||||||
|
|
||||||
pub(crate) fn language(&self) -> &LanguageIdentifier {
|
pub(crate) fn langid(&self) -> &LanguageIdentifier {
|
||||||
self.language
|
self.langid
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn theme(&self) -> ThemeStaticRef {
|
pub(crate) fn theme(&self) -> ThemeStaticRef {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ impl ComponentTrait for L10n {
|
||||||
(PreEscaped(translate(
|
(PreEscaped(translate(
|
||||||
self.key(),
|
self.key(),
|
||||||
Locale::Using(
|
Locale::Using(
|
||||||
rcx.language(),
|
rcx.langid(),
|
||||||
locales,
|
locales,
|
||||||
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
|
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
|
||||||
args.insert(key.to_string(), value.to_owned().into());
|
args.insert(key.to_string(), value.to_owned().into());
|
||||||
|
|
@ -44,7 +44,7 @@ impl ComponentTrait for L10n {
|
||||||
(translate(
|
(translate(
|
||||||
self.key(),
|
self.key(),
|
||||||
Locale::Using(
|
Locale::Using(
|
||||||
rcx.language(),
|
rcx.langid(),
|
||||||
locales,
|
locales,
|
||||||
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
|
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
|
||||||
args.insert(key.to_string(), value.to_owned().into());
|
args.insert(key.to_string(), value.to_owned().into());
|
||||||
|
|
|
||||||
|
|
@ -94,47 +94,46 @@
|
||||||
use crate::html::{Markup, PreEscaped};
|
use crate::html::{Markup, PreEscaped};
|
||||||
use crate::{args, config, trace, LazyStatic};
|
use crate::{args, config, trace, LazyStatic};
|
||||||
|
|
||||||
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;
|
pub use unic_langid::{langid, CharacterDirection, LanguageIdentifier};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
static LANGUAGES: LazyStatic<HashMap<String, (LanguageIdentifier, &str)>> = LazyStatic::new(|| {
|
static LANGUAGES: LazyStatic<HashMap<String, (LanguageIdentifier, &str)>> = LazyStatic::new(|| {
|
||||||
args![
|
args![
|
||||||
"en" => (langid!("en-US"), "English"),
|
"en" => (langid!("en-US"), "English"),
|
||||||
"en-US" => (langid!("en-US"), "English (...)"),
|
"en-GB" => (langid!("en-GB"), "English (British)"),
|
||||||
|
"en-US" => (langid!("en-US"), "English (United States)"),
|
||||||
"es" => (langid!("es-ES"), "Spanish"),
|
"es" => (langid!("es-ES"), "Spanish"),
|
||||||
"es-ES" => (langid!("es-ES"), "Spanish (Spain)")
|
"es-ES" => (langid!("es-ES"), "Spanish (Spain)")
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
static DEFAULT_LANGID: LazyStatic<LanguageIdentifier> = LazyStatic::new(|| langid!("en-US"));
|
static FALLBACK_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`.
|
/// global para la aplicación a partir de `SETTINGS.app.language`.
|
||||||
pub static LANGID: LazyStatic<&LanguageIdentifier> =
|
pub(crate) static DEFAULT_LANGID: LazyStatic<&LanguageIdentifier> =
|
||||||
LazyStatic::new(
|
LazyStatic::new(|| langid_for(config::SETTINGS.app.language.as_str()));
|
||||||
|| match LANGUAGES.get(config::SETTINGS.app.language.as_str()) {
|
|
||||||
|
pub fn langid_for(language: &str) -> &LanguageIdentifier {
|
||||||
|
match LANGUAGES.get(language) {
|
||||||
Some((langid, _)) => langid,
|
Some((langid, _)) => langid,
|
||||||
_ => {
|
_ => {
|
||||||
trace::warn!(
|
trace::warn!(
|
||||||
"{}, {} \"{}\"! {}, {}",
|
"{} \"{}\"! {}",
|
||||||
"Failed to parse language",
|
"Failed to set language. Unicode Language Identifier",
|
||||||
"unrecognized Unicode Language Identifier",
|
|
||||||
config::SETTINGS.app.language,
|
config::SETTINGS.app.language,
|
||||||
"Using \"en-US\"",
|
"is not accepted. Using \"en-US\", check the settings file",
|
||||||
"check the settings file",
|
|
||||||
);
|
);
|
||||||
&*DEFAULT_LANGID
|
&*FALLBACK_LANGID
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
pub enum Locale<'a> {
|
pub enum Locale<'a> {
|
||||||
From(&'a Locales),
|
From(&'a Locales),
|
||||||
|
|
@ -157,8 +156,8 @@ pub fn e(key: &str, locale: Locale) -> Markup {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn translate(key: &str, locale: Locale) -> String {
|
pub(crate) fn translate(key: &str, locale: Locale) -> String {
|
||||||
match locale {
|
match locale {
|
||||||
Locale::From(locales) => locales.lookup(&LANGID, key),
|
Locale::From(locales) => locales.lookup(&DEFAULT_LANGID, key),
|
||||||
Locale::With(locales, args) => locales.lookup_with_args(&LANGID, key, args),
|
Locale::With(locales, args) => locales.lookup_with_args(&DEFAULT_LANGID, key, args),
|
||||||
Locale::Using(langid, locales, args) => locales.lookup_with_args(langid, key, args),
|
Locale::Using(langid, locales, args) => locales.lookup_with_args(langid, key, args),
|
||||||
}
|
}
|
||||||
.unwrap_or(key.to_string())
|
.unwrap_or(key.to_string())
|
||||||
|
|
|
||||||
|
|
@ -2,43 +2,18 @@ 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::{html, AttributeValue, Classes, ClassesOp, Favicon, Markup, DOCTYPE};
|
use crate::html::{html, Classes, ClassesOp, Favicon, Markup, DOCTYPE};
|
||||||
|
use crate::locale::{langid_for, CharacterDirection, LanguageIdentifier};
|
||||||
use crate::response::fatal_error::FatalError;
|
use crate::response::fatal_error::FatalError;
|
||||||
use crate::{config, fn_builder, locale, server, trace, LazyStatic};
|
use crate::{fn_builder, server};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
static DEFAULT_DIRECTION: LazyStatic<Option<String>> = LazyStatic::new(|| {
|
|
||||||
let direction = config::SETTINGS.app.direction.to_lowercase();
|
|
||||||
match direction.as_str() {
|
|
||||||
"auto" => Some("auto".to_owned()),
|
|
||||||
"ltr" => Some("ltr".to_owned()),
|
|
||||||
"rtl" => Some("rtl".to_owned()),
|
|
||||||
"" => None,
|
|
||||||
_ => {
|
|
||||||
trace::warn!(
|
|
||||||
"Text direction \"{}\" not valid, {}",
|
|
||||||
config::SETTINGS.app.direction,
|
|
||||||
"check the settings file"
|
|
||||||
);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
pub enum TextDirection {
|
|
||||||
Auto,
|
|
||||||
LeftToRight,
|
|
||||||
RightToLeft,
|
|
||||||
}
|
|
||||||
|
|
||||||
type PageTitle = OneComponent<L10n>;
|
type PageTitle = OneComponent<L10n>;
|
||||||
type PageDescription = OneComponent<L10n>;
|
type PageDescription = OneComponent<L10n>;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
language : AttributeValue,
|
|
||||||
direction : AttributeValue,
|
|
||||||
title : PageTitle,
|
title : PageTitle,
|
||||||
description : PageDescription,
|
description : PageDescription,
|
||||||
metadata : Vec<(&'static str, &'static str)>,
|
metadata : Vec<(&'static str, &'static str)>,
|
||||||
|
|
@ -54,11 +29,6 @@ impl Default for Page {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Page {
|
Page {
|
||||||
language : AttributeValue::new().with_value(locale::LANGID.language.as_str()),
|
|
||||||
direction : match &*DEFAULT_DIRECTION {
|
|
||||||
Some(direction) => AttributeValue::new().with_value(direction),
|
|
||||||
_ => AttributeValue::new(),
|
|
||||||
},
|
|
||||||
title : PageTitle::new(),
|
title : PageTitle::new(),
|
||||||
description : PageDescription::new(),
|
description : PageDescription::new(),
|
||||||
metadata : Vec::new(),
|
metadata : Vec::new(),
|
||||||
|
|
@ -82,18 +52,8 @@ impl Page {
|
||||||
// Page BUILDER.
|
// Page BUILDER.
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_language(&mut self, language: &str) -> &mut Self {
|
pub fn alter_language(&mut self, language: &'static str) -> &mut Self {
|
||||||
self.language.alter_value(language);
|
self.context.alter(ContextOp::LangId(langid_for(language)));
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[fn_builder]
|
|
||||||
pub fn alter_direction(&mut self, dir: TextDirection) -> &mut Self {
|
|
||||||
self.direction.alter_value(match dir {
|
|
||||||
TextDirection::Auto => "auto",
|
|
||||||
TextDirection::LeftToRight => "ltr",
|
|
||||||
TextDirection::RightToLeft => "rtl",
|
|
||||||
});
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,12 +122,8 @@ impl Page {
|
||||||
|
|
||||||
// Page GETTERS.
|
// Page GETTERS.
|
||||||
|
|
||||||
pub fn language(&self) -> &AttributeValue {
|
pub fn langid(&self) -> &LanguageIdentifier {
|
||||||
&self.language
|
&self.context.langid()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn direction(&self) -> &AttributeValue {
|
|
||||||
&self.direction
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn title(&mut self) -> String {
|
pub fn title(&mut self) -> String {
|
||||||
|
|
@ -220,9 +176,14 @@ impl Page {
|
||||||
let head = self.context.theme().render_page_head(self);
|
let head = self.context.theme().render_page_head(self);
|
||||||
|
|
||||||
// Finalmente, renderizar la página.
|
// Finalmente, renderizar la página.
|
||||||
|
let lang = self.langid().language.as_str();
|
||||||
|
let dir = match self.langid().character_direction() {
|
||||||
|
CharacterDirection::LTR => "ltr",
|
||||||
|
CharacterDirection::RTL => "rtl",
|
||||||
|
};
|
||||||
Ok(html! {
|
Ok(html! {
|
||||||
(DOCTYPE)
|
(DOCTYPE)
|
||||||
html lang=[self.language().get()] dir=[self.direction().get()] {
|
html lang=(lang) dir=(dir) {
|
||||||
(head)
|
(head)
|
||||||
(body)
|
(body)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue