Añade `Theme::parent()` para declarar jerarquías de herencia entre temas. Sustituye la acción `PrepareRender<C>` por el método `Theme::prepare_component()` y la macro `render_component!`.
170 lines
5.8 KiB
Rust
170 lines
5.8 KiB
Rust
//! Localización (L10n).
|
|
//!
|
|
//! PageTop utiliza las especificaciones de [Fluent](https://www.projectfluent.org/) para la
|
|
//! localización de aplicaciones, y aprovecha [fluent-templates](https://docs.rs/fluent-templates/)
|
|
//! para integrar los recursos de traducción directamente en el binario de la aplicación.
|
|
//!
|
|
//! # Sintaxis Fluent (FTL)
|
|
//!
|
|
//! El formato empleado para describir los recursos de traducción se denomina
|
|
//! [FTL](https://www.projectfluent.org/fluent/guide/). Está diseñado para ser legible y expresivo,
|
|
//! permitiendo representar construcciones complejas del lenguaje natural como el género, el plural
|
|
//! o las conjugaciones verbales.
|
|
//!
|
|
//! # Recursos Fluent
|
|
//!
|
|
//! Por defecto, las traducciones están en el directorio `src/locale`, con subdirectorios para cada
|
|
//! [Identificador de Idioma Unicode](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)
|
|
//! válido. Podríamos tener una estructura como esta:
|
|
//!
|
|
//! ```text
|
|
//! src/locale/
|
|
//! ├── common.ftl
|
|
//! ├── en-US/
|
|
//! │ ├── default.ftl
|
|
//! │ └── main.ftl
|
|
//! ├── es-ES/
|
|
//! │ ├── default.ftl
|
|
//! │ └── main.ftl
|
|
//! ├── es-MX/
|
|
//! │ ├── default.ftl
|
|
//! │ └── main.ftl
|
|
//! └── fr-FR/
|
|
//! ├── default.ftl
|
|
//! └── main.ftl
|
|
//! ```
|
|
//!
|
|
//! Ejemplo de un archivo en `src/locale/en-US/main.ftl`:
|
|
//!
|
|
//! ```text
|
|
//! hello-world = Hello world!
|
|
//! hello-user = Hello, {$userName}!
|
|
//! shared-photos =
|
|
//! {$userName} {$photoCount ->
|
|
//! [one] added a new photo
|
|
//! *[other] added {$photoCount} new photos
|
|
//! } of {$userGender ->
|
|
//! [male] him and his family
|
|
//! [female] her and her family
|
|
//! *[other] the family
|
|
//! }.
|
|
//! ```
|
|
//!
|
|
//! Y su archivo equivalente para español en `src/locale/es-ES/main.ftl`:
|
|
//!
|
|
//! ```text
|
|
//! hello-world = ¡Hola, mundo!
|
|
//! hello-user = ¡Hola, {$userName}!
|
|
//! shared-photos =
|
|
//! {$userName} {$photoCount ->
|
|
//! [one] ha añadido una nueva foto
|
|
//! *[other] ha añadido {$photoCount} nuevas fotos
|
|
//! } de {$userGender ->
|
|
//! [male] él y su familia
|
|
//! [female] ella y su familia
|
|
//! *[other] la familia
|
|
//! }.
|
|
//! ```
|
|
//!
|
|
//!
|
|
//! # Cómo aplicar la localización en tu código
|
|
//!
|
|
//! Una vez creado el directorio con los recursos FTL, basta con usar la macro
|
|
//! [`include_locales!`](crate::include_locales) para integrarlos en la aplicación.
|
|
//!
|
|
//! Si los recursos se encuentran en el directorio por defecto `src/locale` del *crate*, sólo hay
|
|
//! que declarar:
|
|
//!
|
|
//! ```rust
|
|
//! # use pagetop::prelude::*;
|
|
//! include_locales!(LOCALES_SAMPLE);
|
|
//! ```
|
|
//!
|
|
//! Si están ubicados en otro directorio, se puede usar la forma:
|
|
//!
|
|
//! ```rust,ignore
|
|
//! include_locales!(LOCALES_SAMPLE from "ruta/a/las/traducciones");
|
|
//! ```
|
|
//!
|
|
//! Y *voilà*, sólo queda operar con los idiomas soportados por PageTop usando [`Locale`] y traducir
|
|
//! textos con [`L10n`].
|
|
|
|
pub use fluent_templates;
|
|
pub use unic_langid::{CharacterDirection, LanguageIdentifier};
|
|
|
|
use unic_langid::langid;
|
|
|
|
mod languages;
|
|
|
|
mod definition;
|
|
pub use definition::{LangId, Locale};
|
|
|
|
mod request;
|
|
pub use request::RequestLocale;
|
|
|
|
mod l10n;
|
|
pub use l10n::L10n;
|
|
|
|
// **< include_locales! >***************************************************************************
|
|
|
|
/// Incluye un conjunto de recursos **Fluent** con textos de traducción propios.
|
|
///
|
|
/// Esta macro integra en el binario de la aplicación los archivos FTL ubicados en los siguientes
|
|
/// directorios opcionales de recursos Fluent:
|
|
///
|
|
/// - `$dir_locales`, con los subdirectorios de cada idioma. Por ejemplo, `"files/ftl"` o
|
|
/// `"assets/translations"`. Si no se indica, se usará el directorio por defecto `"src/locale"`.
|
|
/// - `$core_locales`, que añade un conjunto de traducciones que se cargan para **todos** los
|
|
/// idiomas. Sirve para definir textos comunes que no tienen por qué duplicarse en cada
|
|
/// subdirectorio de idioma.
|
|
///
|
|
/// Cada extensión o tema puede definir sus propios recursos de traducción usando esta macro. Para
|
|
/// más detalles sobre el sistema de localización consulta el módulo [`locale`](crate::locale).
|
|
///
|
|
/// # Ejemplos
|
|
///
|
|
/// Uso básico con el directorio por defecto `"src/locale"`:
|
|
///
|
|
/// ```rust
|
|
/// # use pagetop::prelude::*;
|
|
/// include_locales!(LOCALES_SAMPLE);
|
|
/// ```
|
|
///
|
|
/// Uso indicando recursos comunes (además de `"src/locale"`):
|
|
///
|
|
/// ```rust,ignore
|
|
/// include_locales!(LOCALES_SAMPLE, "src/core-locale");
|
|
/// ```
|
|
///
|
|
/// Uso con un directorio de recursos Fluent alternativo:
|
|
///
|
|
/// ```rust,ignore
|
|
/// include_locales!(LOCALES_SAMPLE from "ruta/a/las/traducciones");
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! include_locales {
|
|
// Se desactiva la inserción de marcas de aislamiento Unicode (FSI/PDI) en los argumentos para
|
|
// mejorar la legibilidad y la compatibilidad en ciertos contextos de renderizado.
|
|
( $LOCALES:ident $(, $core_locales:literal)? ) => {
|
|
$crate::locale::fluent_templates::static_loader! {
|
|
static $LOCALES = {
|
|
locales: "src/locale",
|
|
$( core_locales: $core_locales, )?
|
|
fallback_language: "en-US",
|
|
// Elimina marcas de aislamiento Unicode en los argumentos.
|
|
customise: |bundle| bundle.set_use_isolating(false),
|
|
};
|
|
}
|
|
};
|
|
( $LOCALES:ident from $dir_locales:literal $(, $core_locales:literal)? ) => {
|
|
$crate::locale::fluent_templates::static_loader! {
|
|
static $LOCALES = {
|
|
locales: $dir_locales,
|
|
$( core_locales: $core_locales, )?
|
|
fallback_language: "en-US",
|
|
// Elimina marcas de aislamiento Unicode en los argumentos.
|
|
customise: |bundle| bundle.set_use_isolating(false),
|
|
};
|
|
}
|
|
};
|
|
}
|