👽️ Simplifica API de localización para documentar

This commit is contained in:
Manuel Cillero 2023-05-28 12:51:13 +02:00
parent 805c670a53
commit e68d0b27f0
9 changed files with 62 additions and 47 deletions

View file

@ -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]

View file

@ -58,15 +58,19 @@ impl ThemeTrait for Bootsier {
alt="Caution!"; alt="Caution!";
div class="media-body" { div class="media-body" {
h1 class="display-4" { ("RESOURCE NOT FOUND") } 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"; hr class="my-4";
p { (t("e404-description", Locale::From(&LOCALE_BOOTSIER))) } p {
(_t("e404-description", Locale::From(&LOCALE_BOOTSIER)))
}
a a
class="btn btn-primary btn-lg" class="btn btn-primary btn-lg"
href="/" href="/"
role="button" role="button"
{ {
(t("back-homepage", Locale::From(&LOCALE_BOOTSIER))) (_t("back-homepage", Locale::From(&LOCALE_BOOTSIER)))
} }
} }
} }

View file

@ -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> {
@ -146,7 +146,7 @@ fn about_pagetop() -> Container {
format!( 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)),
), ),
), ),
)), )),

View file

@ -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)))
} }
} }

View file

@ -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) {

View file

@ -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> {

View file

@ -1,4 +1,4 @@
//! Localización (¿i18n ó l10n?). //! Localización (L10n).
//! //!
//! Proporciona soporte a [Fluent](https://www.projectfluent.org/), un conjunto de especificaciones //! Proporciona soporte a [Fluent](https://www.projectfluent.org/), un conjunto de especificaciones
//! para la localización de aplicaciones, así como implementaciones y buenas prácticas originalmente //! para la localización de aplicaciones, así como implementaciones y buenas prácticas originalmente
@ -16,25 +16,29 @@
//! # Recursos Fluent //! # Recursos Fluent
//! //!
//! PageTop utiliza [fluent-templates](https://docs.rs/fluent-templates/) para integrar durante la //! PageTop utiliza [fluent-templates](https://docs.rs/fluent-templates/) para integrar durante la
//! compilación los recursos de localización en el binario de la aplicación. Básicamente agrupa //! compilación los recursos de localización en el binario de la aplicación. En el siguiente ejemplo
//! todos los archivos de los subdirectorios del directorio *src/locales* que tienen un //! agruparía todos los archivos y subdirectorios de *static/locales* que tienen un
//! [Identificador de Idioma Unicode](https://docs.rs/unic-langid/) válido y los asigna a su //! [Identificador de Idioma Unicode](https://docs.rs/unic-langid/) válido y los asignaría a su
//! identificador correspondiente: //! identificador correspondiente:
//! //!
//! ```text //! ```text
//! resources/locales //! static/locales
//! ├── common.ftl //! ├── common.ftl
//! ├── en-US //! ├── en-US
//! │ └── main.ftl //! │ ├── default.ftl
//! ├── es-ES //! │ └── main.ftl
//! │ └── main.ftl //! ├── es-ES
//! ├── es-MX //! │ ├── default.ftl
//! │ └── main.ftl //! │ └── main.ftl
//! └── fr //! ├── es-MX
//! └── main.ftl //! │ ├── default.ftl
//! │ └── main.ftl
//! └── fr
//! ├── default.ftl
//! └── main.ftl
//! ``` //! ```
//! //!
//! Ejemplo de un archivo *src/locales/en-US/main.ftl*: //! Ejemplo de un archivo *static/locales/en-US/main.ftl*:
//! //!
//! ```text //! ```text
//! hello-world = Hello world! //! hello-world = Hello world!
@ -50,7 +54,7 @@
//! }. //! }.
//! ``` //! ```
//! //!
//! Ejemplo de un archivo *src/locales/es-ES/main.ftl*: //! Ejemplo del archivo equivalente *static/locales/es-ES/main.ftl*:
//! //!
//! ```text //! ```text
//! hello-world = Hola mundo! //! hello-world = Hola mundo!
@ -69,36 +73,41 @@
//! # Cómo aplicar la localización en tu código //! # Cómo aplicar la localización en tu código
//! //!
//! Una vez hayas creado tu directorio de recursos FTL, sólo tienes que usar la poderosa macro //! Una vez hayas creado tu directorio de recursos FTL, sólo tienes que usar la poderosa macro
//! [`define_locale!`](crate::define_locale) para integrar fácilmente tus recursos de localización. //! [`define_locale!`](crate::define_locale) para integrarlos en tu módulo o aplicación.
//! //!
//! Luego sólo tendrás que usar la función `t()` para realizar tus traducciones: //! Y podrás usar las funciones globales [`_t()`] o [`_e()`] para traducir tus textos:
//! //!
//! ``` //! ```
//! use pagetop::{args, define_locale, t}; //! use pagetop::prelude::*;
//! //!
//! define_locale!(LOCALE_SAMPLE, "src/locales"); //! define_locale!(LOCALE_SAMPLE, "static/locales");
//! //!
//! fn demo() { //! fn demo() {
//! println!("* {}", l("hello-world", Locale::From(&LOCALE_SAMPLE))); //! println!("* {}", _t("hello-world", Locale::From(&LOCALE_SAMPLE)));
//! println!("* {}", t("hello-user", Locale::With(&LOCALE_SAMPLE, &args!["userName" => "Julia"]))); //! println!("* {}", _t("hello-user", Locale::With(&LOCALE_SAMPLE, &args!["userName" => "Julia"])));
//! //!
//! let args = args![ //! let args = args![
//! "userName" => "Roberto", //! "userName" => "Roberto",
//! "photoCount" => 3, //! "photoCount" => 3,
//! "userGender" => "male" //! "userGender" => "male"
//! ]; //! ];
//! println!("* {}\n", t("shared-photos", Locale::With(&LOCALE_SAMPLE, &args))); //! println!("* {}\n", _t("shared-photos", Locale::With(&LOCALE_SAMPLE, &args)));
//! } //! }
//! ``` //! ```
//! Aunque normalmente usarás el componente [L10n](crate::core::component::L10n) para añadir textos
//! traducibles en las respuestas web según el contexto del renderizado.
use crate::html::{Markup, PreEscaped}; use crate::html::{Markup, PreEscaped};
use crate::{args, config, trace, LazyStatic}; use crate::{args, config, trace, LazyStatic};
pub use fluent_templates; pub(crate) use unic_langid::{langid, LanguageIdentifier};
pub use fluent_templates::fluent_bundle::FluentValue;
pub use fluent_templates::{static_loader as static_locale, Loader, StaticLoader as Locales};
pub use unic_langid::{langid, CharacterDirection, LanguageIdentifier}; pub use fluent_templates;
pub(crate) use fluent_templates::StaticLoader as Locales;
use fluent_templates::fluent_bundle::FluentValue;
use fluent_templates::Loader;
use std::collections::HashMap; use std::collections::HashMap;
@ -130,7 +139,7 @@ pub fn langid_for(language: &str) -> &LanguageIdentifier {
config::SETTINGS.app.language, config::SETTINGS.app.language,
"is not accepted. Using \"en-US\", check the settings file", "is not accepted. Using \"en-US\", check the settings file",
); );
&*FALLBACK_LANGID &FALLBACK_LANGID
} }
} }
} }
@ -145,11 +154,11 @@ pub enum Locale<'a> {
), ),
} }
pub fn t(key: &str, locale: Locale) -> String { pub fn _t(key: &str, locale: Locale) -> String {
translate(key, locale) translate(key, locale)
} }
pub fn e(key: &str, locale: Locale) -> Markup { pub fn _e(key: &str, locale: Locale) -> Markup {
PreEscaped(translate(key, locale)) PreEscaped(translate(key, locale))
} }

View file

@ -3,10 +3,12 @@ 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, Classes, ClassesOp, Favicon, Markup, DOCTYPE}; use crate::html::{html, Classes, ClassesOp, Favicon, Markup, DOCTYPE};
use crate::locale::{langid_for, CharacterDirection, LanguageIdentifier}; use crate::locale::{langid_for, LanguageIdentifier};
use crate::response::fatal_error::FatalError; use crate::response::fatal_error::FatalError;
use crate::{fn_builder, server}; use crate::{fn_builder, server};
use unic_langid::CharacterDirection;
use std::collections::HashMap; use std::collections::HashMap;
type PageTitle = OneComponent<L10n>; type PageTitle = OneComponent<L10n>;
@ -123,7 +125,7 @@ impl Page {
// Page GETTERS. // Page GETTERS.
pub fn langid(&self) -> &LanguageIdentifier { pub fn langid(&self) -> &LanguageIdentifier {
&self.context.langid() self.context.langid()
} }
pub fn title(&mut self) -> String { pub fn title(&mut self) -> String {

View file

@ -93,7 +93,7 @@ macro_rules! define_locale {
( $LOCALES:ident, $dir_locales:literal $(, $core_locales:literal)? ) => { ( $LOCALES:ident, $dir_locales:literal $(, $core_locales:literal)? ) => {
use $crate::locale::*; use $crate::locale::*;
static_locale! { fluent_templates::static_loader! {
pub static $LOCALES = { pub static $LOCALES = {
locales: $dir_locales, locales: $dir_locales,
$( core_locales: $core_locales, )? $( core_locales: $core_locales, )?