🍻 Última revista a las traducciones por contexto

This commit is contained in:
Manuel Cillero 2023-05-28 11:24:03 +02:00
parent 23a6f36f62
commit 805c670a53
5 changed files with 50 additions and 86 deletions

View file

@ -33,8 +33,8 @@ impl Application {
// Inicia registro de trazas y eventos.
LazyStatic::force(&trace::TRACING);
// Valida el identificador de idioma.
LazyStatic::force(&locale::LANGID);
// Valida el identificador global de idioma.
LazyStatic::force(&locale::DEFAULT_LANGID);
#[cfg(feature = "database")]
// Conecta con la base de datos.

View file

@ -1,6 +1,6 @@
use crate::core::module::{all::theme_by_single_name, ThemeStaticRef};
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::{concat_string, config, util, LazyStatic};
@ -14,6 +14,7 @@ static DEFAULT_THEME: LazyStatic<ThemeStaticRef> =
});
pub enum ContextOp {
LangId(&'static LanguageIdentifier),
Theme(&'static str),
Request(Option<HttpRequest>),
AddStyleSheet(StyleSheet),
@ -24,7 +25,7 @@ pub enum ContextOp {
#[rustfmt::skip]
pub struct RenderContext {
language : &'static LanguageIdentifier,
langid : &'static LanguageIdentifier,
theme : ThemeStaticRef,
request : Option<HttpRequest>,
stylesheets: Assets<StyleSheet>,
@ -37,7 +38,7 @@ impl Default for RenderContext {
#[rustfmt::skip]
fn default() -> Self {
RenderContext {
language : &LANGID,
langid : &DEFAULT_LANGID,
theme : *DEFAULT_THEME,
request : None,
stylesheets: Assets::<StyleSheet>::new(),
@ -55,6 +56,9 @@ impl RenderContext {
pub fn alter(&mut self, op: ContextOp) -> &mut Self {
match op {
ContextOp::LangId(langid) => {
self.langid = langid;
}
ContextOp::Theme(theme_name) => {
self.theme = theme_by_single_name(theme_name).unwrap_or(*DEFAULT_THEME);
}
@ -84,8 +88,8 @@ impl RenderContext {
/// Context GETTERS.
pub(crate) fn language(&self) -> &LanguageIdentifier {
self.language
pub(crate) fn langid(&self) -> &LanguageIdentifier {
self.langid
}
pub(crate) fn theme(&self) -> ThemeStaticRef {

View file

@ -32,7 +32,7 @@ impl ComponentTrait for L10n {
(PreEscaped(translate(
self.key(),
Locale::Using(
rcx.language(),
rcx.langid(),
locales,
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
args.insert(key.to_string(), value.to_owned().into());
@ -44,7 +44,7 @@ impl ComponentTrait for L10n {
(translate(
self.key(),
Locale::Using(
rcx.language(),
rcx.langid(),
locales,
&self.args().iter().fold(HashMap::new(), |mut args, (key, value)| {
args.insert(key.to_string(), value.to_owned().into());

View file

@ -94,47 +94,46 @@
use crate::html::{Markup, PreEscaped};
use crate::{args, config, trace, LazyStatic};
use unic_langid::langid;
pub use fluent_templates;
pub use fluent_templates::fluent_bundle::FluentValue;
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;
static LANGUAGES: LazyStatic<HashMap<String, (LanguageIdentifier, &str)>> = LazyStatic::new(|| {
args![
"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-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
/// ([Unicode Language Identifier](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier))
/// para la aplicación, obtenido de `SETTINGS.app.language`.
pub static LANGID: LazyStatic<&LanguageIdentifier> =
LazyStatic::new(
|| match LANGUAGES.get(config::SETTINGS.app.language.as_str()) {
Some((langid, _)) => langid,
_ => {
trace::warn!(
"{}, {} \"{}\"! {}, {}",
"Failed to parse language",
"unrecognized Unicode Language Identifier",
config::SETTINGS.app.language,
"Using \"en-US\"",
"check the settings file",
);
&*DEFAULT_LANGID
}
},
);
/// global para la aplicación a partir de `SETTINGS.app.language`.
pub(crate) static DEFAULT_LANGID: LazyStatic<&LanguageIdentifier> =
LazyStatic::new(|| langid_for(config::SETTINGS.app.language.as_str()));
pub fn langid_for(language: &str) -> &LanguageIdentifier {
match LANGUAGES.get(language) {
Some((langid, _)) => langid,
_ => {
trace::warn!(
"{} \"{}\"! {}",
"Failed to set language. Unicode Language Identifier",
config::SETTINGS.app.language,
"is not accepted. Using \"en-US\", check the settings file",
);
&*FALLBACK_LANGID
}
}
}
pub enum Locale<'a> {
From(&'a Locales),
@ -157,8 +156,8 @@ pub fn e(key: &str, locale: Locale) -> Markup {
#[inline]
pub(crate) fn translate(key: &str, locale: Locale) -> String {
match locale {
Locale::From(locales) => locales.lookup(&LANGID, key),
Locale::With(locales, args) => locales.lookup_with_args(&LANGID, key, args),
Locale::From(locales) => locales.lookup(&DEFAULT_LANGID, key),
Locale::With(locales, args) => locales.lookup_with_args(&DEFAULT_LANGID, key, args),
Locale::Using(langid, locales, args) => locales.lookup_with_args(langid, key, args),
}
.unwrap_or(key.to_string())

View file

@ -2,43 +2,18 @@ use super::{BeforeRenderPageHook, ResultPage, HOOK_BEFORE_RENDER_PAGE};
use crate::core::component::*;
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::{config, fn_builder, locale, server, trace, LazyStatic};
use crate::{fn_builder, server};
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 PageDescription = OneComponent<L10n>;
#[rustfmt::skip]
pub struct Page {
language : AttributeValue,
direction : AttributeValue,
title : PageTitle,
description : PageDescription,
metadata : Vec<(&'static str, &'static str)>,
@ -54,11 +29,6 @@ impl Default for Page {
#[rustfmt::skip]
fn default() -> Self {
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(),
description : PageDescription::new(),
metadata : Vec::new(),
@ -82,18 +52,8 @@ impl Page {
// Page BUILDER.
#[fn_builder]
pub fn alter_language(&mut self, language: &str) -> &mut Self {
self.language.alter_value(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",
});
pub fn alter_language(&mut self, language: &'static str) -> &mut Self {
self.context.alter(ContextOp::LangId(langid_for(language)));
self
}
@ -162,12 +122,8 @@ impl Page {
// Page GETTERS.
pub fn language(&self) -> &AttributeValue {
&self.language
}
pub fn direction(&self) -> &AttributeValue {
&self.direction
pub fn langid(&self) -> &LanguageIdentifier {
&self.context.langid()
}
pub fn title(&mut self) -> String {
@ -220,9 +176,14 @@ impl Page {
let head = self.context.theme().render_page_head(self);
// 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! {
(DOCTYPE)
html lang=[self.language().get()] dir=[self.direction().get()] {
html lang=(lang) dir=(dir) {
(head)
(body)
}