👽️ Simplifica API de localización para documentar
This commit is contained in:
parent
805c670a53
commit
e68d0b27f0
9 changed files with 62 additions and 47 deletions
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
|
|
|
||||||
|
|
@ -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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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, )?
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue