🚧 Ajustes menores en rutas y localización

- Añade `Route::try_resolve()` y `RoutePath::is_empty()` para omitir
  atributos HTML opcionales cuando la ruta resultante está vacía.
- Renombra `Locale::configured_langid()` a `try_langid()` (convención
  `try_*` para Option).
- Reordena include_locales! y otros cambios menores.
This commit is contained in:
Manuel Cillero 2026-07-26 09:55:27 +02:00
parent 8573aca29e
commit b9d9cdf601
6 changed files with 22 additions and 7 deletions

View file

@ -144,6 +144,15 @@ impl Route {
pub fn resolve(&self, cx: &Context) -> RoutePath { pub fn resolve(&self, cx: &Context) -> RoutePath {
(self.0)(cx) (self.0)(cx)
} }
/// Como [`resolve()`](Self::resolve), pero devuelve `None` cuando la ruta calculada está vacía.
///
/// Útil para atributos HTML opcionales (por ejemplo `href`) que no deben renderizarse si la
/// ruta resultante no tiene contenido.
pub fn try_resolve(&self, cx: &Context) -> Option<RoutePath> {
let route = self.resolve(cx);
(!route.is_empty()).then_some(route)
}
} }
impl fmt::Debug for Route { impl fmt::Debug for Route {

View file

@ -19,7 +19,7 @@ enum Source {
Inline(CowStr, Box<dyn Fn(&mut Context) -> String + Send + Sync>), Inline(CowStr, Box<dyn Fn(&mut Context) -> String + Send + Sync>),
} }
/// Define el medio objetivo para la hoja de estilos. /// Define el medio objetivo para una hoja de estilos.
/// ///
/// Permite especificar en qué contexto se aplica el CSS, adaptándose a diferentes dispositivos o /// Permite especificar en qué contexto se aplica el CSS, adaptándose a diferentes dispositivos o
/// situaciones de impresión. /// situaciones de impresión.

View file

@ -97,6 +97,12 @@ impl RoutePath {
crate::util::url_looks_external(&self.path) crate::util::url_looks_external(&self.path)
} }
/// Indica si la ruta no tiene *path* ni parámetros, es decir, si su representación textual
/// sería una cadena vacía.
pub fn is_empty(&self) -> bool {
self.path.is_empty() && self.query.is_empty()
}
// **< RoutePath HELPERS >********************************************************************** // **< RoutePath HELPERS >**********************************************************************
// Codifica un valor para su uso seguro como parte de una *query string* según RFC 3986: los // Codifica un valor para su uso seguro como parte de una *query string* según RFC 3986: los

View file

@ -170,7 +170,7 @@ impl Locale {
/// Devuelve el identificador de idioma configurado explícitamente, si es válido. /// Devuelve el identificador de idioma configurado explícitamente, si es válido.
/// ///
/// Si no se ha configurado un idioma por defecto o el valor no es válido, devuelve `None`. /// Si no se ha configurado un idioma por defecto o el valor no es válido, devuelve `None`.
pub fn configured_langid() -> Option<&'static LanguageIdentifier> { pub fn try_langid() -> Option<&'static LanguageIdentifier> {
*CONFIG_LANGID *CONFIG_LANGID
} }

View file

@ -3,6 +3,8 @@ use crate::{AutoDefault, CowStr, include_locales};
use super::{LangId, Locale}; use super::{LangId, Locale};
include_locales!(LOCALES_PAGETOP);
use fluent_templates::Loader; use fluent_templates::Loader;
use fluent_templates::StaticLoader as Locales; use fluent_templates::StaticLoader as Locales;
@ -10,8 +12,6 @@ use std::collections::HashMap;
use std::fmt; use std::fmt;
include_locales!(LOCALES_PAGETOP);
/// Operación de localización a realizar. /// Operación de localización a realizar.
/// ///
/// * `None` - No se aplica ninguna localización. /// * `None` - No se aplica ninguna localización.

View file

@ -29,13 +29,13 @@ impl RequestLocale {
/// - [`LangNegotiation::Full`](crate::global::LangNegotiation::Full) determina el idioma en /// - [`LangNegotiation::Full`](crate::global::LangNegotiation::Full) determina el idioma en
/// este orden: /// este orden:
/// 1. Parámetro de *query* `?lang=...`, si existe y corresponde a un idioma soportado. /// 1. Parámetro de *query* `?lang=...`, si existe y corresponde a un idioma soportado.
/// 2. [`Locale::configured_langid()`], si la aplicación tiene un idioma por defecto válido. /// 2. [`Locale::try_langid()`], si la aplicación tiene un idioma por defecto válido.
/// 3. Cabecera `Accept-Language`, si puede resolverse con [`Locale::resolve()`]. /// 3. Cabecera `Accept-Language`, si puede resolverse con [`Locale::resolve()`].
/// 4. Idioma de respaldo. /// 4. Idioma de respaldo.
/// ///
/// - [`LangNegotiation::NoQuery`](crate::global::LangNegotiation::NoQuery) descarta el uso del /// - [`LangNegotiation::NoQuery`](crate::global::LangNegotiation::NoQuery) descarta el uso del
/// parámetro `?lang=...` y determina el idioma en este orden: /// parámetro `?lang=...` y determina el idioma en este orden:
/// 1. [`Locale::configured_langid()`], si la aplicación tiene un idioma por defecto válido. /// 1. [`Locale::try_langid()`], si la aplicación tiene un idioma por defecto válido.
/// 2. Cabecera `Accept-Language`, si puede resolverse con [`Locale::resolve()`]. /// 2. Cabecera `Accept-Language`, si puede resolverse con [`Locale::resolve()`].
/// 3. Idioma de respaldo. /// 3. Idioma de respaldo.
/// ///
@ -56,7 +56,7 @@ impl RequestLocale {
Locale::default_langid() Locale::default_langid()
} }
global::LangNegotiation::Full | global::LangNegotiation::NoQuery => { global::LangNegotiation::Full | global::LangNegotiation::NoQuery => {
if let Some(default) = Locale::configured_langid() { if let Some(default) = Locale::try_langid() {
default default
} else { } else {
// Sin idioma por defecto, se evalúa la cabecera `Accept-Language`. // Sin idioma por defecto, se evalúa la cabecera `Accept-Language`.