🚧 Working on 0.1.0 version

This commit is contained in:
Manuel Cillero 2024-11-30 11:35:48 +01:00
parent 9f62955acb
commit 41cedf2541
28 changed files with 3473 additions and 535 deletions

View file

@ -45,7 +45,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);
@ -61,11 +61,13 @@ impl Application {
// Displays the application banner based on the configuration.
fn show_banner() {
use colored::Colorize;
use terminal_size::{terminal_size, Width};
if global::SETTINGS.app.startup_banner.to_lowercase() != "off" {
// Application name, formatted for the terminal width if necessary.
let mut app_name = global::SETTINGS.app.name.to_string();
let mut app_ff = "".to_string();
let app_name = &global::SETTINGS.app.name;
if let Some((Width(term_width), _)) = terminal_size() {
if term_width >= 80 {
let maxlen: usize = ((term_width / 10) - 2).into();
@ -74,19 +76,27 @@ impl Application {
app = format!("{app}...");
}
if let Some(ff) = figfont::FIGFONT.convert(&app) {
app_name = ff.to_string();
app_ff = ff.to_string();
}
}
}
println!("\n{app_name}");
if app_ff.is_empty() {
println!("\n{app_name}");
} else {
print!("\n{app_ff}");
}
// Application description.
if !global::SETTINGS.app.description.is_empty() {
println!("{}\n", global::SETTINGS.app.description);
println!("{}", global::SETTINGS.app.description.cyan());
};
// PageTop version.
println!("Powered by PageTop {}\n", env!("CARGO_PKG_VERSION"));
println!(
"{} {}\n",
"Powered by PageTop".yellow(),
env!("CARGO_PKG_VERSION").yellow()
);
}
}

View file

@ -12,229 +12,122 @@ impl PackageTrait for Welcome {
}
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
scfg.route("/", service::web::get().to(home_page))
.route("/{lang}", service::web::get().to(home_lang));
scfg.route("/", service::web::get().to(homepage));
}
}
async fn home_page(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
home(request, &LANGID_DEFAULT)
}
async fn home_lang(
request: HttpRequest,
path: service::web::Path<String>,
) -> ResultPage<Markup, ErrorPage> {
match langid_for(path.into_inner()) {
Ok(lang) => home(request, lang),
_ => Err(ErrorPage::NotFound(request)),
}
}
fn home(request: HttpRequest, lang: &'static LanguageIdentifier) -> ResultPage<Markup, ErrorPage> {
async fn homepage(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
Page::new(request)
.with_title(L10n::l("welcome_title"))
.with_assets(AssetsOp::LangId(lang))
.with_assets(AssetsOp::AddStyleSheet(StyleSheet::from(
"/base/css/welcome.css",
)))
.with_body_id("welcome")
.with_component(hello_world())
.with_component(welcome())
.with_component(about_pagetop())
.with_component(promo_pagetop())
.with_component(reporting_issues())
.with_title(L10n::l("welcome_page"))
.with_assets(AssetsOp::Theme("Basic"))
.with_assets(AssetsOp::AddStyleSheet(StyleSheet::inline("styles", r##"
body {
background-color: #f3d060;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 20px;
}
.skip__to_content {
display: none;
}
.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;
}
"##)))
.with_component(Html::with(html! {
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()) " ]" }
}
}
}))
.render()
}
fn hello_world() -> flex::Container {
flex::Container::header()
.with_classes(ClassesOp::Add, "hello-world")
.with_justify(flex::Justify::Center)
.add_item(
flex::Item::new()
.with_size(flex::Size::Percent90)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::MD))
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "hello-col-text")
.with_size(flex::Size::Percent40)
.add_component(
Heading::h1(L10n::l("welcome_title"))
.with_size(HeadingSize::Medium),
)
.add_component(
Paragraph::fluent(L10n::l("welcome_intro").with_arg(
"app",
format!(
"<span class=\"app-name\">{}</span>",
&global::SETTINGS.app.name,
),
))
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(
L10n::l("welcome_powered").with_arg(
"pagetop",
format!(
"<a href=\"{}\" target=\"_blank\">{}</a>",
"https://pagetop.cillero.es", "PageTop",
),
),
))
.add_component(
Button::anchor(
"https://github.com/manuelcillero/pagetop",
L10n::l("welcome_code"),
)
.with_target(ButtonTarget::Blank)
.with_left_icon(Some(Icon::with("git")))
.with_classes(ClassesOp::Add, "code-link")
.with_font_size(FontSize::Medium),
)
.add_component(
Button::anchor("#welcome-page", L10n::l("welcome"))
.with_style(StyleBase::Link)
.with_left_icon(Some(Icon::with("arrow-down-circle-fill")))
.with_classes(ClassesOp::Add, "welcome-link")
.with_font_size(FontSize::Medium),
),
)
.add_item(
flex::Item::with(Image::with("/base/images/header.svg"))
.with_classes(ClassesOp::Add, "hello-col-image")
.with_size(flex::Size::Percent60),
),
),
)
}
fn welcome() -> flex::Container {
flex::Container::section()
.with_id("welcome-page")
.with_classes(ClassesOp::Add, "welcome")
.with_justify(flex::Justify::Center)
.add_item(
flex::Item::new()
.with_size(flex::Size::Percent80)
.add_component(Heading::h2(L10n::l("welcome_page")))
.add_component(
Heading::h3(L10n::l("welcome_subtitle").with_arg(
"app",
format!(
"<span class=\"app-name\">{}</span>",
&global::SETTINGS.app.name
),
))
.with_size(HeadingSize::Subtitle),
)
.add_component(
Paragraph::fluent(L10n::l("welcome_text1")).with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(L10n::l("welcome_text2"))),
)
}
fn about_pagetop() -> flex::Container {
flex::Container::new()
.with_classes(ClassesOp::Add, "pagetop")
.with_justify(flex::Justify::Center)
.add_item(
flex::Item::new()
.with_size(flex::Size::Percent90)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::SM))
.add_item(
flex::Item::with(Image::with("/base/images/about.svg"))
.with_classes(ClassesOp::Add, "pagetop-col-image")
.with_size(flex::Size::Percent40),
)
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "pagetop-col-text")
.add_component(Heading::h2(L10n::l("welcome_pagetop_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_pagetop_text1"))
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text2")))
.add_component(Paragraph::fluent(L10n::l("welcome_pagetop_text3"))),
),
),
)
}
fn promo_pagetop() -> flex::Container {
flex::Container::new()
.with_classes(ClassesOp::Add, "promo")
.with_justify(flex::Justify::Center)
.add_item(
flex::Item::new()
.with_size(flex::Size::Percent75)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::MD))
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "promo-col-text")
.with_size(flex::Size::Percent50)
.add_component(Heading::h2(L10n::l("welcome_promo_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_promo_text1").with_arg(
"pagetop",
format!(
"<a href=\"{}\" target=\"_blank\">{}</a>",
"https://crates.io/crates/pagetop", "PageTop",
),
))
.with_font_size(FontSize::Medium),
),
)
.add_item(
flex::Item::with(Image::with("/base/images/pagetop.png"))
.with_classes(ClassesOp::Add, "promo-col-image")
.with_size(flex::Size::Percent50),
),
),
)
}
fn reporting_issues() -> flex::Container {
flex::Container::new()
.with_classes(ClassesOp::Add, "issues")
.with_justify(flex::Justify::Center)
.add_item(
flex::Item::new()
.with_size(flex::Size::Percent90)
.add_component(
flex::Container::new()
.with_direction(flex::Direction::Column(BreakPoint::MD))
.add_item(
flex::Item::with(Image::with("/base/images/issues.jpg"))
.with_classes(ClassesOp::Add, "issues-col-image"),
)
.add_item(
flex::Item::new()
.with_classes(ClassesOp::Add, "issues-col-text")
.with_size(flex::Size::Percent50)
.add_component(Heading::h2(L10n::l("welcome_issues_title")))
.add_component(
Paragraph::fluent(L10n::l("welcome_issues_text1"))
.with_font_size(FontSize::Medium),
)
.add_component(Paragraph::fluent(
L10n::l("welcome_issues_text2").with_arg(
"app",
format!(
"<span class=\"app-name\">{}</span>",
&global::SETTINGS.app.name,
),
),
)),
),
),
)
}

View file

@ -3,30 +3,9 @@ use crate::prelude::*;
pub struct Basic;
impl PackageTrait for Basic {
fn name(&self) -> L10n {
L10n::n("Basic")
}
fn theme(&self) -> Option<ThemeRef> {
Some(&Basic)
}
}
impl ThemeTrait for Basic {
fn after_prepare_body(&self, page: &mut Page) {
page.set_assets(AssetsOp::SetFavicon(Some(
Favicon::new().with_icon("/base/favicon.ico"),
)))
.set_assets(AssetsOp::AddStyleSheet(
StyleSheet::from("/base/css/normalize.min.css")
.with_version("8.0.1")
.with_weight(-90),
))
.set_assets(AssetsOp::AddBaseAssets)
.set_assets(AssetsOp::AddStyleSheet(
StyleSheet::from("/base/css/basic.css")
.with_version("0.0.1")
.with_weight(-90),
));
}
}
impl ThemeTrait for Basic {}

View file

@ -14,10 +14,7 @@ impl PackageTrait for Chassis {
impl ThemeTrait for Chassis {
fn after_prepare_body(&self, page: &mut Page) {
page.set_assets(AssetsOp::SetFavicon(Some(
Favicon::new().with_icon("/base/favicon.ico"),
)))
.set_assets(AssetsOp::AddStyleSheet(
page.set_assets(AssetsOp::AddStyleSheet(
StyleSheet::from("/base/css/normalize.min.css")
.with_version("8.0.1")
.with_weight(-90),

View file

@ -14,10 +14,7 @@ impl PackageTrait for Inception {
impl ThemeTrait for Inception {
fn after_prepare_body(&self, page: &mut Page) {
page.set_assets(AssetsOp::SetFavicon(Some(
Favicon::new().with_icon("/base/favicon.ico"),
)))
.set_assets(AssetsOp::AddStyleSheet(
page.set_assets(AssetsOp::AddStyleSheet(
StyleSheet::from("/base/css/normalize.min.css")
.with_version("8.0.1")
.with_weight(-90),

View file

@ -1,12 +1,12 @@
use crate::base::component::add_base_assets;
use crate::concat_string;
use crate::core::component::AnyOp;
use crate::core::theme::all::{theme_by_short_name, THEME_DEFAULT};
use crate::core::theme::all::{theme_by_short_name, DEFAULT_THEME};
use crate::core::theme::{ComponentsInRegions, ThemeRef};
use crate::global::TypeInfo;
use crate::html::{html, Markup};
use crate::html::{Assets, Favicon, JavaScript, StyleSheet};
use crate::locale::{LanguageIdentifier, LANGID_DEFAULT};
use crate::locale::{LanguageIdentifier, DEFAULT_LANGID};
use crate::service::HttpRequest;
use std::collections::HashMap;
@ -68,8 +68,8 @@ impl Context {
pub(crate) fn new(request: HttpRequest) -> Self {
Context {
request,
langid : &LANGID_DEFAULT,
theme : *THEME_DEFAULT,
langid : &DEFAULT_LANGID,
theme : *DEFAULT_THEME,
layout : "default",
favicon : None,
stylesheet: Assets::<StyleSheet>::new(),
@ -86,7 +86,7 @@ impl Context {
self.langid = langid;
}
AssetsOp::Theme(theme_name) => {
self.theme = theme_by_short_name(theme_name).unwrap_or(*THEME_DEFAULT);
self.theme = theme_by_short_name(theme_name).unwrap_or(*DEFAULT_THEME);
}
AssetsOp::Layout(layout) => {
self.layout = layout;

View file

@ -5,7 +5,7 @@ use crate::{global, service, static_files, static_files_service, trace};
use std::sync::{LazyLock, RwLock};
static_files!(base);
static_files!(assets);
// PACKAGES ****************************************************************************************
@ -21,14 +21,12 @@ pub fn register_packages(root_package: Option<PackageRef>) {
// Initialize a list for packages to be enabled.
let mut enabled_list: Vec<PackageRef> = Vec::new();
// Add default theme to the enabled list.
add_to_enabled(&mut enabled_list, &crate::base::theme::Basic);
// Add default welcome page package to the enabled list.
add_to_enabled(&mut enabled_list, &crate::base::package::Welcome);
// Add default theme packages to the enabled list.
add_to_enabled(&mut enabled_list, &crate::base::theme::Basic);
add_to_enabled(&mut enabled_list, &crate::base::theme::Chassis);
add_to_enabled(&mut enabled_list, &crate::base::theme::Inception);
// If a root package is provided, add it to the enabled list.
if let Some(package) = root_package {
add_to_enabled(&mut enabled_list, package);
@ -130,12 +128,12 @@ pub fn init_packages() {
// CONFIGURE SERVICES ******************************************************************************
pub fn configure_services(scfg: &mut service::web::ServiceConfig) {
static_files_service!(
scfg,
base => "/base",
[&global::SETTINGS.dev.pagetop_project_dir, "static/base"]
);
for m in ENABLED_PACKAGES.read().unwrap().iter() {
m.configure_service(scfg);
}
static_files_service!(
scfg,
assets => "/",
[&global::SETTINGS.dev.pagetop_project_dir, "static/assets"]
);
}

View file

@ -9,10 +9,10 @@ pub static THEMES: LazyLock<RwLock<Vec<ThemeRef>>> = LazyLock::new(|| RwLock::ne
// DEFAULT THEME ***********************************************************************************
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 => &crate::base::theme::Inception,
None => &crate::base::theme::Basic,
});
// THEME BY NAME ***********************************************************************************

View file

@ -1,7 +1,7 @@
use crate::base::component::*;
use crate::core::component::{AssetsOp, ComponentBase, ComponentTrait};
use crate::core::component::{ComponentBase, ComponentTrait};
use crate::core::package::PackageTrait;
use crate::html::{html, Favicon, PrepareMarkup};
use crate::html::{html, PrepareMarkup};
use crate::locale::L10n;
use crate::response::page::Page;
use crate::{concat_string, global};
@ -69,11 +69,8 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
})
}
fn after_prepare_body(&self, page: &mut Page) {
page.set_assets(AssetsOp::SetFaviconIfNone(
Favicon::new().with_icon("/base/favicon.ico"),
));
}
#[allow(unused_variables)]
fn after_prepare_body(&self, page: &mut Page) {}
fn prepare_head(&self, page: &mut Page) -> PrepareMarkup {
let viewport = "width=device-width, initial-scale=1, shrink-to-fit=no";

View file

@ -1,5 +1,5 @@
use crate::html::assets::AssetsTrait;
use crate::html::{html, Markup};
use crate::html::{html, Markup, PreEscaped};
use crate::{concat_string, AutoDefault, Weight};
#[derive(AutoDefault)]
@ -47,7 +47,7 @@ impl AssetsTrait for StyleSheet {
media=[self.media];
},
Source::Inline(_, code) => html! {
styles { (code) };
style { (PreEscaped(code)) };
},
}
}

View file

@ -98,7 +98,7 @@ pub type Weight = i8;
// Global settings, functions and macro helpers.
pub mod global;
static_locales!(LOCALES_PAGETOP);
include_locales!(LOCALES_PAGETOP);
// *************************************************************************************************
// PUBLIC API.

View file

@ -114,13 +114,13 @@ static LANGUAGES: LazyLock<HashMap<String, (LanguageIdentifier, &str)>> = LazyLo
]
});
pub static LANGID_FALLBACK: LazyLock<LanguageIdentifier> = LazyLock::new(|| langid!("en-US"));
static FALLBACK_LANGID: LazyLock<LanguageIdentifier> = LazyLock::new(|| langid!("en-US"));
/// 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> = LazyLock::new(|| {
langid_for(global::SETTINGS.app.language.as_str()).unwrap_or(&LANGID_FALLBACK)
pub static DEFAULT_LANGID: LazyLock<&LanguageIdentifier> = LazyLock::new(|| {
langid_for(global::SETTINGS.app.language.as_str()).unwrap_or(&FALLBACK_LANGID)
});
pub fn langid_for(language: impl Into<String>) -> Result<&'static LanguageIdentifier, String> {
@ -129,7 +129,7 @@ pub fn langid_for(language: impl Into<String>) -> Result<&'static LanguageIdenti
Some((langid, _)) => Ok(langid),
None => {
if language.is_empty() {
Ok(&LANGID_FALLBACK)
Ok(&FALLBACK_LANGID)
} else {
Err(format!(
"No langid for Unicode Language Identifier \"{language}\".",
@ -141,7 +141,7 @@ pub fn langid_for(language: impl Into<String>) -> Result<&'static LanguageIdenti
#[macro_export]
/// Defines a set of localization elements and local translation texts.
macro_rules! static_locales {
macro_rules! include_locales {
( $LOCALES:ident $(, $core_locales:literal)? ) => {
$crate::locale::fluent_templates::static_loader! {
static $LOCALES = {
@ -241,6 +241,10 @@ impl L10n {
}
}
pub fn markup(&self) -> Markup {
PreEscaped(self.using(&DEFAULT_LANGID).unwrap_or_default())
}
pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup {
PreEscaped(self.using(langid).unwrap_or_default())
}
@ -259,16 +263,16 @@ impl fmt::Display for L10n {
if self.args.is_empty() {
locales.lookup(
match key.as_str() {
LANGUAGE_SET_FAILURE => &LANGID_FALLBACK,
_ => &LANGID_DEFAULT,
LANGUAGE_SET_FAILURE => &FALLBACK_LANGID,
_ => &DEFAULT_LANGID,
},
key,
)
} else {
locales.lookup_with_args(
match key.as_str() {
LANGUAGE_SET_FAILURE => &LANGID_FALLBACK,
_ => &LANGID_DEFAULT,
LANGUAGE_SET_FAILURE => &FALLBACK_LANGID,
_ => &DEFAULT_LANGID,
},
key,
&self

View file

@ -0,0 +1,5 @@
english = English
english_british = English (British)
english_united_states = English (United States)
spanish = Spanish
spanish_spain = Spanish (Spain)

View file

@ -1,26 +1,23 @@
welcome_package_name = Default homepage
welcome_package_description = Displays a demo homepage when none is configured.
welcome_package_description = Displays a landing page 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 installation of { $app }.
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_text1 = If you can read this page, it means that the <strong>PageTop</strong> server is working properly, but has not yet been configured.
welcome_pagetop_text2 = <strong>PageTop</strong> 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 <strong>PageTop</strong>, 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 <strong>{ $app }</strong>, please refer to its official repository or support channel, rather than directly to <strong>PageTop</strong>.
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 = Coding is creating

View file

@ -0,0 +1,5 @@
english = Inglés
english_british = Inglés (Gran Bretaña)
english_united_states = Inglés (Estados Unidos)
spanish = Español
spanish_spain = Español (España)

View file

@ -1,26 +1,23 @@
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_package_description = Muestra una página de inicio 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 la instalación de { $app }.
welcome_powered = Una solución web creada con { $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 por qué se muestra 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 <strong>PageTop</strong> funciona correctamente, pero aún no se ha configurado.
welcome_pagetop_text2 = <strong>PageTop</strong> 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 <strong>PageTop</strong> 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 <strong>{ $app }</strong>, por favor acude a su repositorio oficial o canal de soporte, y no al de <strong>PageTop</strong> 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 = Programar es crear

View file

@ -16,7 +16,7 @@ pub use crate::config_defaults;
// crate::html
pub use crate::html;
// crate::locale
pub use crate::static_locales;
pub use crate::include_locales;
// crate::service
pub use crate::{static_files, static_files_service};
// crate::core::action