🎨 Mejora Region para declarar las regiones
This commit is contained in:
parent
9af2ac39a1
commit
4c8610af07
2 changed files with 27 additions and 17 deletions
|
|
@ -28,14 +28,14 @@ pub type ThemeRef = &'static dyn Theme;
|
||||||
pub trait ThemePage {
|
pub trait ThemePage {
|
||||||
/// Renderiza el **contenido interior** del `<body>` de la página.
|
/// Renderiza el **contenido interior** del `<body>` de la página.
|
||||||
///
|
///
|
||||||
/// Recorre `regions` en el **orden declarado** y, para cada región con contenido, genera un
|
/// Esta implementación recorre `regions` en el **orden declarado** y, para cada región con
|
||||||
/// contenedor con `role="region"` y un `aria-label` localizado.
|
/// contenido, genera un contenedor con `role="region"` y un `aria-label` localizado.
|
||||||
/// Se asume que cada identificador de región es **único** dentro de la página.
|
/// Se asume que cada identificador de región es **único** dentro de la página.
|
||||||
///
|
///
|
||||||
/// La etiqueta `<body>` no se incluye aquí; únicamente renderiza su contenido.
|
/// La etiqueta `<body>` no se incluye aquí; únicamente renderiza su contenido.
|
||||||
fn render_body(&self, page: &mut Page, regions: &[(Region, L10n)]) -> Markup {
|
fn render_body(&self, page: &mut Page, regions: &[Region]) -> Markup {
|
||||||
html! {
|
html! {
|
||||||
@for (region, region_label) in regions {
|
@for region in regions {
|
||||||
@let output = page.context().render_components_of(region.key());
|
@let output = page.context().render_components_of(region.key());
|
||||||
@if !output.is_empty() {
|
@if !output.is_empty() {
|
||||||
@let region_name = region.name();
|
@let region_name = region.name();
|
||||||
|
|
@ -43,7 +43,7 @@ pub trait ThemePage {
|
||||||
id=(region_name)
|
id=(region_name)
|
||||||
class={ "region region--" (region_name) }
|
class={ "region region--" (region_name) }
|
||||||
role="region"
|
role="region"
|
||||||
aria-label=[region_label.lookup(page)]
|
aria-label=[region.label().lookup(page)]
|
||||||
{
|
{
|
||||||
(output)
|
(output)
|
||||||
}
|
}
|
||||||
|
|
@ -125,31 +125,31 @@ pub trait Theme: Extension + ThemePage + Send + Sync {
|
||||||
|
|
||||||
/// Declaración ordenada de las regiones disponibles en la página.
|
/// Declaración ordenada de las regiones disponibles en la página.
|
||||||
///
|
///
|
||||||
/// Devuelve una **lista estática** de pares `(Region, L10n)` que se usará para renderizar todas
|
/// Devuelve una **lista estática** de regiones ([`Region`](crate::core::theme::Region)) con la
|
||||||
/// las regiones que componen una página en el orden indicado .
|
/// información necesaria para renderizar el contenedor de cada región.
|
||||||
///
|
///
|
||||||
/// Si un tema necesita un conjunto distinto de regiones, se puede **sobrescribir** este método
|
/// Si un tema necesita un conjunto distinto de regiones, se puede **sobrescribir** este método
|
||||||
/// con los siguientes requisitos y recomendaciones:
|
/// con los siguientes requisitos y recomendaciones:
|
||||||
///
|
///
|
||||||
/// - Los identificadores deben ser **estables** (p. ej. `"sidebar-left"`, `"content"`).
|
/// - Los identificadores deben ser **estables** (p. ej. `"sidebar-left"`, `"content"`).
|
||||||
/// - La región `"content"` es **obligatoria**. Se puede usar [`Region::default()`] para
|
/// - La región `"content"` es **obligatoria** porque se usa por defecto para añadir componentes
|
||||||
/// declararla.
|
/// para renderizar. Se puede utilizar [`Region::default()`] para declararla.
|
||||||
/// - La etiqueta `L10n` se evalúa con el idioma activo de la página.
|
/// - La etiqueta `L10n` se evaluará con el idioma activo de la página.
|
||||||
///
|
///
|
||||||
/// Por defecto devuelve:
|
/// Por defecto devuelve:
|
||||||
///
|
///
|
||||||
/// - `"header"`: cabecera.
|
/// - `"header"`: cabecera.
|
||||||
/// - `"content"`: contenido principal (**obligatoria**).
|
/// - `"content"`: contenido principal (**obligatoria**).
|
||||||
/// - `"footer"`: pie.
|
/// - `"footer"`: pie.
|
||||||
fn page_regions(&self) -> &'static [(Region, L10n)] {
|
fn page_regions(&self) -> &'static [Region] {
|
||||||
static REGIONS: LazyLock<[(Region, L10n); 3]> = LazyLock::new(|| {
|
static REGIONS: LazyLock<[Region; 3]> = LazyLock::new(|| {
|
||||||
[
|
[
|
||||||
(Region::declare("header"), L10n::l("region_header")),
|
Region::declare("header", L10n::l("region_header")),
|
||||||
(Region::default(), L10n::l("region_content")),
|
Region::default(),
|
||||||
(Region::declare("footer"), L10n::l("region_footer")),
|
Region::declare("footer", L10n::l("region_footer")),
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
®IONS[..]
|
&*REGIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Acciones específicas del tema antes de renderizar el `<body>` de la página.
|
/// Acciones específicas del tema antes de renderizar el `<body>` de la página.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::core::component::{Child, ChildOp, Children};
|
use crate::core::component::{Child, ChildOp, Children};
|
||||||
use crate::core::theme::ThemeRef;
|
use crate::core::theme::ThemeRef;
|
||||||
|
use crate::locale::L10n;
|
||||||
use crate::{builder_fn, AutoDefault, UniqueId};
|
use crate::{builder_fn, AutoDefault, UniqueId};
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
@ -29,6 +30,7 @@ pub const REGION_CONTENT: &str = "content";
|
||||||
pub struct Region {
|
pub struct Region {
|
||||||
key: &'static str,
|
key: &'static str,
|
||||||
name: String,
|
name: String,
|
||||||
|
label: L10n,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Region {
|
impl Default for Region {
|
||||||
|
|
@ -37,6 +39,7 @@ impl Default for Region {
|
||||||
Self {
|
Self {
|
||||||
key: REGION_CONTENT,
|
key: REGION_CONTENT,
|
||||||
name: REGION_CONTENT.to_string(),
|
name: REGION_CONTENT.to_string(),
|
||||||
|
label: L10n::l("region_content"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -51,10 +54,11 @@ impl Region {
|
||||||
/// sencillos, limitando los caracteres a `[a-z0-9-]` (p.ej., `"sidebar"` o `"main-menu"`), cuyo
|
/// sencillos, limitando los caracteres a `[a-z0-9-]` (p.ej., `"sidebar"` o `"main-menu"`), cuyo
|
||||||
/// nombre normalizado coincidirá con la clave.
|
/// nombre normalizado coincidirá con la clave.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn declare(key: &'static str) -> Self {
|
pub fn declare(key: &'static str, label: L10n) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key,
|
key,
|
||||||
name: key.trim().to_ascii_lowercase().replace(' ', "-"),
|
name: key.trim().to_ascii_lowercase().replace(' ', "-"),
|
||||||
|
label,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,6 +73,12 @@ impl Region {
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Devuelve la etiqueta localizada asociada a la región.
|
||||||
|
#[inline]
|
||||||
|
pub fn label(&self) -> &L10n {
|
||||||
|
&self.label
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contenedor interno de componentes agrupados por región.
|
// Contenedor interno de componentes agrupados por región.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue