Add default welcome homepage

This commit is contained in:
Manuel Cillero 2024-11-18 00:33:51 +01:00
parent 346dac7713
commit 92268ca653
32 changed files with 211 additions and 228 deletions

View file

@ -12,11 +12,6 @@ members = [
# App
"packages/drust",
# Examples
# "examples/app-basic",
# "examples/hello-world",
# "examples/hello-name",
]
[workspace.package]

View file

@ -1,7 +0,0 @@
use pagetop_build::StaticFilesBundle;
fn main() -> std::io::Result<()> {
StaticFilesBundle::from_dir("./static/base")
.with_name("base")
.build()
}

View file

@ -1,37 +0,0 @@
<div align="center">
<h1>PageTop Build</h1>
<p>Simplifies the process of embedding resources in PageTop app binaries.</p>
[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?style=for-the-badge)](#-license)
[![API Docs](https://img.shields.io/docsrs/pagetop-build?label=API%20Docs&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop-build)
[![Crates.io](https://img.shields.io/crates/v/pagetop-build.svg?style=for-the-badge&logo=ipfs)](https://crates.io/crates/pagetop-build)
[![Downloads](https://img.shields.io/crates/d/pagetop-build.svg?style=for-the-badge&logo=transmission)](https://crates.io/crates/pagetop-build)
</div>
# 📦 About PageTop
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
Rendering* web solutions.
# 🚧 Warning
**PageTop** framework is currently in active development. The API is unstable and subject to
frequent changes. Production use is not recommended until version **0.1.0**.
# 📜 License
All code in this crate is dual-licensed under either:
* MIT License
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
* Apache License, Version 2.0,
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
at your option. This means you can select the license you prefer! This dual-licensing approach is
the de-facto standard in the Rust ecosystem.

View file

@ -1,51 +0,0 @@
<div align="center">
<h1>PageTop Macros</h1>
<p>A collection of macros that boost PageTop development.</p>
[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg?style=for-the-badge)](#-license)
[![API Docs](https://img.shields.io/docsrs/pagetop-macros?label=API%20Docs&style=for-the-badge&logo=Docs.rs)](https://docs.rs/pagetop-macros)
[![Crates.io](https://img.shields.io/crates/v/pagetop-macros.svg?style=for-the-badge&logo=ipfs)](https://crates.io/crates/pagetop-macros)
[![Downloads](https://img.shields.io/crates/d/pagetop-macros.svg?style=for-the-badge&logo=transmission)](https://crates.io/crates/pagetop-macros)
</div>
# 📦 About PageTop
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
Rendering* web solutions.
# 🚧 Warning
**PageTop** framework is currently in active development. The API is unstable and subject to
frequent changes. Production use is not recommended until version **0.1.0**.
# 🔖 Credits
This crate includes an adapted version of [maud-macros](https://crates.io/crates/maud_macros),
version [0.25.0](https://github.com/lambda-fairy/maud/tree/v0.25.0/maud_macros), by
[Chris Wong](https://crates.io/users/lambda-fairy).
It also includes an adapted version of [SmartDefault](https://crates.io/crates/smart_default)
(version 0.7.1) by [Jane Doe](https://crates.io/users/jane-doe), renamed as `AutoDefault`, to
streamline the implementation of `Default` in **PageTop** projects.
Both adaptations eliminate the need to explicitly add `maud` or `smart_default` as dependencies in
`Cargo.toml` files.
# 📜 License
All code in this crate is dual-licensed under either:
* MIT License
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
* Apache License, Version 2.0,
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
at your option. This means you can select the license you prefer! This dual-licensing approach is
the de-facto standard in the Rust ecosystem.

View file

@ -19,7 +19,6 @@ pagetop.workspace = true
include_dir.workspace = true
static-files.workspace = true
tera = "1.20.0"
[build-dependencies]

View file

@ -19,22 +19,24 @@ license = { workspace = true }
name = "pagetop"
[dependencies]
colored = "2.1.0"
concat-string = "1.0.1"
figlet-rs = "0.1.5"
fluent-bundle = "0.15.3"
fluent-templates = "0.11.0"
itoa = "1.0.11"
nom = "7.1.3"
paste = "1.0.15"
substring = "1.4.5"
terminal_size = "0.4.0"
toml = "0.8.19"
tracing = "0.1.40"
tracing-appender = "0.2.3"
colored = "2.1.0"
concat-string = "1.0.1"
figlet-rs = "0.1.5"
itoa = "1.0.11"
nom = "7.1.3"
paste = "1.0.15"
substring = "1.4.5"
terminal_size = "0.4.0"
toml = "0.8.19"
tracing = "0.1.40"
tracing-appender = "0.2.3"
tracing-subscriber = { version = "0.3.18", features = ["json", "env-filter"] }
tracing-actix-web = "0.7.15"
unic-langid = { version = "0.9.5", features = ["macros"] }
tracing-actix-web = "0.7.15"
fluent-bundle = "0.15.3"
fluent-templates = "0.11.0"
unic-langid = { version = "0.9.5", features = ["macros"] }
actix-web = "4.9.0"
actix-web-files = { package = "actix-files", version = "0.6.6" }

View file

@ -42,7 +42,7 @@ impl Application {
LazyLock::force(&trace::TRACING);
// Validates the default language identifier.
LazyLock::force(&locale::LANGID_DEFAULT);
LazyLock::force(&locale::DEFAULT_LANGID);
// Registers the application's packages.
package::all::register_packages(root_package);

View file

@ -2,3 +2,4 @@ mod definition;
pub use definition::{PackageRef, PackageTrait};
pub(crate) mod all;
pub(crate) mod welcome;

View file

@ -1,5 +1,5 @@
use crate::core::action::add_action;
use crate::core::package::PackageRef;
use crate::core::package::{welcome, PackageRef};
use crate::core::theme::all::THEMES;
use crate::{service, trace};
@ -123,4 +123,6 @@ pub fn configure_services(scfg: &mut service::web::ServiceConfig) {
for m in ENABLED_PACKAGES.read().unwrap().iter() {
m.configure_service(scfg);
}
// Default welcome homepage.
scfg.route("/", service::web::get().to(welcome::homepage));
}

View file

@ -0,0 +1,120 @@
use crate::html::{html, Markup};
use crate::locale::L10n;
use crate::{concat_string, global};
pub async fn homepage() -> Markup {
html! {
head {
meta charset="UTF-8" {}
meta name="viewport" content="width=device-width, initial-scale=1" {}
title { (concat_string!(
&global::SETTINGS.app.name, " | ", L10n::l("welcome_page").to_string()
)) }
style { r#"
body {
background-color: #f3d060;
font-size: 20px;
}
.wrapper {
max-width: 1200px;
width: 100%;
margin: 0 auto;
padding: 0;
}
.container {
padding: 0 16px;
}
.title {
font-size: clamp(3rem, 10vw, 10rem);
letter-spacing: -0.05em;
line-height: 1.2;
margin: 0;
}
.subtitle {
font-size: clamp(1.8rem, 2vw, 3rem);
letter-spacing: -0.02em;
line-height: 1.2;
margin: 0;
}
.powered {
margin: .5em 0 1em;
}
.box-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: stretch;
gap: 1.5em;
}
.box {
flex: 1 1 280px;
border: 3px solid #25282a;
box-shadow: 5px 5px 0px #25282a;
box-sizing: border-box;
padding: 0 16px;
}
footer {
margin-top: 5em;
font-size: 14px;
font-weight: 500;
color: #a5282c;
}
"# }
}
body style="font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;" {
div class="wrapper" {
div class="container" {
h1 class="title" { (L10n::l("welcome_title").markup()) }
p class="subtitle" {
(L10n::l("welcome_intro").with_arg("app", format!(
"<span style=\"font-weight: bold;\">{}</span>",
&global::SETTINGS.app.name
)).markup())
}
p class="powered" {
(L10n::l("welcome_powered").with_arg("pagetop", format!(
"<a href=\"{}\" target=\"_blank\">{}</a>",
"https://crates.io/crates/pagetop", "PageTop"
)).markup())
}
h2 { (L10n::l("welcome_page").markup()) }
div class="box-container" {
section class="box" style="background-color: #5eb0e5;" {
h3 {
(L10n::l("welcome_subtitle")
.with_arg("app", &global::SETTINGS.app.name)
.markup())
}
p { (L10n::l("welcome_text1").markup()) }
p { (L10n::l("welcome_text2").markup()) }
}
section class="box" style="background-color: #aee1cd;" {
h3 {
(L10n::l("welcome_pagetop_title").markup())
}
p { (L10n::l("welcome_pagetop_text1").markup()) }
p { (L10n::l("welcome_pagetop_text2").markup()) }
p { (L10n::l("welcome_pagetop_text3").markup()) }
}
section class="box" style="background-color: #ebebe3;" {
h3 {
(L10n::l("welcome_issues_title").markup())
}
p { (L10n::l("welcome_issues_text1").markup()) }
p {
(L10n::l("welcome_issues_text2")
.with_arg("app", &global::SETTINGS.app.name)
.markup())
}
}
}
footer { "[" (L10n::l("welcome_have_fun").markup()) "]" }
}
}
}
}
}

View file

@ -19,7 +19,7 @@ impl PackageTrait for NoTheme {
impl ThemeTrait for NoTheme {
}
pub static THEME_DEFAULT: LazyLock<ThemeRef> =
pub static DEFAULT_THEME: LazyLock<ThemeRef> =
LazyLock::new(|| match theme_by_short_name(&global::SETTINGS.app.theme) {
Some(theme) => theme,
None => &NoTheme,

View file

@ -79,7 +79,7 @@ pub use concat_string::concat_string;
/// Enables flexible identifier concatenation in macros, allowing new items with pasted identifiers.
pub use paste::paste;
pub use pagetop_macros::{main, test, AutoDefault};
pub use pagetop_macros::{html, main, test, AutoDefault};
pub type StaticResources = std::collections::HashMap<&'static str, static_files::Resource>;

View file

@ -84,6 +84,7 @@
//! static_locales!(LOCALES_SAMPLE in "path/to/locale");
//! ```
use crate::html::{Markup, PreEscaped};
use crate::{global, kv, AutoDefault};
pub use fluent_bundle::FluentValue;
@ -119,7 +120,7 @@ pub static LANGID_FALLBACK: LazyLock<LanguageIdentifier> = LazyLock::new(|| lang
/// Sets the application's default
/// [Unicode Language Identifier](https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)
/// through `SETTINGS.app.language`.
pub static LANGID_DEFAULT: LazyLock<&LanguageIdentifier> =
pub static DEFAULT_LANGID: LazyLock<&LanguageIdentifier> =
LazyLock::new(|| langid_for(&global::SETTINGS.app.language).unwrap_or(&LANGID_FALLBACK));
pub fn langid_for(language: impl Into<String>) -> Result<&'static LanguageIdentifier, String> {
@ -228,6 +229,18 @@ impl L10n {
},
}
}
/// Escapes the content using the default language identifier.
pub fn markup(&self) -> Markup {
let content = self.using(&DEFAULT_LANGID).unwrap_or_default();
PreEscaped(content)
}
/// Escapes the content using the specified language identifier.
pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup {
let content = self.using(langid).unwrap_or_default();
PreEscaped(content)
}
}
impl fmt::Display for L10n {
@ -244,7 +257,7 @@ impl fmt::Display for L10n {
locales.lookup(
match key.as_str() {
LANGUAGE_SET_FAILURE => &LANGID_FALLBACK,
_ => &LANGID_DEFAULT,
_ => &DEFAULT_LANGID,
},
key,
)
@ -252,7 +265,7 @@ impl fmt::Display for L10n {
locales.lookup_with_args(
match key.as_str() {
LANGUAGE_SET_FAILURE => &LANGID_FALLBACK,
_ => &LANGID_DEFAULT,
_ => &DEFAULT_LANGID,
},
key,
&self.args,

View file

@ -1,13 +0,0 @@
# Branding component.
site_home = Home
# PoweredBy component.
poweredby_pagetop = Powered by {$pagetop_link}
pagetop_logo = PageTop logo
# Menu component.
menu_toggle = Toggle menu visibility
# Form components.
button_submit = Submit
button_reset = Reset

View file

@ -1,8 +0,0 @@
header = Header
pagetop = Page Top
content = Content
sidebar_left = Sidebar Left
sidebar_right = Sidebar Right
footer = Footer
skip_to_content = Skip to main content (Press Enter)

View file

@ -1,26 +1,20 @@
welcome_package_name = Default homepage
welcome_package_description = Displays a demo homepage when none is configured.
welcome_title = Hello world!
welcome_intro = This page is used to check the proper operation of the { $app } installation.
welcome_powered = This web solution is powered by { $pagetop }.
welcome_code = Code
welcome = Welcome
welcome_intro = Verifying the proper operation of your { $app } installation.
welcome_powered = A web solution powered by { $pagetop }.
welcome_page = Welcome page
welcome_subtitle = Are you user of { $app }?
welcome_page = Welcome Page
welcome_subtitle = Are you a { $app } user?
welcome_text1 = If you don't know what this page is about, this probably means that the site is either experiencing problems or is undergoing routine maintenance.
welcome_text2 = If the problem persists, please contact your system administrator.
welcome_text2 = If the issue persists, please contact your system administrator for assistance.
welcome_pagetop_title = About PageTop
welcome_pagetop_text1 = If you can read this page, it means that the PageTop server is working properly, but has not yet been configured.
welcome_pagetop_text2 = PageTop is a <a href="https://www.rust-lang.org" target="_blank">Rust</a>-based web development framework to build modular, extensible, and configurable web solutions.
welcome_pagetop_text3 = For more information on PageTop please visit the <a href="https://docs.rs/pagetop/latest/pagetop" target="_blank">technical documentation</a>.
welcome_pagetop_text2 = PageTop is a <a href="https://www.rust-lang.org" target="_blank">Rust</a>-based web development framework designed to create modular, extensible, and configurable web solutions.
welcome_pagetop_text3 = For detailed information, please visit the <a href="https://docs.rs/pagetop/latest/pagetop" target="_blank">official technical documentation</a>.
welcome_promo_title = Promoting PageTop
welcome_promo_text1 = You are free to use the image below on applications powered by { $pagetop }. Thanks for using PageTop!
welcome_issues_title = Reporting Issues
welcome_issues_text1 = To report any issues with PageTop, please use <a href="https://github.com/manuelcillero/pagetop/issues" target="_blank">GitHub</a>. However, check the existing error reports to avoid duplicates.
welcome_issues_text2 = For issues specific to { $app }, please refer to its official repository or support channel, rather than directly to PageTop.
welcome_issues_title = Reporting problems
welcome_issues_text1 = Please use <a href="https://github.com/manuelcillero/pagetop/issues" target="_blank">GitHub to report any issues</a> with PageTop. However, check the existing error reports before submitting a new issue.
welcome_issues_text2 = If the issues are specific to { $app }, please refer to its official repository or support channel, rather than directly to PageTop.
welcome_have_fun = Write code. Break nothing. Repeat.

View file

@ -1,13 +0,0 @@
# Branding component.
site_home = Inicio
# PoweredBy component.
poweredby_pagetop = Funciona con {$pagetop_link}
pagetop_logo = Logotipo de PageTop
# Menu component.
menu_toggle = Alternar visibilidad del menú
# Form components.
button_submit = Enviar
button_reset = Reiniciar

View file

@ -1,8 +0,0 @@
header = Cabecera
pagetop = Superior
content = Contenido
sidebar_left = Barra lateral izquierda
sidebar_right = Barra lateral derecha
footer = Pie
skip_to_content = Ir al contenido principal (Pulsar Intro)

View file

@ -1,26 +1,20 @@
welcome_package_name = Página de inicio predeterminada
welcome_package_description = Muestra una página de demostración predeterminada cuando no hay ninguna configurada.
welcome_title = ¡Hola mundo!
welcome_intro = Esta página se utiliza para verificar el correcto funcionamiento de la instalación de { $app }.
welcome_powered = Esta solución web funciona con { $pagetop }.
welcome_code = Código
welcome = Bienvenida
welcome_intro = Verificando el funcionamiento de tu instalación de { $app }.
welcome_powered = Una solución web con la potencia de { $pagetop }.
welcome_page = Página de bienvenida
welcome_page = Página de Bienvenida
welcome_subtitle = ¿Eres usuario de { $app }?
welcome_text1 = Si no sabes de qué trata esta página, probablemente significa que el sitio está experimentando problemas o está pasando por un mantenimiento de rutina.
welcome_text2 = Si el problema persiste, póngase en contacto con el administrador del sistema.
welcome_text1 = Si no sabes de qué trata esta página probablemente significa que el sitio está experimentando problemas o está pasando por un mantenimiento de rutina.
welcome_text2 = Si el problema persiste, por favor póngase en contacto con el administrador del sistema.
welcome_pagetop_title = Sobre PageTop
welcome_pagetop_text1 = Si puedes leer esta página, significa que el servidor PageTop funciona correctamente, pero aún no se ha configurado.
welcome_pagetop_text2 = PageTop es un entorno de desarrollo web basado en <a href="https://www.rust-lang.org/es" target="_blank">Rust</a> para construir soluciones web modulares, extensibles y configurables.
welcome_pagetop_text3 = Para más información sobre PageTop, por favor visita la <a href="https://docs.rs/pagetop/latest/pagetop" target="_blank">documentación técnica</a>.
welcome_pagetop_text1 = Si puedes leer esta página significa que el servidor PageTop funciona correctamente, pero aún no se ha configurado.
welcome_pagetop_text2 = PageTop es un entorno de desarrollo web basado en <a href="https://www.rust-lang.org/es" target="_blank">Rust</a>, diseñado para crear soluciones web modulares, extensibles y configurables.
welcome_pagetop_text3 = Para más información visita la <a href="https://docs.rs/pagetop/latest/pagetop" target="_blank">documentación técnica oficial</a>.
welcome_promo_title = Promociona PageTop
welcome_promo_text1 = Eres libre de usar la siguiente imagen en aplicaciones desarrolladas con { $pagetop }. ¡Gracias por usar PageTop!
welcome_issues_title = Informando Problemas
welcome_issues_text1 = Para comunicar cualquier problema con PageTop utiliza <a href="https://github.com/manuelcillero/pagetop/issues" target="_blank">GitHub</a>. No obstante, comprueba los informes de errores ya existentes para evitar duplicados.
welcome_issues_text2 = Si son fallos específicos de { $app }, por favor acude a su repositorio oficial o canal de soporte, y no al de PageTop directamente.
welcome_issues_title = Informando problemas
welcome_issues_text1 = Por favor, utiliza <a href="https://github.com/manuelcillero/pagetop/issues" target="_blank">GitHub para reportar cualquier problema</a> con PageTop. No obstante, comprueba los informes de errores existentes antes de enviar uno nuevo.
welcome_issues_text2 = Si son fallos específicos de { $app }, por favor acude a su repositorio o canal de soporte oficial y no al de PageTop directamente.
welcome_have_fun = Escribe código. No rompas nada. Repite.

View file

@ -2,7 +2,7 @@
// RE-EXPORTED.
pub use crate::{concat_string, main, paste, test};
pub use crate::{concat_string, html, main, paste, test};
pub use crate::{AutoDefault, StaticResources, TypeId, Weight};

View file

@ -2,14 +2,6 @@
pub mod config;
mod data;
mod de;
mod error;
mod file;
mod path;
mod source;
mod value;
use crate::trace;
use std::io;

View file

@ -1,8 +1,16 @@
//! Retrieve settings values from configuration files.
mod data;
mod de;
mod error;
mod file;
mod path;
mod source;
mod value;
use crate::concat_string;
use crate::util::data::ConfigData;
use crate::util::file::File;
use crate::util::config::data::ConfigData;
use crate::util::config::file::File;
use std::sync::LazyLock;

View file

@ -1,7 +1,7 @@
use crate::util::error::*;
use crate::util::path;
use crate::util::source::Source;
use crate::util::value::Value;
use crate::util::config::error::*;
use crate::util::config::path;
use crate::util::config::source::Source;
use crate::util::config::value::Value;
use serde::de::Deserialize;

View file

@ -1,6 +1,6 @@
use crate::util::data::ConfigData;
use crate::util::error::*;
use crate::util::value::{Table, Value, ValueKind};
use crate::util::config::data::ConfigData;
use crate::util::config::error::*;
use crate::util::config::value::{Table, Value, ValueKind};
use serde::de;
use serde::forward_to_deserialize_any;

View file

@ -1,9 +1,9 @@
mod source;
mod toml;
use crate::util::error::*;
use crate::util::source::Source;
use crate::util::value::Value;
use crate::util::config::error::*;
use crate::util::config::source::Source;
use crate::util::config::value::Value;
use std::collections::HashMap;
use std::path::{Path, PathBuf};

View file

@ -1,4 +1,4 @@
use crate::util::value::{Value, ValueKind};
use crate::util::config::value::{Value, ValueKind};
use toml;

View file

@ -1,5 +1,5 @@
use crate::util::error::*;
use crate::util::value::{Value, ValueKind};
use crate::util::config::error::*;
use crate::util::config::value::{Value, ValueKind};
use std::collections::HashMap;
use std::str::FromStr;

View file

@ -1,6 +1,6 @@
use crate::util::error::*;
use crate::util::path;
use crate::util::value::{Value, ValueKind};
use crate::util::config::error::*;
use crate::util::config::path;
use crate::util::config::value::{Value, ValueKind};
use std::collections::HashMap;
use std::fmt::Debug;

View file

@ -1,4 +1,4 @@
use crate::util::error::*;
use crate::util::config::error::*;
use serde::de::{Deserialize, Deserializer, Visitor};