🎨 Mejora la página de bienvenida y el tema básico
Se unifican parámetros y estilos en el tema básico para ofrecer dos composiciones de página dirigidas a una introducción de contenidos neutra o con referencias a PageTop.
This commit is contained in:
parent
aae6c7df15
commit
d29a1b56af
8 changed files with 130 additions and 84 deletions
|
@ -25,55 +25,30 @@ async fn homepage(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
|
||||||
let app = &global::SETTINGS.app.name;
|
let app = &global::SETTINGS.app.name;
|
||||||
|
|
||||||
Page::new(request)
|
Page::new(request)
|
||||||
.with_theme("basic")
|
.with_theme("Basic")
|
||||||
.with_layout("intro")
|
.with_layout("PageTopIntro")
|
||||||
.with_title(L10n::l("welcome_title"))
|
.with_title(L10n::l("welcome_title"))
|
||||||
.with_description(L10n::l("welcome_intro").with_arg("app", app))
|
.with_description(L10n::l("welcome_intro").with_arg("app", app))
|
||||||
.with_param("intro_button_text", L10n::l("welcome_powered"))
|
.with_param("intro_button_txt", L10n::l("welcome_powered"))
|
||||||
.with_param("intro_button_link", "https://pagetop.cillero.es".to_string())
|
.with_param("intro_button_lnk", "https://pagetop.cillero.es".to_string())
|
||||||
.with_assets(AssetsOp::AddJavaScript(JavaScript::on_load_async("welcome-js", |cx|
|
|
||||||
util::indoc!(r#"
|
|
||||||
try {
|
|
||||||
const resp = await fetch("https://crates.io/api/v1/crates/pagetop");
|
|
||||||
const data = await resp.json();
|
|
||||||
const date = new Date(data.versions[0].created_at);
|
|
||||||
const formatted = date.toLocaleDateString("LANGID", { year: "numeric", month: "2-digit", day: "2-digit" });
|
|
||||||
document.getElementById("welcome-release").src = `https://img.shields.io/badge/Release%20date-${encodeURIComponent(formatted)}-blue?label=LABEL&style=for-the-badge`;
|
|
||||||
document.getElementById("welcome-badges").style.display = "block";
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Failed to fetch release date from crates.io:", e);
|
|
||||||
}
|
|
||||||
"#)
|
|
||||||
.replace("LANGID", cx.langid().to_string().as_str())
|
|
||||||
.replace("LABEL", L10n::l("welcome_release_label").using(cx).as_str())
|
|
||||||
.to_string(),
|
|
||||||
)))
|
|
||||||
.add_component(Html::with(|cx| html! {
|
|
||||||
p { (L10n::l("welcome_text1").using(cx)) }
|
|
||||||
div id="welcome-badges" style="display: none; margin-bottom: 1.1rem;" {
|
|
||||||
img
|
|
||||||
src="https://img.shields.io/crates/v/pagetop.svg?label=PageTop&style=for-the-badge"
|
|
||||||
alt=[L10n::l("welcome_pagetop_label").lookup(cx)] {} (" ")
|
|
||||||
img
|
|
||||||
id="welcome-release"
|
|
||||||
alt=[L10n::l("welcome_release_label").lookup(cx)] {} (" ")
|
|
||||||
img
|
|
||||||
src=(format!(
|
|
||||||
"https://img.shields.io/badge/license-MIT%2FApache-blue.svg?label={}&style=for-the-badge",
|
|
||||||
L10n::l("welcome_license_label").lookup(cx).unwrap_or_default()
|
|
||||||
))
|
|
||||||
alt=[L10n::l("welcome_license_label").lookup(cx)] {}
|
|
||||||
}
|
|
||||||
p { (L10n::l("welcome_text2").using(cx)) }
|
|
||||||
}))
|
|
||||||
.add_component(
|
.add_component(
|
||||||
Block::new()
|
Block::new()
|
||||||
.with_title(L10n::l("welcome_notice_title"))
|
.with_title(L10n::l("welcome_status_title"))
|
||||||
.add_component(Html::with(move |cx| html! {
|
.add_component(Html::with(move |cx| {
|
||||||
p { (L10n::l("welcome_notice_1").using(cx)) }
|
html! {
|
||||||
p { (L10n::l("welcome_notice_2").using(cx)) }
|
p { (L10n::l("welcome_status_1").using(cx)) }
|
||||||
p { (L10n::l("welcome_notice_3").using(cx)) }
|
p { (L10n::l("welcome_status_2").using(cx)) }
|
||||||
p { (L10n::l("welcome_notice_4").with_arg("app", app).using(cx)) }
|
}
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.add_component(
|
||||||
|
Block::new()
|
||||||
|
.with_title(L10n::l("welcome_support_title"))
|
||||||
|
.add_component(Html::with(move |cx| {
|
||||||
|
html! {
|
||||||
|
p { (L10n::l("welcome_support_1").using(cx)) }
|
||||||
|
p { (L10n::l("welcome_support_2").with_arg("app", app).using(cx)) }
|
||||||
|
}
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
.render()
|
.render()
|
||||||
|
|
|
@ -1,8 +1,33 @@
|
||||||
//! Es el tema básico que incluye PageTop por defecto.
|
/// Es el tema básico que incluye PageTop por defecto.
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// Tema básico por defecto.
|
/// Tema básico por defecto.
|
||||||
|
///
|
||||||
|
/// Ofrece las siguientes composiciones (*layouts*):
|
||||||
|
///
|
||||||
|
/// - **Composición predeterminada**
|
||||||
|
/// - Renderizado genérico con
|
||||||
|
/// [`ThemePage::render_body()`](crate::core::theme::ThemePage::render_body) usando las regiones
|
||||||
|
/// predefinidas en [`page_regions()`](crate::core::theme::Theme::page_regions).
|
||||||
|
///
|
||||||
|
/// - **`Intro`**
|
||||||
|
/// - Página de entrada con cabecera visual, título y descripción y un botón opcional de llamada a
|
||||||
|
/// la acción. Ideal para una página de inicio o bienvenida en el contexto de PageTop.
|
||||||
|
/// - **Regiones:** `content` (se renderiza dentro de `.intro-content__body`).
|
||||||
|
/// - **Parámetros:**
|
||||||
|
/// - `intro_button_txt` (`L10n`) – Texto del botón.
|
||||||
|
/// - `intro_button_lnk` (`Option<String>`) – URL del botón; si no se indica, el botón no se
|
||||||
|
/// muestra.
|
||||||
|
///
|
||||||
|
/// - **`PageTopIntro`**
|
||||||
|
/// - Variante de `Intro` con textos predefinidos sobre PageTop al inicio del contenido. Añade una
|
||||||
|
/// banda de *badges* con la versión de [PageTop en crates.io](https://crates.io/crates/pagetop)
|
||||||
|
/// más la fecha de la última versión publicada y la licencia de uso.
|
||||||
|
/// - **Regiones:** `content` (igual que `Intro`).
|
||||||
|
/// - **Parámetros:** los mismos que `Intro`.
|
||||||
|
///
|
||||||
|
/// **Nota:** si no se especifica `layout` o el valor no coincide con ninguno de los anteriores, se
|
||||||
|
/// aplica la composición predeterminada.
|
||||||
pub struct Basic;
|
pub struct Basic;
|
||||||
|
|
||||||
impl Extension for Basic {
|
impl Extension for Basic {
|
||||||
|
@ -14,14 +39,16 @@ impl Extension for Basic {
|
||||||
impl Theme for Basic {
|
impl Theme for Basic {
|
||||||
fn render_page_body(&self, page: &mut Page) -> Markup {
|
fn render_page_body(&self, page: &mut Page) -> Markup {
|
||||||
match page.layout() {
|
match page.layout() {
|
||||||
"intro" => render_intro(page),
|
"Intro" => render_intro(page),
|
||||||
|
"PageTopIntro" => render_pagetop_intro(page),
|
||||||
_ => <Self as ThemePage>::render_body(self, page, self.page_regions()),
|
_ => <Self as ThemePage>::render_body(self, page, self.page_regions()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_render_page_body(&self, page: &mut Page) {
|
fn after_render_page_body(&self, page: &mut Page) {
|
||||||
let styles = match page.layout() {
|
let styles = match page.layout() {
|
||||||
"intro" => "/css/intro.css",
|
"Intro" => "/css/intro.css",
|
||||||
|
"PageTopIntro" => "/css/intro.css",
|
||||||
_ => "/css/basic.css",
|
_ => "/css/basic.css",
|
||||||
};
|
};
|
||||||
page.alter_assets(AssetsOp::AddStyleSheet(
|
page.alter_assets(AssetsOp::AddStyleSheet(
|
||||||
|
@ -41,8 +68,8 @@ fn render_intro(page: &mut Page) -> Markup {
|
||||||
let title = page.title().unwrap_or_default();
|
let title = page.title().unwrap_or_default();
|
||||||
let intro = page.description().unwrap_or_default();
|
let intro = page.description().unwrap_or_default();
|
||||||
|
|
||||||
let intro_button_text: L10n = page.param_or_default("intro_button_text");
|
let intro_button_txt: L10n = page.param_or_default("intro_button_txt");
|
||||||
let intro_button_link: Option<&String> = page.param("intro_button_link");
|
let intro_button_lnk: Option<&String> = page.param("intro_button_lnk");
|
||||||
|
|
||||||
html! {
|
html! {
|
||||||
body id=[page.body_id().get()] class=[page.body_classes().get()] {
|
body id=[page.body_id().get()] class=[page.body_classes().get()] {
|
||||||
|
@ -74,17 +101,17 @@ fn render_intro(page: &mut Page) -> Markup {
|
||||||
}
|
}
|
||||||
main class="intro-content" {
|
main class="intro-content" {
|
||||||
section class="intro-content__body" {
|
section class="intro-content__body" {
|
||||||
@if intro_button_link.is_some() {
|
@if intro_button_lnk.is_some() {
|
||||||
div class="intro-button" {
|
div class="intro-button" {
|
||||||
a
|
a
|
||||||
class="intro-button__link"
|
class="intro-button__link"
|
||||||
href=[intro_button_link]
|
href=[intro_button_lnk]
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
{
|
{
|
||||||
span {} span {} span {}
|
span {} span {} span {}
|
||||||
div class="intro-button__text" {
|
div class="intro-button__text" {
|
||||||
(intro_button_text.using(page))
|
(intro_button_txt.using(page))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,3 +146,43 @@ fn render_intro(page: &mut Page) -> Markup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_pagetop_intro(page: &mut Page) -> Markup {
|
||||||
|
page.alter_assets(AssetsOp::AddJavaScript(JavaScript::on_load_async("intro-js", |cx|
|
||||||
|
util::indoc!(r#"
|
||||||
|
try {
|
||||||
|
const resp = await fetch("https://crates.io/api/v1/crates/pagetop");
|
||||||
|
const data = await resp.json();
|
||||||
|
const date = new Date(data.versions[0].created_at);
|
||||||
|
const formatted = date.toLocaleDateString("LANGID", { year: "numeric", month: "2-digit", day: "2-digit" });
|
||||||
|
document.getElementById("intro-release").src = `https://img.shields.io/badge/Release%20date-${encodeURIComponent(formatted)}-blue?label=LABEL&style=for-the-badge`;
|
||||||
|
document.getElementById("intro-badges").style.display = "block";
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to fetch release date from crates.io:", e);
|
||||||
|
}
|
||||||
|
"#)
|
||||||
|
.replace("LANGID", cx.langid().to_string().as_str())
|
||||||
|
.replace("LABEL", L10n::l("intro_release_label").using(cx).as_str())
|
||||||
|
.to_string(),
|
||||||
|
)))
|
||||||
|
.alter_child_in("content", ChildOp::Prepend(Child::with(Html::with(|cx| html! {
|
||||||
|
p { (L10n::l("intro_text1").using(cx)) }
|
||||||
|
div id="intro-badges" style="display: none; margin-bottom: 1.1rem;" {
|
||||||
|
img
|
||||||
|
src="https://img.shields.io/crates/v/pagetop.svg?label=PageTop&style=for-the-badge"
|
||||||
|
alt=[L10n::l("intro_pagetop_label").lookup(cx)] {} (" ")
|
||||||
|
img
|
||||||
|
id="intro-release"
|
||||||
|
alt=[L10n::l("intro_release_label").lookup(cx)] {} (" ")
|
||||||
|
img
|
||||||
|
src=(format!(
|
||||||
|
"https://img.shields.io/badge/license-MIT%2FApache-blue.svg?label={}&style=for-the-badge",
|
||||||
|
L10n::l("intro_license_label").lookup(cx).unwrap_or_default()
|
||||||
|
))
|
||||||
|
alt=[L10n::l("intro_license_label").lookup(cx)] {}
|
||||||
|
}
|
||||||
|
p { (L10n::l("intro_text2").using(cx)) }
|
||||||
|
}))));
|
||||||
|
|
||||||
|
render_intro(page)
|
||||||
|
}
|
||||||
|
|
|
@ -125,18 +125,18 @@ 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 en el
|
/// Devuelve una **lista estática** de pares `(Region, L10n)` que se usará para renderizar todas
|
||||||
/// orden indicado todas las regiones que componen una página.
|
/// las regiones que componen una página en el orden indicado .
|
||||||
///
|
///
|
||||||
/// Requisitos y recomendaciones:
|
/// Si un tema necesita un conjunto distinto de regiones, se puede **sobrescribir** este método
|
||||||
|
/// 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**. Se puede usar [`Region::default()`] para
|
||||||
/// declararla.
|
/// declararla.
|
||||||
/// - La etiqueta `L10n` se evalúa con el idioma activo de la página.
|
/// - La etiqueta `L10n` se evalúa con el idioma activo de la página.
|
||||||
///
|
///
|
||||||
/// Si tu tema define un conjunto distinto, se puede **sobrescribir** este método. Por defecto
|
/// Por defecto devuelve:
|
||||||
/// devuelve:
|
|
||||||
///
|
///
|
||||||
/// - `"header"`: cabecera.
|
/// - `"header"`: cabecera.
|
||||||
/// - `"content"`: contenido principal (**obligatoria**).
|
/// - `"content"`: contenido principal (**obligatoria**).
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
# Basic theme, intro layout.
|
# Basic theme, intro layout.
|
||||||
|
intro_pagetop_label = PageTop version on Crates.io
|
||||||
|
intro_release_label = Release date
|
||||||
|
intro_license_label = License
|
||||||
|
|
||||||
|
intro_text1 = PageTop is <strong>an opinionated Rust web development framework</strong> designed to build modular, extensible, and configurable web solutions.
|
||||||
|
intro_text2 = PageTop brings back the essence of the classic web, renders on the server (SSR) and uses <em>HTML-first</em> components, CSS and JavaScript, <strong>with the performance and security of Rust</strong>.
|
||||||
|
|
||||||
intro_code = Code
|
intro_code = Code
|
||||||
intro_have_fun = Coding is creating
|
intro_have_fun = Coding is creating
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,10 @@ welcome_title = Hello, world!
|
||||||
welcome_intro = Discover⚡{ $app }
|
welcome_intro = Discover⚡{ $app }
|
||||||
welcome_powered = A web solution powered by <strong>PageTop</strong>
|
welcome_powered = A web solution powered by <strong>PageTop</strong>
|
||||||
|
|
||||||
welcome_pagetop_label = PageTop version on Crates.io
|
welcome_status_title = Status
|
||||||
welcome_release_label = Release date
|
welcome_status_1 = If you can see this page, it means the <strong>PageTop</strong> server is running correctly, but the application is not fully configured. This may be due to routine maintenance or a temporary issue.
|
||||||
welcome_license_label = License
|
welcome_status_2 = If the issue persists, please <strong>contact the system administrator</strong>.
|
||||||
|
|
||||||
welcome_text1 = PageTop is <strong>a Rust-based web development framework</strong> designed to build modular, extensible, and configurable web solutions.
|
welcome_support_title = Support
|
||||||
welcome_text2 = PageTop brings back the essence of the classic web, renders on the server (SSR) and uses <em>HTML-first</em> components, CSS and JavaScript, <strong>with the performance and security of Rust</strong>.
|
welcome_support_1 = To report issues with the <strong>PageTop</strong> framework, use <a href="https://git.cillero.es/manuelcillero/pagetop/issues" target="_blank" rel="noreferrer">SoloGit</a>. Remember, before opening a new issue, review the existing ones to avoid duplicates.
|
||||||
|
welcome_support_2 = For issues specific to the application (<strong>{ $app }</strong>), please use its official repository or support channel.
|
||||||
welcome_notice_title = Notice
|
|
||||||
welcome_notice_1 = If you can see this page, the <strong>PageTop</strong> server is running correctly, but the application is not fully configured. This may be due to routine maintenance or a temporary issue.
|
|
||||||
welcome_notice_2 = If the issue persists, please <strong>contact the system administrator</strong>.
|
|
||||||
welcome_notice_3 = To report issues with the <strong>PageTop</strong> framework, use <a href="https://git.cillero.es/manuelcillero/pagetop/issues" target="_blank" rel="noreferrer">SoloGit</a>. Before opening a new issue, review the existing ones to avoid duplicates.
|
|
||||||
welcome_notice_4 = For issues specific to the application (<strong>{ $app }</strong>), please use its official repository or support channel.
|
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
# Basic theme, intro layout.
|
# Basic theme, intro layout.
|
||||||
|
intro_pagetop_label = Versión de PageTop en Crates.io
|
||||||
|
intro_release_label = Lanzamiento
|
||||||
|
intro_license_label = Licencia
|
||||||
|
|
||||||
|
intro_text1 = PageTop es un <strong>entorno de desarrollo web basado en Rust</strong>, pensado para construir soluciones web modulares, extensibles y configurables.
|
||||||
|
intro_text2 = PageTop reivindica la esencia de la web clásica, renderiza en el servidor (SSR) utilizando componentes <em>HTML-first</em>, CSS y JavaScript, <strong>con el rendimiento y la seguridad de Rust</strong>.
|
||||||
|
|
||||||
intro_code = Código
|
intro_code = Código
|
||||||
intro_have_fun = Programar es crear
|
intro_have_fun = Programar es crear
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,10 @@ welcome_title = ¡Hola, mundo!
|
||||||
welcome_intro = Descubre⚡{ $app }
|
welcome_intro = Descubre⚡{ $app }
|
||||||
welcome_powered = Una solución web creada con <strong>PageTop</strong>
|
welcome_powered = Una solución web creada con <strong>PageTop</strong>
|
||||||
|
|
||||||
welcome_pagetop_label = Versión de PageTop en Crates.io
|
welcome_status_title = Estado
|
||||||
welcome_release_label = Lanzamiento
|
welcome_status_1 = Si puedes ver esta página, es porque el servidor de <strong>PageTop</strong> está funcionando correctamente, pero la aplicación no está completamente configurada. Esto puede deberse a tareas de mantenimiento o a una incidencia temporal.
|
||||||
welcome_license_label = Licencia
|
welcome_status_2 = Si el problema persiste, por favor, <strong>contacta con el administrador del sistema</strong>.
|
||||||
|
|
||||||
welcome_text1 = PageTop es un <strong>entorno de desarrollo web basado en Rust</strong>, pensado para construir soluciones web modulares, extensibles y configurables.
|
welcome_support_title = Soporte
|
||||||
welcome_text2 = PageTop reivindica la esencia de la web clásica, renderiza en el servidor (SSR) utilizando componentes <em>HTML-first</em>, CSS y JavaScript, <strong>con el rendimiento y la seguridad de Rust</strong>.
|
welcome_support_1 = Para comunicar incidencias del propio entorno <strong>PageTop</strong>, utiliza <a href="https://git.cillero.es/manuelcillero/pagetop/issues" target="_blank" rel="noreferrer">SoloGit</a>. Recuerda, antes de abrir una nueva incidencia, revisa las existentes para evitar duplicados.
|
||||||
|
welcome_support_2 = Para fallos específicos de la aplicación (<strong>{ $app }</strong>), utiliza su repositorio oficial o su canal de soporte.
|
||||||
welcome_notice_title = Aviso
|
|
||||||
welcome_notice_1 = Si puedes ver esta página, el servidor de <strong>PageTop</strong> está funcionando correctamente, pero la aplicación no está completamente configurada. Esto puede deberse a tareas de mantenimiento o a una incidencia temporal.
|
|
||||||
welcome_notice_2 = Si el problema persiste, por favor, <strong>contacta con el administrador del sistema</strong>.
|
|
||||||
welcome_notice_3 = Para comunicar incidencias del propio entorno <strong>PageTop</strong>, utiliza <a href="https://git.cillero.es/manuelcillero/pagetop/issues" target="_blank" rel="noreferrer">SoloGit</a>. Antes de abrir una nueva incidencia, revisa las existentes para evitar duplicados.
|
|
||||||
welcome_notice_4 = Para fallos específicos de la aplicación (<strong>{ $app }</strong>), utiliza su repositorio oficial o su canal de soporte.
|
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
--color: #1a202c;
|
--color: #1a202c;
|
||||||
--color-gray: #e4e4e7;
|
--color-gray: #e4e4e7;
|
||||||
--color-link: #1e4eae;
|
--color-link: #1e4eae;
|
||||||
--color-block-1: #fecaca;
|
--color-block-1: #b689ff;
|
||||||
--color-block-2: #e6a9e2;
|
--color-block-2: #fecaca;
|
||||||
--color-block-3: #b689ff;
|
--color-block-3: #e6a9e2;
|
||||||
--color-block-4: #ffedca;
|
--color-block-4: #ffedca;
|
||||||
--color-block-5: #ffffff;
|
--color-block-5: #ffffff;
|
||||||
--focus-outline: 2px solid var(--color-link);
|
--focus-outline: 2px solid var(--color-link);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue