1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*!
<div align="center">
<img src="https://git.cillero.es/manuelcillero/pagetop/raw/branch/main/static/banner.png" />
<h1>PageTop</h1>
<p>Un entorno para el desarrollo de soluciones web modulares, extensibles y configurables.</p>
[](https://docs.rs/pagetop)
[](https://crates.io/crates/pagetop)
[](https://crates.io/crates/pagetop)
[](https://git.cillero.es/manuelcillero/pagetop#licencia)
<br>
</div>
PageTop reivindica la esencia de la web clásica usando [Rust](https://www.rust-lang.org/es) para la
creación de soluciones web SSR (*renderizadas en el servidor*) basadas en HTML, CSS y JavaScript.
Ofrece un conjunto de herramientas que los desarrolladores pueden implementar, extender o adaptar
según las necesidades de cada proyecto, incluyendo:
* **Acciones** (*actions*): alteran la lógica interna de una funcionalidad interceptando su flujo
de ejecución.
* **Componentes** (*components*): encapsulan HTML, CSS y JavaScript en unidades funcionales,
configurables y reutilizables.
* **Extensiones** (*extensions*): añaden, extienden o personalizan funcionalidades usando las APIs
de PageTop o de terceros.
* **Temas** (*themes*): son extensiones que permiten modificar la apariencia de páginas y
componentes.
# ⚡️ Guía rápida
La aplicación más sencilla de PageTop se ve así:
```rust,no_run
use pagetop::prelude::*;
#[pagetop::main]
async fn main() -> std::io::Result<()> {
Application::new().run()?.await
}
```
Este código arranca el servidor de PageTop. Con la configuración por defecto, muestra una página de
bienvenida accesible desde un navegador local en la dirección `http://localhost:8080`.
Para personalizar el servicio, se puede crear una extensión de PageTop de la siguiente manera:
```rust,no_run
use pagetop::prelude::*;
struct HelloWorld;
impl Extension for HelloWorld {
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
scfg.route("/", service::web::get().to(hello_world));
}
}
async fn hello_world(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
Page::new(request)
.with_child(Html::with(|_| html! { h1 { "Hello World!" } }))
.render()
}
#[pagetop::main]
async fn main() -> std::io::Result<()> {
Application::prepare(&HelloWorld).run()?.await
}
```
Este programa implementa una extensión llamada `HelloWorld` que sirve una página web en la ruta raíz
(`/`) mostrando el texto "Hello world!" dentro de un elemento HTML `<h1>`.
# 🧩 Gestión de Dependencias
Los proyectos que utilizan PageTop gestionan las dependencias con `cargo`, como cualquier otro
proyecto en Rust.
Sin embargo, es fundamental que cada extensión declare explícitamente sus
[dependencias](core::extension::Extension::dependencies), si las tiene, para que PageTop pueda
estructurar e inicializar la aplicación de forma modular.
*/
// Alias para que las rutas absolutas `::pagetop::...` generadas por las macros funcionen en el
// propio *crate*, en *crates* externos y en *doctests*.
extern crate self as pagetop;
use HashMap;
use Deref;
// **< RE-EXPORTED >********************************************************************************
/// Versión del *crate* `pagetop`, obtenida en tiempo de compilación (`CARGO_PKG_VERSION`).
///
/// Útil para versionar recursos estáticos de PageTop desde otros *crates*. Por ejemplo:
///
/// ```rust
/// use pagetop::prelude::*;
///
/// pub struct MyTheme;
///
/// impl Extension for MyTheme {
/// fn theme(&self) -> Option<ThemeRef> {
/// Some(&Self)
/// }
/// }
///
/// impl Theme for MyTheme {
/// fn before_render_page_body(&self, page: &mut Page) {
/// page
/// .alter_assets(AssetsOp::AddStyleSheet(
/// StyleSheet::from("/css/normalize.css").with_version("8.0.1"),
/// ))
/// .alter_assets(AssetsOp::AddStyleSheet(
/// StyleSheet::from("/css/basic.css").with_version(PAGETOP_VERSION),
/// ))
/// .alter_assets(AssetsOp::AddStyleSheet(
/// StyleSheet::from("/mytheme/styles.css").with_version(env!("CARGO_PKG_VERSION")),
/// ));
/// }
/// }
/// ```
/// Donde `PAGETOP_VERSION` identifica la versión de PageTop y `env!("CARGO_PKG_VERSION")` hace
/// referencia a la versión del *crate* que lo usa.
pub const PAGETOP_VERSION: &str = env!;
pub use ;
pub use ;
pub use Getters;
/// Contenedor para un conjunto de recursos embebidos.
/// Alias para `Cow<'static, str>`.
///
/// Es un puntero inteligente con semántica *copy-on-write* para cadenas. Permite reutilizar
/// literales estáticos sin asignación de memoria adicional y, al mismo tiempo, aceptar cadenas
/// dinámicas representadas como `String`.
pub type CowStr = Cow;
/// Identificador único de un tipo estático durante la ejecución de la aplicación.
///
/// **Nota:** El valor es único sólo dentro del proceso actual y cambia en cada compilación.
pub type UniqueId = TypeId;
/// Representa el peso lógico de una instancia en una colección ordenada por pesos.
///
/// Las instancias con pesos **más bajos**, incluyendo valores negativos (`-128..127`), se situarán
/// antes en la ordenación.
pub type Weight = i8;
// **< API >****************************************************************************************
// Macros y funciones útiles.
// Carga las opciones de configuración.
// Opciones de configuración globales.
// Gestión de trazas y registro de eventos de la aplicación.
// HTML en código.
// Localización.
// Soporte a fechas y horas.
// Tipos y funciones esenciales para crear acciones, componentes, extensiones y temas.
// Respuestas a peticiones web en sus diferentes formatos.
// Gestión del servidor y servicios web.
// Reúne acciones, componentes, extensiones y temas predefinidos.
// Prepara y ejecuta la aplicación.
// **< PRELUDE >************************************************************************************