♻️ Refactoriza manejo de idiomas para localización
This commit is contained in:
parent
126b31a7ed
commit
ac0889cb8c
7 changed files with 218 additions and 135 deletions
|
@ -3,7 +3,7 @@ use crate::core::theme::ThemeRef;
|
|||
use crate::core::TypeInfo;
|
||||
use crate::html::{html, Markup};
|
||||
use crate::html::{Assets, Favicon, JavaScript, StyleSheet};
|
||||
use crate::locale::{LanguageIdentifier, DEFAULT_LANGID};
|
||||
use crate::locale::{LangId, LangMatch, LanguageIdentifier, DEFAULT_LANGID, FALLBACK_LANGID};
|
||||
use crate::service::HttpRequest;
|
||||
use crate::{builder_fn, join};
|
||||
|
||||
|
@ -69,9 +69,9 @@ impl Error for ErrorParam {}
|
|||
/// use pagetop::prelude::*;
|
||||
///
|
||||
/// fn new_context(request: HttpRequest) -> Context {
|
||||
/// Context::new(request)
|
||||
/// Context::new(Some(request))
|
||||
/// // Establece el idioma del documento a español.
|
||||
/// .with_langid(LangMatch::langid_or_default("es-ES"))
|
||||
/// .with_langid(&LangMatch::resolve("es-ES"))
|
||||
/// // Selecciona un tema (por su nombre corto).
|
||||
/// .with_theme("aliner")
|
||||
/// // Asigna un favicon.
|
||||
|
@ -125,9 +125,23 @@ impl Context {
|
|||
/// cargados.
|
||||
#[rustfmt::skip]
|
||||
pub fn new(request: Option<HttpRequest>) -> Self {
|
||||
// Se intenta DEFAULT_LANGID.
|
||||
let langid = DEFAULT_LANGID
|
||||
// Si es None evalúa la cadena de extracción desde la cabecera HTTP.
|
||||
.or_else(|| {
|
||||
request
|
||||
// Se usa `as_ref()` sobre `Option<HttpRequest>` para no mover el valor.
|
||||
.as_ref()
|
||||
.and_then(|req| req.headers().get("Accept-Language"))
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.and_then(|language| LangMatch::resolve(language).as_option())
|
||||
})
|
||||
// Si todo falla, se recurre a &FALLBACK_LANGID.
|
||||
.unwrap_or(&FALLBACK_LANGID);
|
||||
|
||||
Context {
|
||||
request,
|
||||
langid : &DEFAULT_LANGID,
|
||||
langid,
|
||||
theme : *DEFAULT_THEME,
|
||||
layout : "default",
|
||||
favicon : None,
|
||||
|
@ -140,10 +154,10 @@ impl Context {
|
|||
|
||||
// Context BUILDER *****************************************************************************
|
||||
|
||||
/// Modifica el identificador de idioma del documento.
|
||||
/// Modifica la fuente de idioma del documento.
|
||||
#[builder_fn]
|
||||
pub fn with_langid(mut self, langid: &'static LanguageIdentifier) -> Self {
|
||||
self.langid = langid;
|
||||
pub fn with_langid(mut self, language: &impl LangId) -> Self {
|
||||
self.langid = language.langid();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -202,11 +216,6 @@ impl Context {
|
|||
self.request.as_ref()
|
||||
}
|
||||
|
||||
/// Devuelve el identificador de idioma asociado al documento.
|
||||
pub fn langid(&self) -> &LanguageIdentifier {
|
||||
self.langid
|
||||
}
|
||||
|
||||
/// Devuelve el tema que se usará para renderizar el documento.
|
||||
pub fn theme(&self) -> ThemeRef {
|
||||
self.theme
|
||||
|
@ -281,3 +290,21 @@ impl Context {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Permite a [`Context`](crate::html::Context) actuar como proveedor de idioma.
|
||||
///
|
||||
/// Devuelve un [`LanguageIdentifier`] siguiendo este orden de prioridad:
|
||||
///
|
||||
/// 1. Un idioma válido establecido explícitamente con [`Context::with_langid`].
|
||||
/// 2. El idioma por defecto configurado para la aplicación.
|
||||
/// 3. Un idioma válido extraído de la cabecera `Accept-Language` del navegador.
|
||||
/// 4. Y si ninguna de las opciones anteriores aplica, se usa el idioma de respaldo (`"en-US"`).
|
||||
///
|
||||
/// Resulta útil para usar un contexto ([`Context`]) como fuente de traducción en
|
||||
/// [`L10n::using`](crate::locale::L10n::using) o
|
||||
/// [`L10n::to_markup`](crate::locale::L10n::to_markup).
|
||||
impl LangId for Context {
|
||||
fn langid(&self) -> &'static LanguageIdentifier {
|
||||
self.langid
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::html::Markup;
|
||||
use crate::locale::{L10n, LanguageIdentifier};
|
||||
use crate::locale::{L10n, LangId};
|
||||
use crate::{builder_fn, AutoDefault};
|
||||
|
||||
/// Cadena para traducir al renderizar ([`locale`](crate::locale)).
|
||||
|
@ -16,18 +16,18 @@ use crate::{builder_fn, AutoDefault};
|
|||
///
|
||||
/// // Español disponible.
|
||||
/// assert_eq!(
|
||||
/// hello.using(LangMatch::langid_or_default("es-ES")),
|
||||
/// hello.using(&LangMatch::resolve("es-ES")),
|
||||
/// Some(String::from("¡Hola mundo!"))
|
||||
/// );
|
||||
///
|
||||
/// // Japonés no disponible, traduce al idioma de respaldo ("en-US").
|
||||
/// assert_eq!(
|
||||
/// hello.using(LangMatch::langid_or_fallback("ja-JP")),
|
||||
/// hello.using(&LangMatch::resolve("ja-JP")),
|
||||
/// Some(String::from("Hello world!"))
|
||||
/// );
|
||||
///
|
||||
/// // Para incrustar en HTML escapado:
|
||||
/// let markup = hello.escaped(LangMatch::langid_or_default("es-ES"));
|
||||
/// let markup = hello.to_markup(&LangMatch::resolve("es-ES"));
|
||||
/// assert_eq!(markup.into_string(), "¡Hola mundo!");
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug)]
|
||||
|
@ -50,16 +50,16 @@ impl OptionTranslated {
|
|||
|
||||
// OptionTranslated GETTERS ********************************************************************
|
||||
|
||||
/// Devuelve la traducción para `langid`, si existe.
|
||||
pub fn using(&self, langid: &LanguageIdentifier) -> Option<String> {
|
||||
self.0.using(langid)
|
||||
/// Devuelve la traducción para `language`, si existe.
|
||||
pub fn using(&self, language: &impl LangId) -> Option<String> {
|
||||
self.0.using(language)
|
||||
}
|
||||
|
||||
/// Devuelve la traducción *escapada* como [`Markup`] para `langid`, si existe.
|
||||
/// Devuelve la traducción *escapada* como [`Markup`] para `language`, si existe.
|
||||
///
|
||||
/// Útil para incrustar el texto directamente en plantillas HTML sin riesgo de inyección de
|
||||
/// contenido.
|
||||
pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup {
|
||||
self.0.escaped(langid)
|
||||
pub fn to_markup(&self, language: &impl LangId) -> Markup {
|
||||
self.0.to_markup(language)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue