🎨 Mejora la página de bienvenida y el tema básico #6
5 changed files with 88 additions and 22 deletions
|
@ -48,13 +48,13 @@ pub struct App {
|
||||||
pub description: String,
|
pub description: String,
|
||||||
/// Tema predeterminado.
|
/// Tema predeterminado.
|
||||||
pub theme: String,
|
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
|
/// Si no está definido o no es válido, el idioma efectivo para el renderizado se resolverá
|
||||||
/// implementación de [`LangId`](crate::locale::LangId) en este orden: primero, el establecido
|
/// según la implementación de [`LangId`](crate::locale::LangId) en este orden: primero intenta
|
||||||
/// explícitamente con [`Contextual::with_langid()`](crate::html::Contextual::with_langid); si
|
/// con el establecido en [`Contextual::with_langid()`](crate::html::Contextual::with_langid);
|
||||||
/// no se ha definido, se usará el indicado en la cabecera `Accept-Language` del navegador; y,
|
/// pero si no se ha definido explícitamente, usará el indicado en la cabecera `Accept-Language`
|
||||||
/// si ninguno aplica, se empleará el idioma de respaldo ("en-US").
|
/// del navegador; y, si ninguno aplica, se empleará el idioma de respaldo ("en-US").
|
||||||
pub language: String,
|
pub language: String,
|
||||||
/// Banner ASCII mostrado al inicio: *"Off"* (desactivado), *"Slant"*, *"Small"*, *"Speed"* o
|
/// Banner ASCII mostrado al inicio: *"Off"* (desactivado), *"Slant"*, *"Small"*, *"Speed"* o
|
||||||
/// *"Starwars"*.
|
/// *"Starwars"*.
|
||||||
|
|
|
@ -5,22 +5,49 @@ pub mod stylesheet;
|
||||||
use crate::html::{html, Markup, Render};
|
use crate::html::{html, Markup, Render};
|
||||||
use crate::{AutoDefault, Weight};
|
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 {
|
pub trait Asset: Render {
|
||||||
/// Devuelve el nombre del recurso, utilizado como clave única.
|
/// Devuelve el nombre del recurso, utilizado como clave única.
|
||||||
fn name(&self) -> &str;
|
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;
|
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)]
|
#[derive(AutoDefault)]
|
||||||
pub struct Assets<T>(Vec<T>);
|
pub struct Assets<T>(Vec<T>);
|
||||||
|
|
||||||
impl<T: Asset> Assets<T> {
|
impl<T: Asset> Assets<T> {
|
||||||
|
/// 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 {
|
pub fn new() -> Self {
|
||||||
Self(Vec::new())
|
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 {
|
pub fn add(&mut self, asset: T) -> bool {
|
||||||
match self.0.iter().position(|x| x.name() == asset.name()) {
|
match self.0.iter().position(|x| x.name() == asset.name()) {
|
||||||
Some(index) => {
|
Some(index) => {
|
||||||
|
@ -39,6 +66,9 @@ impl<T: Asset> Assets<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Elimina un recurso por nombre.
|
||||||
|
///
|
||||||
|
/// Devuelve `true` si el recurso existía y fue eliminado.
|
||||||
pub fn remove(&mut self, name: impl AsRef<str>) -> bool {
|
pub fn remove(&mut self, name: impl AsRef<str>) -> bool {
|
||||||
if let Some(index) = self.0.iter().position(|x| x.name() == name.as_ref()) {
|
if let Some(index) = self.0.iter().position(|x| x.name() == name.as_ref()) {
|
||||||
self.0.remove(index);
|
self.0.remove(index);
|
||||||
|
|
|
@ -138,7 +138,9 @@ impl JavaScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Asset for 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 {
|
fn name(&self) -> &str {
|
||||||
match &self.source {
|
match &self.source {
|
||||||
Source::From(path) => path,
|
Source::From(path) => path,
|
||||||
|
|
|
@ -143,7 +143,9 @@ impl StyleSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Asset for 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 {
|
fn name(&self) -> &str {
|
||||||
match &self.source {
|
match &self.source {
|
||||||
Source::From(path) => path,
|
Source::From(path) => path,
|
||||||
|
|
|
@ -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<C: Contextual>(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 {
|
pub trait Contextual: LangId {
|
||||||
// Contextual BUILDER **************************************************************************
|
// Contextual BUILDER **************************************************************************
|
||||||
|
|
||||||
/// Asigna la fuente de idioma del documento.
|
/// Establece el idioma del documento.
|
||||||
#[builder_fn]
|
#[builder_fn]
|
||||||
fn with_langid(self, language: &impl LangId) -> Self;
|
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]
|
#[builder_fn]
|
||||||
fn with_request(self, request: Option<HttpRequest>) -> Self;
|
fn with_request(self, request: Option<HttpRequest>) -> Self;
|
||||||
|
|
||||||
/// Asigna el tema para renderizar el documento.
|
/// Especifica el tema para renderizar el documento.
|
||||||
#[builder_fn]
|
#[builder_fn]
|
||||||
fn with_theme(self, theme_name: &'static str) -> Self;
|
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]
|
#[builder_fn]
|
||||||
fn with_layout(self, layout_name: &'static str) -> Self;
|
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"`.
|
/// Devuelve la composición para renderizar el documento. Por defecto es `"default"`.
|
||||||
fn layout(&self) -> &str;
|
fn layout(&self) -> &str;
|
||||||
|
|
||||||
/// Recupera un parámetro como [`Option`], simplificando el acceso.
|
/// Recupera un parámetro como [`Option`].
|
||||||
fn param<T: 'static>(&self, key: &'static str) -> Option<&T>;
|
fn param<T: 'static>(&self, key: &'static str) -> Option<&T>;
|
||||||
|
|
||||||
/// Devuelve el Favicon de los recursos del contexto.
|
/// 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.
|
/// Devuelve las hojas de estilo de los recursos del contexto.
|
||||||
fn stylesheets(&self) -> &Assets<StyleSheet>;
|
fn stylesheets(&self) -> &Assets<StyleSheet>;
|
||||||
|
|
||||||
/// Devuelve los scripts JavaScript de los recursos del contexto.
|
/// Devuelve los *scripts* JavaScript de los recursos del contexto.
|
||||||
fn javascripts(&self) -> &Assets<JavaScript>;
|
fn javascripts(&self) -> &Assets<JavaScript>;
|
||||||
|
|
||||||
// Contextual HELPERS **************************************************************************
|
// Contextual HELPERS **************************************************************************
|
||||||
|
|
||||||
/// Devuelve un identificador único dentro del contexto para el tipo `T`, si no se proporciona
|
/// Genera un identificador único por tipo (`<tipo>-<n>`) cuando no se aporta uno explícito.
|
||||||
/// un `id` explícito.
|
///
|
||||||
|
/// Es útil para componentes u otros elementos HTML que necesitan un identificador predecible si
|
||||||
|
/// no se proporciona ninguno.
|
||||||
fn required_id<T>(&mut self, id: Option<String>) -> String;
|
fn required_id<T>(&mut self, id: Option<String>) -> 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
|
/// Extiende [`Contextual`] con métodos para **instanciar** y configurar un nuevo contexto,
|
||||||
/// origen, el idioma, tema y composición para el renderizado, los recursos *favicon* ([`Favicon`]),
|
/// **renderizar los recursos** del documento (incluyendo el [`Favicon`], las hojas de estilo
|
||||||
/// hojas de estilo ([`StyleSheet`]) y *scripts* ([`JavaScript`]), así como *parámetros dinámicos
|
/// [`StyleSheet`] y los *scripts* [`JavaScript`]), o extender el uso de **parámetros dinámicos
|
||||||
/// heterogéneos* de contexto definidos en tiempo de ejecución.
|
/// tipados** con nuevos métodos.
|
||||||
///
|
///
|
||||||
/// # Ejemplos
|
/// # Ejemplos
|
||||||
///
|
///
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue