diff --git a/src/global.rs b/src/global.rs index c81eec9..ccc6d9d 100644 --- a/src/global.rs +++ b/src/global.rs @@ -48,13 +48,13 @@ pub struct App { pub description: String, /// Tema predeterminado. pub theme: String, - /// Idioma por defecto de la aplicación. + /// Idioma por defecto para la aplicación. /// - /// Si este valor no es válido, el idioma efectivo para el renderizado se resolverá mediante la - /// implementación de [`LangId`](crate::locale::LangId) en este orden: primero, el establecido - /// explícitamente con [`Contextual::with_langid()`](crate::html::Contextual::with_langid); si - /// no se ha definido, se usará el indicado en la cabecera `Accept-Language` del navegador; y, - /// si ninguno aplica, se empleará el idioma de respaldo ("en-US"). + /// Si no está definido o no es válido, el idioma efectivo para el renderizado se resolverá + /// según la implementación de [`LangId`](crate::locale::LangId) en este orden: primero intenta + /// con el establecido en [`Contextual::with_langid()`](crate::html::Contextual::with_langid); + /// pero si no se ha definido explícitamente, usará el indicado en la cabecera `Accept-Language` + /// del navegador; y, si ninguno aplica, se empleará el idioma de respaldo ("en-US"). pub language: String, /// Banner ASCII mostrado al inicio: *"Off"* (desactivado), *"Slant"*, *"Small"*, *"Speed"* o /// *"Starwars"*. diff --git a/src/html/assets.rs b/src/html/assets.rs index e53e8e3..ee5431f 100644 --- a/src/html/assets.rs +++ b/src/html/assets.rs @@ -5,22 +5,49 @@ pub mod stylesheet; use crate::html::{html, Markup, Render}; use crate::{AutoDefault, Weight}; +/// Representación genérica de un *script* [`JavaScript`](crate::html::JavaScript) o una hoja de +/// estilos [`StyleSheet`](crate::html::StyleSheet). +/// +/// Estos recursos se incluyen en los conjuntos de recursos ([`Assets`]) que suelen renderizarse en +/// un documento HTML. +/// +/// Cada recurso se identifica por un **nombre único** ([`Asset::name()`]), usado como clave; y un +/// **peso** ([`Asset::weight()`]), que determina su orden relativo de renderizado. pub trait Asset: Render { /// Devuelve el nombre del recurso, utilizado como clave única. fn name(&self) -> &str; - /// Devuelve el peso del recurso, durante el renderizado se procesan de menor a mayor peso. + /// Devuelve el peso del recurso, usado para ordenar el renderizado de menor a mayor peso. fn weight(&self) -> Weight; } +/// Gestión común para conjuntos de recursos como [`JavaScript`](crate::html::JavaScript) y +/// [`StyleSheet`](crate::html::StyleSheet). +/// +/// Se emplea normalmente para agrupar, administrar y renderizar los recursos de un documento HTML. +/// Cada recurso se identifica por un nombre único ([`Asset::name()`]) y tiene asociado un peso +/// ([`Asset::weight()`]) que determina su orden de renderizado. +/// +/// Durante el renderizado, los recursos se procesan en orden ascendente de peso. En caso de +/// igualdad, se respeta el orden de inserción. #[derive(AutoDefault)] pub struct Assets(Vec); impl Assets { + /// Crea un nuevo conjunto vacío de recursos. + /// + /// Normalmente no se instancia directamente, sino como parte de la gestión de recursos que + /// hacen páginas o temas. pub fn new() -> Self { Self(Vec::new()) } + /// Inserta un recurso. + /// + /// Si no existe otro con el mismo nombre, lo añade. Si ya existe y su peso era mayor, lo + /// reemplaza. Y si su peso era menor o igual, entonces no realiza ningún cambio. + /// + /// Devuelve `true` si el recurso fue insertado o reemplazado. pub fn add(&mut self, asset: T) -> bool { match self.0.iter().position(|x| x.name() == asset.name()) { Some(index) => { @@ -39,6 +66,9 @@ impl Assets { } } + /// Elimina un recurso por nombre. + /// + /// Devuelve `true` si el recurso existía y fue eliminado. pub fn remove(&mut self, name: impl AsRef) -> bool { if let Some(index) = self.0.iter().position(|x| x.name() == name.as_ref()) { self.0.remove(index); diff --git a/src/html/assets/javascript.rs b/src/html/assets/javascript.rs index 89b5261..be6f906 100644 --- a/src/html/assets/javascript.rs +++ b/src/html/assets/javascript.rs @@ -138,7 +138,9 @@ impl JavaScript { } impl Asset for JavaScript { - // Para *scripts* externos es la ruta; para *scripts* embebidos, un identificador. + /// Devuelve el nombre del recurso, utilizado como clave única. + /// + /// Para *scripts* externos es la ruta del recurso; para *scripts* embebidos, un identificador. fn name(&self) -> &str { match &self.source { Source::From(path) => path, diff --git a/src/html/assets/stylesheet.rs b/src/html/assets/stylesheet.rs index a553726..38a97d7 100644 --- a/src/html/assets/stylesheet.rs +++ b/src/html/assets/stylesheet.rs @@ -143,7 +143,9 @@ impl StyleSheet { } impl Asset for StyleSheet { - // Para hojas de estilos externas es la ruta; para las embebidas, un identificador. + /// Devuelve el nombre del recurso, utilizado como clave única. + /// + /// Para hojas de estilos externas es la ruta del recurso; para las embebidas, un identificador. fn name(&self) -> &str { match &self.source { Source::From(path) => path, diff --git a/src/html/context.rs b/src/html/context.rs index 7af884c..79148b0 100644 --- a/src/html/context.rs +++ b/src/html/context.rs @@ -47,22 +47,52 @@ pub enum ErrorParam { }, } +/// Interfaz para gestionar el **contexto de renderizado** de un documento HTML. +/// +/// `Contextual` extiende [`LangId`] y define los métodos para: +/// +/// - Establecer el **idioma** del documento. +/// - Almacenar la **solicitud HTTP** de origen. +/// - Seleccionar **tema** y **composición** (*layout*) de renderizado. +/// - Administrar **recursos** del documento como el icono [`Favicon`], las hojas de estilo +/// [`StyleSheet`] o los *scripts* [`JavaScript`] mediante [`AssetsOp`]. +/// - Leer y mantener **parámetros dinámicos tipados** de contexto. +/// - Generar **identificadores únicos** por tipo de componente. +/// +/// Lo implementan, típicamente, estructuras que representan el contexto de renderizado, como +/// [`Context`](crate::html::Context) o [`Page`](crate::response::page::Page). +/// +/// # Ejemplo +/// +/// ```rust +/// use pagetop::prelude::*; +/// +/// fn prepare_context(cx: C) -> C { +/// cx.with_langid(&LangMatch::resolve("es-ES")) +/// .with_theme("aliner") +/// .with_layout("default") +/// .with_assets(AssetsOp::SetFavicon(Some(Favicon::new().with_icon("/favicon.ico")))) +/// .with_assets(AssetsOp::AddStyleSheet(StyleSheet::from("/css/app.css"))) +/// .with_assets(AssetsOp::AddJavaScript(JavaScript::defer("/js/app.js"))) +/// .with_param("usuario_id", 42_i32) +/// } +/// ``` pub trait Contextual: LangId { // Contextual BUILDER ************************************************************************** - /// Asigna la fuente de idioma del documento. + /// Establece el idioma del documento. #[builder_fn] fn with_langid(self, language: &impl LangId) -> Self; - /// Asigna la solicitud HTTP al contexto. + /// Almacena la solicitud HTTP de origen en el contexto. #[builder_fn] fn with_request(self, request: Option) -> Self; - /// Asigna el tema para renderizar el documento. + /// Especifica el tema para renderizar el documento. #[builder_fn] fn with_theme(self, theme_name: &'static str) -> Self; - /// Asigna la composición para renderizar el documento. + /// Especifica la composición para renderizar el documento. #[builder_fn] fn with_layout(self, layout_name: &'static str) -> Self; @@ -85,7 +115,7 @@ pub trait Contextual: LangId { /// Devuelve la composición para renderizar el documento. Por defecto es `"default"`. fn layout(&self) -> &str; - /// Recupera un parámetro como [`Option`], simplificando el acceso. + /// Recupera un parámetro como [`Option`]. fn param(&self, key: &'static str) -> Option<&T>; /// Devuelve el Favicon de los recursos del contexto. @@ -94,22 +124,24 @@ pub trait Contextual: LangId { /// Devuelve las hojas de estilo de los recursos del contexto. fn stylesheets(&self) -> &Assets; - /// Devuelve los scripts JavaScript de los recursos del contexto. + /// Devuelve los *scripts* JavaScript de los recursos del contexto. fn javascripts(&self) -> &Assets; // Contextual HELPERS ************************************************************************** - /// Devuelve un identificador único dentro del contexto para el tipo `T`, si no se proporciona - /// un `id` explícito. + /// Genera un identificador único por tipo (`-`) cuando no se aporta uno explícito. + /// + /// Es útil para componentes u otros elementos HTML que necesitan un identificador predecible si + /// no se proporciona ninguno. fn required_id(&mut self, id: Option) -> String; } -/// Implementa el contexto de un documento HTML. +/// Implementa un **contexto de renderizado** para un documento HTML. /// -/// Se crea internamente para manejar información relevante del documento, como la solicitud HTTP de -/// origen, el idioma, tema y composición para el renderizado, los recursos *favicon* ([`Favicon`]), -/// hojas de estilo ([`StyleSheet`]) y *scripts* ([`JavaScript`]), así como *parámetros dinámicos -/// heterogéneos* de contexto definidos en tiempo de ejecución. +/// Extiende [`Contextual`] con métodos para **instanciar** y configurar un nuevo contexto, +/// **renderizar los recursos** del documento (incluyendo el [`Favicon`], las hojas de estilo +/// [`StyleSheet`] y los *scripts* [`JavaScript`]), o extender el uso de **parámetros dinámicos +/// tipados** con nuevos métodos. /// /// # Ejemplos ///