diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 48fe96bf..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,130 +0,0 @@ -# Guía de contribución a PageTop - -Gracias por tu interés en contribuir a **PageTop** 🎉 - -Este documento describe **cómo participar en el desarrollo del proyecto**, el flujo de trabajo y las -normas que permitan garantizar un historial limpio, trazable y sostenible a largo plazo. - -Por favor, léelo completo antes de abrir una *issue* o una *pull request*. - - -## 1. Repositorios - -PageTop mantiene **un único repositorio oficial**: - - * **Repositorio oficial:** https://git.cillero.es/manuelcillero/pagetop - * **Repositorio espejo:** https://github.com/manuelcillero/pagetop - -> ⚠️ **Importante** -> Aunque GitHub permite abrir *issues* y *pull requests*, **la integración del código se realiza -> únicamente en el repositorio oficial**. GitHub actúa como repositorio espejo que se sincroniza -> automáticamente para reflejar el mismo estado. - - -## 2. Issues (incidencias, propuestas, preguntas) - -Antes de abrir una *issue* **en GitHub**: - - * comprueba que no exista ya una similar, - * describe claramente el problema o propuesta, - * incluye pasos de reproducción si se trata de un *bug*, - * indica versión, entorno y contexto cuando sea relevante. - -Las *issues* se usan para: - - * informar de errores, - * propuestas de mejora, - * discusión técnica previa a cambios relevantes. - - -## 3. Pull Requests (PRs) - -### 3.1 Dónde abrirlas - -Las *pull requests* se abren **en GitHub**, normalmente contra la rama `main`. GitHub es el punto de -entrada recomendado para contribuciones externas. - -### 3.2 Reglas generales para PRs - - * Cada PR debe abordar **un único objetivo claro**. - * Mantén el alcance lo más acotado posible. - * Incluye descripción clara del cambio. - * Si el PR corrige una *issue*, enlázala explícitamente. - * Asegúrate de que el código compila y pasa las pruebas. - -### 3.3 Revisión y aceptación - -Todas las PRs son **revisadas manualmente** y pueden recibir comentarios o solicitudes de cambios. - -Las PRs aceptadas se integran en el repositorio oficial, nunca directamente en GitHub, preservando -siempre la **autoría original** del contribuidor. - - -### 3.4. Cierre de Pull Requests y sincronización - -Una vez que el cambio ha sido integrado en el repositorio oficial: - - * La PR en GitHub se **cierra manualmente**. - * Se añade un **mensaje estándar de cierre** indicando que el cambio ha sido integrado. - * El repositorio de GitHub **se sincroniza automáticamente** como espejo. - - -## 4. Estilo de código y calidad - - * Sigue el estilo existente del proyecto. - * Mantén los comentarios claros y precisos. - * La documentación es parte del código: actualízala cuando sea necesario. - * Cambios públicos o estructurales deben ir acompañados de documentación. - - -## 5. Commits - -PageTop usa la especificación **gitmoji** para los mensajes de *commit*. El formato recomendado es: - - ```text - [(ámbito opcional):] - «LÍNEA EN BLANCO» - Cuerpo opcional - «LÍNEA EN BLANCO» - Nota(s) al pie opcional(es) para referencias, incidencias o cambios incompatibles - ``` - -Ejemplos (no más de 50 caracteres en la primera línea, y no más de 80 en el resto): - - * `📝 Actualiza la guía de contribución` - * `♻️ (locale): Refactoriza sistema de localización` - * Un mensaje completo: - ``` - 🎨 (bootsier): Mejora la asignación de clases - - - Simplifica la generación de clases CSS para componentes Bootstrap. - - Elimina duplicidades en enums de estilos y centraliza la lógica de composición - para reducir errores y facilitar mantenimiento. - - Alinea los nombres de variantes con la documentación pública. - - Refs: PR #123 - ``` - -El emoji puede usarse en formato Unicode o como *shortcode*, por ejemplo `:sparkles:` en vez de ✨. - -Consulta la especificación oficial en https://gitmoji.dev/specification - -Durante la integración, los *commits* pueden ajustarse para adaptarse al historial del proyecto. - -Un *commit* debe representar una unidad lógica de cambio. Usa mensajes claros y descriptivos. - - -## 6. Comunicación y respeto - -PageTop sigue un enfoque profesional y colaborativo: - - * Sé respetuoso en revisiones y discusiones. - * Acepta sugerencias técnicas como parte del proceso. - * Recuerda que todas las contribuciones son revisadas con el objetivo de mejorar el proyecto. - -Si tienes dudas sobre el proceso, abre una *issue* de tipo pregunta para tratar la cuestión en -comunidad. - ---- - -Gracias por contribuir a **PageTop** 🚀 Cada aportación contribuye a mejorar el proyecto. diff --git a/Cargo.lock b/Cargo.lock index 16b0fd66..2f9fa42e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -982,17 +982,6 @@ dependencies = [ "wasi 0.14.7+wasi-0.2.4", ] -[[package]] -name = "getter-methods" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43d815f896a3c730f0d76b8348a1700dc8d8fd6c377e4590d531bdd646574d8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "ghash" version = "0.5.1" @@ -1084,9 +1073,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "hkdf" @@ -1290,22 +1279,19 @@ checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" [[package]] name = "indexmap" -version = "2.12.1" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.16.0", ] [[package]] name = "indoc" -version = "2.0.7" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" -dependencies = [ - "rustversion", -] +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" [[package]] name = "inout" @@ -1568,19 +1554,19 @@ dependencies = [ "actix-web", "chrono", "colored", + "concat-string", "config", "figlet-rs", "fluent-templates", - "getter-methods", - "indexmap", + "indoc", "itoa", "pagetop-aliner", "pagetop-bootsier", "pagetop-build", "pagetop-macros", - "pagetop-minimal", "pagetop-statics", "parking_lot", + "pastey", "serde", "serde_json", "substring", @@ -1628,15 +1614,6 @@ dependencies = [ "syn", ] -[[package]] -name = "pagetop-minimal" -version = "0.0.10" -dependencies = [ - "concat-string", - "indoc", - "pastey", -] - [[package]] name = "pagetop-statics" version = "0.1.2" @@ -1674,9 +1651,9 @@ dependencies = [ [[package]] name = "pastey" -version = "0.2.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d6c094ee800037dff99e02cab0eaf3142826586742a270ab3d7a62656bd27a" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" [[package]] name = "path-matchers" diff --git a/Cargo.toml b/Cargo.toml index a801b786..b1bae0a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,12 +17,13 @@ authors.workspace = true [dependencies] chrono = "0.4" colored = "3.0" +concat-string = "1.0" config = { version = "0.15", default-features = false, features = ["toml"] } figlet-rs = "0.1" -getter-methods = "2.0" +indoc = "2.0" itoa = "1.0" -indexmap = "2.12" parking_lot = "0.12" +paste = { package = "pastey", version = "0.1" } substring = "1.4" terminal_size = "0.4" @@ -41,7 +42,6 @@ actix-web-files = { package = "actix-files", version = "0.6" } serde.workspace = true pagetop-macros.workspace = true -pagetop-minimal.workspace = true pagetop-statics.workspace = true [features] @@ -64,7 +64,6 @@ members = [ # Helpers "helpers/pagetop-build", "helpers/pagetop-macros", - "helpers/pagetop-minimal", "helpers/pagetop-statics", # Extensions "extensions/pagetop-aliner", @@ -83,7 +82,6 @@ serde = { version = "1.0", features = ["derive"] } # Helpers pagetop-build = { version = "0.3", path = "helpers/pagetop-build" } pagetop-macros = { version = "0.2", path = "helpers/pagetop-macros" } -pagetop-minimal = { version = "0.0", path = "helpers/pagetop-minimal" } pagetop-statics = { version = "0.1", path = "helpers/pagetop-statics" } # Extensions pagetop-aliner = { version = "0.0", path = "extensions/pagetop-aliner" } diff --git a/MAINTAINERS.md b/MAINTAINERS.md deleted file mode 100644 index 25559841..00000000 --- a/MAINTAINERS.md +++ /dev/null @@ -1,156 +0,0 @@ -# MAINTAINERS.md - -## Guía para mantenedores de PageTop - -Este documento describe **el flujo técnico interno de revisión e integración de contribuciones** en -**PageTop**. - -Está dirigido a **mantenedores del proyecto** y **no forma parte de la guía de contribución para -usuarios externos**. Su objetivo es servir como **referencia operativa**, garantizando coherencia, -trazabilidad y preservación de la autoría en un entorno con repositorios espejo. - - -## 1. Repositorios y principios - -PageTop mantiene **un único repositorio oficial**: - - * **Repositorio oficial:** https://git.cillero.es/manuelcillero/pagetop - * **Repositorio espejo:** https://github.com/manuelcillero/pagetop - -### Principios clave - - * El repositorio oficial **es la única fuente de verdad** del historial. - * **Nunca se realizan *merges* en GitHub**. - * Toda integración definitiva se realiza en el repositorio oficial. - * La autoría original debe preservarse siempre. - - -## 2. Configuración local recomendada - -El remoto `github` debe configurarse únicamente para operaciones de lectura (*fetch*), con la URL de -*push* deshabilitada para evitar publicaciones accidentales en el repositorio espejo. - -Estado esperado de `git remote -v`: - -```text -origin git@git.cillero.es:manuelcillero/pagetop.git (fetch) -origin git@git.cillero.es:manuelcillero/pagetop.git (push) -github git@github.com:manuelcillero/pagetop.git (fetch) -github DISABLED (push) -``` - -Convenciones usadas en este documento: - - * `origin` -> Repositorio oficial - * `github` -> Repositorio espejo - - -## 3. Recepción y revisión de Pull Requests - -Las PRs externas llegan por GitHub, normalmente contra la rama `main`. - -Se asume que el repositorio local está configurado para recuperar PRs de GitHub como referencias -remotas (`refs/pull//head`): - -```bash -git fetch github --prune -git checkout -b pr-123 github/pr/123 -``` - -Antes de integrar: - - * Revisar el código manualmente. - * Verificar formato, análisis y pruebas: - - ```bash - cargo fmt - cargo clippy - cargo test - ``` - - * Comprobar impacto en documentación. - * Evaluar coherencia con la arquitectura y el estilo del proyecto. - -Los cambios adicionales se solicitan o se aplican explicando claramente el motivo. - - -## 4. Estrategia de integración - -La integración **se realiza siempre en el repositorio oficial** (`origin`). - -### 4.1 Estrategia por defecto: *rebase* + *fast-forward* - -Esta es la **estrategia estándar y recomendada** en PageTop. Ventajas: - - * conserva los commits originales, - * preserva la autoría real de cada cambio, - * mantiene un historial lineal y trazable, - * facilita auditoría y depuración. - -Procedimiento típico: - -```bash -git checkout pr-123 -git rebase main - -# Resolver conflictos si los hay - -git checkout main -git merge --ff-only pr-123 -``` - -Si `merge --ff-only` falla, **no se debe continuar**, indica divergencias que deben resolverse antes -de integrar la PR. - -### 4.2 Estrategia excepcional: *Squash* - -Sólo debe usarse cuando esté justificado: - - * la PR contiene múltiples commits de prueba o ruido, - * el historial aportado no es significativo, - * el cambio es pequeño y autocontenido. - -En este caso, se debe **preservar explícitamente la autoría**: - -```bash -git checkout main -git merge --squash pr-123 -git commit --author="Nombre Apellido " -``` - - -### 4.3. Publicación en el repositorio oficial - -```bash -git push origin main -``` - -Este *push* representa la **integración definitiva** del cambio en la rama `main`. - - -## 5. Cierre de la PR y sincronización - -Tras integrar el cambio en el repositorio oficial, se cierra manualmente la PR en GitHub con un -mensaje estándar: - -```text -Gracias por tu contribución. - -Este cambio ha sido integrado en el repositorio oficial en `main` (``). -GitHub actúa como repositorio espejo sincronizado. -``` - - -## 6. Principios de mantenimiento - - * Priorizar **claridad y trazabilidad** frente a rapidez. - * Mantener un historial legible y significativo. - * Documentar cambios estructurales o públicos. - * Tratar las contribuciones externas con respeto y transparencia. - ---- - -Este documento puede evolucionar con el proyecto. - -No se trata de imponer rigidez, sino de **capturar el conocimiento operativo real** de PageTop como -guía práctica para el mantenimiento. diff --git a/README.md b/README.md index 4c421edd..9a12c845 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ según las necesidades de cada proyecto, incluyendo: componentes sin comprometer su funcionalidad. -## ⚡️ Guía rápida +# ⚡️ Guía rápida La aplicación más sencilla de PageTop se ve así: @@ -74,7 +74,7 @@ Este programa implementa una extensión llamada `HelloWorld` que sirve una pági (`/`) mostrando el texto "Hello world!" dentro de un elemento HTML `

`. -## 📂 Proyecto +# 📂 Repositorio El código se organiza en un *workspace* donde actualmente se incluyen los siguientes subproyectos: @@ -82,25 +82,21 @@ El código se organiza en un *workspace* donde actualmente se incluyen los sigui fuente de la librería principal. Reúne algunos de los *crates* más estables y populares del ecosistema Rust para proporcionar APIs y recursos para la creación avanzada de soluciones web. -### Auxiliares +## Auxiliares + + * **[pagetop-statics](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-statics)**, + es la librería que permite incluir archivos estáticos en el ejecutable de las aplicaciones + PageTop para servirlos de forma eficiente, con detección de cambios que optimizan el tiempo de + compilación. * **[pagetop-build](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-build)**, prepara los archivos estáticos o archivos SCSS compilados para incluirlos en el binario de las aplicaciones PageTop durante la compilación de los ejecutables. * **[pagetop-macros](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-macros)**, - proporciona una colección de macros procedurales que mejoran la experiencia de desarrollo con - PageTop. + proporciona una colección de macros que mejoran la experiencia de desarrollo con PageTop. - * **[pagetop-minimal](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-minimal)**, - ofrece macros declarativas esenciales para optimizar tareas comunes como la composición de - texto, la concatenación de cadenas y el manejo de colecciones clave-valor. - - * **[pagetop-statics](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/helpers/pagetop-statics)**, - permite incluir archivos estáticos en el ejecutable de las aplicaciones PageTop para servirlos - de forma eficiente, con detección de cambios que optimizan el tiempo de compilación. - -### Extensiones +## Extensiones * **[pagetop-aliner](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-aliner)**, es un tema para demos y pruebas que muestra esquemáticamente la composición de las páginas HTML. @@ -110,7 +106,7 @@ El código se organiza en un *workspace* donde actualmente se incluyen los sigui componentes flexibles. -## 🧪 Pruebas +# 🧪 Pruebas Para simplificar el flujo de trabajo, el repositorio incluye varios **alias de Cargo** declarados en `.cargo/config.toml`. Basta con ejecutarlos desde la raíz del proyecto: @@ -127,14 +123,14 @@ Para simplificar el flujo de trabajo, el repositorio incluye varios **alias de C > Si quieres **activar** las trazas del registro de eventos entonces usa simplemente `cargo test`. -## 🚧 Advertencia +# 🚧 Advertencia **PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos hasta que se libere la versión **1.0.0**. -## 📜 Licencia +# 📜 Licencia El código está disponible bajo una doble licencia: @@ -148,28 +144,7 @@ Puedes elegir la licencia que prefieras. Este enfoque de doble licencia es el es el ecosistema Rust. -## ✨ Contribuir - -PageTop mantiene **un único repositorio oficial**: - - * **Repositorio oficial:** https://git.cillero.es/manuelcillero/pagetop - * **Repositorio espejo:** https://github.com/manuelcillero/pagetop - -El repositorio de GitHub actúa como espejo y punto de entrada para: - - * dar mayor visibilidad al proyecto, - * facilitar la participación de la comunidad, - * centralizar *issues* y *pull requests* externas. - -Aunque GitHub permite abrir *pull requests*, **la integración del código se realiza únicamente en el -repositorio oficial**. El repositorio de GitHub se sincroniza posteriormente para reflejar el mismo -estado. - -En todos los casos, se respeta la **autoría original** de las contribuciones integradas, tanto en el -historial como en la documentación asociada al cambio. - -Para conocer el proceso completo de participación, revisión e integración de cambios, consulta el -archivo [`CONTRIBUTING.md`](CONTRIBUTING.md). +# ✨ Contribuir Cualquier contribución para añadir al proyecto se considerará automáticamente bajo la doble licencia indicada arriba (MIT o Apache v2.0), sin términos o condiciones adicionales, tal y como permite la diff --git a/examples/hello-name.rs b/examples/hello-name.rs index b6f9c113..c6a82aaf 100644 --- a/examples/hello-name.rs +++ b/examples/hello-name.rs @@ -14,11 +14,7 @@ async fn hello_name( ) -> ResultPage { let name = path.into_inner(); Page::new(request) - .add_child(Html::with(move |_| { - html! { - h1 style="text-align: center;" { "Hello " (name) "!" } - } - })) + .add_child(Html::with(move |_| html! { h1 { "Hello " (name) "!" } })) .render() } diff --git a/examples/hello-world.rs b/examples/hello-world.rs index 74727ac2..64817466 100644 --- a/examples/hello-world.rs +++ b/examples/hello-world.rs @@ -10,11 +10,7 @@ impl Extension for HelloWorld { async fn hello_world(request: HttpRequest) -> ResultPage { Page::new(request) - .add_child(Html::with(|_| { - html! { - h1 style="text-align: center;" { "Hello World!" } - } - })) + .add_child(Html::with(|_| html! { h1 { "Hello World!" } })) .render() } diff --git a/examples/navbar-menus.rs b/examples/navbar-menus.rs index a2ae76d0..341d394a 100644 --- a/examples/navbar-menus.rs +++ b/examples/navbar-menus.rs @@ -10,16 +10,22 @@ impl Extension for SuperMenu { } fn initialize(&self) { - let navbar_menu = Navbar::brand_left(navbar::Brand::new()) + let home_path = |cx: &Context| match cx.langid().language.as_str() { + "en" => "/en", + _ => "/", + }; + + let navbar_menu = Navbar::brand_left(navbar::Brand::new().with_path(Some(home_path))) .with_expand(BreakPoint::LG) .add_item(navbar::Item::nav( Nav::new() - .add_item(nav::Item::link(L10n::l("sample_menus_item_link"), |cx| { - cx.route("/") - })) + .add_item(nav::Item::link( + L10n::l("sample_menus_item_link"), + home_path, + )) .add_item(nav::Item::link_blank( L10n::l("sample_menus_item_blank"), - |_| "https://docs.rs/pagetop".into(), + |_| "https://docs.rs/pagetop", )) .add_item(nav::Item::dropdown( Dropdown::new() @@ -27,28 +33,28 @@ impl Extension for SuperMenu { .add_item(dropdown::Item::header(L10n::l("sample_menus_dev_header"))) .add_item(dropdown::Item::link( L10n::l("sample_menus_dev_getting_started"), - |cx| cx.route("/dev/getting-started"), + |_| "/dev/getting-started", )) .add_item(dropdown::Item::link( L10n::l("sample_menus_dev_guides"), - |cx| cx.route("/dev/guides"), + |_| "/dev/guides", )) .add_item(dropdown::Item::link_blank( L10n::l("sample_menus_dev_forum"), - |_| "https://forum.example.dev".into(), + |_| "https://forum.example.dev", )) .add_item(dropdown::Item::divider()) .add_item(dropdown::Item::header(L10n::l("sample_menus_sdk_header"))) .add_item(dropdown::Item::link( L10n::l("sample_menus_sdk_rust"), - |cx| cx.route("/dev/sdks/rust"), + |_| "/dev/sdks/rust", )) - .add_item(dropdown::Item::link(L10n::l("sample_menus_sdk_js"), |cx| { - cx.route("/dev/sdks/js") + .add_item(dropdown::Item::link(L10n::l("sample_menus_sdk_js"), |_| { + "/dev/sdks/js" })) .add_item(dropdown::Item::link( L10n::l("sample_menus_sdk_python"), - |cx| cx.route("/dev/sdks/python"), + |_| "/dev/sdks/python", )) .add_item(dropdown::Item::divider()) .add_item(dropdown::Item::header(L10n::l( @@ -56,22 +62,22 @@ impl Extension for SuperMenu { ))) .add_item(dropdown::Item::link( L10n::l("sample_menus_plugin_auth"), - |cx| cx.route("/dev/sdks/rust/plugins/auth"), + |_| "/dev/sdks/rust/plugins/auth", )) .add_item(dropdown::Item::link( L10n::l("sample_menus_plugin_cache"), - |cx| cx.route("/dev/sdks/rust/plugins/cache"), + |_| "/dev/sdks/rust/plugins/cache", )) .add_item(dropdown::Item::divider()) .add_item(dropdown::Item::label(L10n::l("sample_menus_item_label"))) .add_item(dropdown::Item::link_disabled( L10n::l("sample_menus_item_disabled"), - |cx| cx.route("#"), + |_| "#", )), )) .add_item(nav::Item::link_disabled( L10n::l("sample_menus_item_disabled"), - |cx| cx.route("#"), + |_| "#", )), )) .add_item(navbar::Item::nav( @@ -82,14 +88,14 @@ impl Extension for SuperMenu { ) .add_item(nav::Item::link( L10n::l("sample_menus_item_sign_up"), - |cx| cx.route("/auth/sign-up"), + |_| "/auth/sign-up", )) - .add_item(nav::Item::link(L10n::l("sample_menus_item_login"), |cx| { - cx.route("/auth/login") + .add_item(nav::Item::link(L10n::l("sample_menus_item_login"), |_| { + "/auth/login" })), )); - InRegion::Global(&DefaultRegion::Header).add(Child::with( + InRegion::Named("header").add(Child::with( Container::new() .with_width(container::Width::FluidMax(UnitValue::RelRem(75.0))) .add_child(navbar_menu), diff --git a/extensions/pagetop-aliner/README.md b/extensions/pagetop-aliner/README.md index f3849122..f4670aae 100644 --- a/extensions/pagetop-aliner/README.md +++ b/extensions/pagetop-aliner/README.md @@ -12,14 +12,14 @@
-## 🧭 Sobre PageTop +## Sobre PageTop [PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y configurables, basadas en HTML, CSS y JavaScript. -## ⚡️ Guía rápida +# ⚡️ Guía rápida Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`: @@ -80,14 +80,14 @@ async fn homepage(request: HttpRequest) -> ResultPage { ``` -## 🚧 Advertencia +# 🚧 Advertencia **PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos hasta que se libere la versión **1.0.0**. -## 📜 Licencia +# 📜 Licencia El código está disponible bajo una doble licencia: diff --git a/extensions/pagetop-aliner/src/lib.rs b/extensions/pagetop-aliner/src/lib.rs index 04b5ad1a..4ae4121e 100644 --- a/extensions/pagetop-aliner/src/lib.rs +++ b/extensions/pagetop-aliner/src/lib.rs @@ -104,25 +104,12 @@ impl Extension for Aliner { } impl Theme for Aliner { - fn before_render_page_body(&self, page: &mut Page) { - page.alter_assets(ContextOp::AddStyleSheet( - StyleSheet::from("/css/normalize.css") - .with_version("8.0.1") - .with_weight(-99), - )) - .alter_assets(ContextOp::AddStyleSheet( - StyleSheet::from("/css/basic.css") - .with_version(PAGETOP_VERSION) - .with_weight(-99), - )) - .alter_assets(ContextOp::AddStyleSheet( - StyleSheet::from("/aliner/css/styles.css") - .with_version(env!("CARGO_PKG_VERSION")) - .with_weight(-99), - )) - .alter_child_in( - &DefaultRegion::Footer, - ChildOp::AddIfEmpty(Child::with(PoweredBy::new())), - ); + fn after_render_page_body(&self, page: &mut Page) { + page.alter_param("include_basic_assets", true) + .alter_assets(ContextOp::AddStyleSheet( + StyleSheet::from("/aliner/css/styles.css") + .with_version(env!("CARGO_PKG_VERSION")) + .with_weight(-90), + )); } } diff --git a/extensions/pagetop-bootsier/README.md b/extensions/pagetop-bootsier/README.md index e7a3ea79..d6e1666a 100644 --- a/extensions/pagetop-bootsier/README.md +++ b/extensions/pagetop-bootsier/README.md @@ -12,14 +12,14 @@
-## 🧭 Sobre PageTop +## Sobre PageTop [PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y configurables, basadas en HTML, CSS y JavaScript. -## ⚡️ Guía rápida +# ⚡️ Guía rápida Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`: @@ -80,14 +80,14 @@ async fn homepage(request: HttpRequest) -> ResultPage { ``` -## 🚧 Advertencia +# 🚧 Advertencia **PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos hasta que se libere la versión **1.0.0**. -## 📜 Licencia +# 📜 Licencia El código está disponible bajo una doble licencia: diff --git a/extensions/pagetop-bootsier/src/lib.rs b/extensions/pagetop-bootsier/src/lib.rs index 5c88959a..0bf94f47 100644 --- a/extensions/pagetop-bootsier/src/lib.rs +++ b/extensions/pagetop-bootsier/src/lib.rs @@ -102,34 +102,6 @@ pub mod prelude { pub use crate::theme::*; } -/// Plantillas que Bootsier añade. -#[derive(AutoDefault)] -pub enum BootsierTemplate { - /// Plantilla predeterminada de Bootsier. - #[default] - Standard, -} - -impl Template for BootsierTemplate { - fn render(&'static self, cx: &mut Context) -> Markup { - match self { - Self::Standard => theme::Container::new() - .with_classes(ClassesOp::Add, "container-wrapper") - .with_width(theme::container::Width::FluidMax( - config::SETTINGS.bootsier.max_width, - )) - .add_child(Html::with(|cx| { - html! { - (DefaultRegion::Header.render(cx)) - (DefaultRegion::Content.render(cx)) - (DefaultRegion::Footer.render(cx)) - } - })), - } - .render(cx) - } -} - /// Implementa el tema. pub struct Bootsier; @@ -145,12 +117,7 @@ impl Extension for Bootsier { } impl Theme for Bootsier { - #[inline] - fn default_template(&self) -> TemplateRef { - &BootsierTemplate::Standard - } - - fn before_render_page_body(&self, page: &mut Page) { + fn after_render_page_body(&self, page: &mut Page) { page.alter_assets(ContextOp::AddStyleSheet( StyleSheet::from("/bootsier/bs/bootstrap.min.css") .with_version(BOOTSTRAP_VERSION) @@ -160,10 +127,6 @@ impl Theme for Bootsier { JavaScript::defer("/bootsier/js/bootstrap.bundle.min.js") .with_version(BOOTSTRAP_VERSION) .with_weight(-90), - )) - .alter_child_in( - &DefaultRegion::Footer, - ChildOp::AddIfEmpty(Child::with(PoweredBy::new())), - ); + )); } } diff --git a/extensions/pagetop-bootsier/src/locale/en-US/bootsier.ftl b/extensions/pagetop-bootsier/src/locale/en-US/bootsier.ftl index 2454c84e..0e8969cd 100644 --- a/extensions/pagetop-bootsier/src/locale/en-US/bootsier.ftl +++ b/extensions/pagetop-bootsier/src/locale/en-US/bootsier.ftl @@ -1,5 +1,5 @@ -e404_description = Oops! Page Not Found -e404_message = The page you are looking for may have been removed, had its name changed, or is temporarily unavailable. -e500_description = Oops! Unexpected Error -e500_message = We're having an issue. Please report this error to an administrator. -back_homepage = Back to homepage +e404-description = Oops! Page Not Found +e404-message = The page you are looking for may have been removed, had its name changed, or is temporarily unavailable. +e500-description = Oops! Unexpected Error +e500-message = We're having an issue. Please report this error to an administrator. +back-homepage = Back to homepage diff --git a/extensions/pagetop-bootsier/src/locale/en-US/components.ftl b/extensions/pagetop-bootsier/src/locale/en-US/components.ftl index c73478bf..e3b0d6e6 100644 --- a/extensions/pagetop-bootsier/src/locale/en-US/components.ftl +++ b/extensions/pagetop-bootsier/src/locale/en-US/components.ftl @@ -1,11 +1,8 @@ # Dropdown dropdown_toggle = Toggle Dropdown -# form::Input -input_required = This field is required +# Offcanvas +offcanvas_close = Close # Navbar toggle = Toggle navigation - -# Offcanvas -offcanvas_close = Close diff --git a/extensions/pagetop-bootsier/src/locale/en-US/regions.ftl b/extensions/pagetop-bootsier/src/locale/en-US/regions.ftl index af830a4e..f3b76e22 100644 --- a/extensions/pagetop-bootsier/src/locale/en-US/regions.ftl +++ b/extensions/pagetop-bootsier/src/locale/en-US/regions.ftl @@ -1,9 +1,9 @@ -region_header = Header -region_nav_branding = Navigation branding region -region_nav_main = Main navigation region -region_nav_additional = Additional navigation region (eg search form, social icons, etc) -region_breadcrumb = Breadcrumb -region_content = Main content -region_sidebar_first = Sidebar first -region_sidebar_second = Sidebar second -region_footer = Footer +header = Header +nav_branding = Navigation branding region +nav_main = Main navigation region +nav_additional = Additional navigation region (eg search form, social icons, etc) +breadcrumb = Breadcrumb +content = Main content +sidebar_first = Sidebar first +sidebar_second = Sidebar second +footer = Footer diff --git a/extensions/pagetop-bootsier/src/locale/es-ES/bootsier.ftl b/extensions/pagetop-bootsier/src/locale/es-ES/bootsier.ftl index bd97c2ed..998b54f2 100644 --- a/extensions/pagetop-bootsier/src/locale/es-ES/bootsier.ftl +++ b/extensions/pagetop-bootsier/src/locale/es-ES/bootsier.ftl @@ -1,5 +1,5 @@ -e404_description = ¡Vaya! Página No Encontrada -e404_message = La página que está buscando puede haber sido eliminada, cambiada de nombre o no está disponible temporalmente. -e500_description = ¡Vaya! Error Inesperado -e500_message = Está ocurriendo una incidencia. Por favor, informe de este error a un administrador. -back_homepage = Volver al inicio +e404-description = ¡Vaya! Página No Encontrada +e404-message = La página que está buscando puede haber sido eliminada, cambiada de nombre o no está disponible temporalmente. +e500-description = ¡Vaya! Error Inesperado +e500-message = Está ocurriendo una incidencia. Por favor, informe de este error a un administrador. +back-homepage = Volver al inicio diff --git a/extensions/pagetop-bootsier/src/locale/es-ES/components.ftl b/extensions/pagetop-bootsier/src/locale/es-ES/components.ftl index 21b52c91..ab7ff687 100644 --- a/extensions/pagetop-bootsier/src/locale/es-ES/components.ftl +++ b/extensions/pagetop-bootsier/src/locale/es-ES/components.ftl @@ -1,11 +1,8 @@ # Dropdown dropdown_toggle = Mostrar/ocultar menú -# form::Input -input_required = Este campo es obligatorio +# Offcanvas +offcanvas_close = Cerrar # Navbar toggle = Mostrar/ocultar navegación - -# Offcanvas -offcanvas_close = Cerrar diff --git a/extensions/pagetop-bootsier/src/locale/es-ES/regions.ftl b/extensions/pagetop-bootsier/src/locale/es-ES/regions.ftl index e4665add..674fc4b1 100644 --- a/extensions/pagetop-bootsier/src/locale/es-ES/regions.ftl +++ b/extensions/pagetop-bootsier/src/locale/es-ES/regions.ftl @@ -1,9 +1,9 @@ -region_header = Cabecera -region_nav_branding = Navegación y marca -region_nav_main = Navegación principal -region_nav_additional = Navegación adicional (p.e. formulario de búsqueda, iconos sociales, etc.) -region_breadcrumb = Ruta de posicionamiento -region_content = Contenido principal -region_sidebar_first = Barra lateral primera -region_sidebar_second = Barra lateral segunda -region_footer = Pie +header = Cabecera +nav_branding = Navegación y marca +nav_main = Navegación principal +nav_additional = Navegación adicional (p.e. formulario de búsqueda, iconos sociales, etc.) +breadcrumb = Ruta de posicionamiento +content = Contenido principal +sidebar_first = Barra lateral primera +sidebar_second = Barra lateral segunda +footer = Pie diff --git a/extensions/pagetop-bootsier/src/theme.rs b/extensions/pagetop-bootsier/src/theme.rs index 7464caf5..2c6b5757 100644 --- a/extensions/pagetop-bootsier/src/theme.rs +++ b/extensions/pagetop-bootsier/src/theme.rs @@ -19,11 +19,6 @@ pub mod dropdown; #[doc(inline)] pub use dropdown::Dropdown; -// Form. -pub mod form; -#[doc(inline)] -pub use form::Form; - // Image. pub mod image; #[doc(inline)] diff --git a/extensions/pagetop-bootsier/src/theme/aux/border.rs b/extensions/pagetop-bootsier/src/theme/aux/border.rs index 44d24b0e..43882767 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/border.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/border.rs @@ -22,7 +22,7 @@ impl BorderColor { const BORDER: &str = "border"; const BORDER_PREFIX: &str = "border-"; - /// Devuelve el sufijo de la clase `border-*`, o `None` si no define ninguna clase. + // Devuelve el sufijo de la clase `border-*`, o `None` si no define ninguna clase. #[rustfmt::skip] #[inline] const fn suffix(self) -> Option<&'static str> { @@ -35,7 +35,7 @@ impl BorderColor { } } - /// Añade la clase `border-*` a la cadena de clases. + // Añade la clase `border-*` a la cadena de clases. #[inline] pub(crate) fn push_class(self, classes: &mut String) { if let Some(suffix) = self.suffix() { @@ -64,6 +64,7 @@ impl BorderColor { /// assert_eq!(BorderColor::Black.to_class(), "border-black"); /// assert_eq!(BorderColor::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { if let Some(suffix) = self.suffix() { let base_len = match self { diff --git a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs b/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs index 992f8525..4d9a7626 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs @@ -19,7 +19,7 @@ pub enum BreakPoint { } impl BreakPoint { - /// Devuelve la identificación del punto de ruptura. + // Devuelve la identificación del punto de ruptura. #[rustfmt::skip] #[inline] pub(crate) const fn as_str(self) -> &'static str { @@ -33,11 +33,11 @@ impl BreakPoint { } } - /// Añade el punto de ruptura con un prefijo y un sufijo (opcional) separados por un guion `-` a - /// la cadena de clases. - /// - /// - Para `None` - `prefix` o `prefix-suffix` (si `suffix` no está vacío). - /// - Para `SM..XXL` - `prefix-{breakpoint}` o `prefix-{breakpoint}-{suffix}`. + // Añade el punto de ruptura con un prefijo y un sufijo (opcional) separados por un guion `-` a + // la cadena de clases. + // + // - Para `None` - `prefix` o `prefix-suffix` (si `suffix` no está vacío). + // - Para `SM..XXL` - `prefix-{breakpoint}` o `prefix-{breakpoint}-{suffix}`. #[inline] pub(crate) fn push_class(self, classes: &mut String, prefix: &str, suffix: &str) { if prefix.is_empty() { @@ -60,30 +60,30 @@ impl BreakPoint { } } - /// Devuelve la clase para el punto de ruptura, con un prefijo y un sufijo opcional, separados - /// por un guion `-`. - /// - /// - Para `None` - `prefix` o `prefix-suffix` (si `suffix` no está vacío). - /// - Para `SM..XXL` - `prefix-{breakpoint}` o `prefix-{breakpoint}-{suffix}`. - /// - Si `prefix` está vacío devuelve `""`. - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// let bp = BreakPoint::MD; - /// assert_eq!(bp.class_with("col", ""), "col-md"); - /// assert_eq!(bp.class_with("col", "6"), "col-md-6"); - /// - /// let bp = BreakPoint::None; - /// assert_eq!(bp.class_with("offcanvas", ""), "offcanvas"); - /// assert_eq!(bp.class_with("col", "12"), "col-12"); - /// - /// let bp = BreakPoint::LG; - /// assert_eq!(bp.class_with("", "3"), ""); - /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str, suffix: &str) -> String { + // Devuelve la clase para el punto de ruptura, con un prefijo y un sufijo opcional, separados + // por un guion `-`. + // + // - Para `None` - `prefix` o `prefix-suffix` (si `suffix` no está vacío). + // - Para `SM..XXL` - `prefix-{breakpoint}` o `prefix-{breakpoint}-{suffix}`. + // - Si `prefix` está vacío devuelve `""`. + // + // # Ejemplos + // + // ```rust + // # use pagetop_bootsier::prelude::*; + // let bp = BreakPoint::MD; + // assert_eq!(bp.class_with("col", ""), "col-md"); + // assert_eq!(bp.class_with("col", "6"), "col-md-6"); + // + // let bp = BreakPoint::None; + // assert_eq!(bp.class_with("offcanvas", ""), "offcanvas"); + // assert_eq!(bp.class_with("col", "12"), "col-12"); + // + // let bp = BreakPoint::LG; + // assert_eq!(bp.class_with("", "3"), ""); + // ``` + #[inline] + pub(crate) fn class_with(self, prefix: &str, suffix: &str) -> String { if prefix.is_empty() { return String::new(); } diff --git a/extensions/pagetop-bootsier/src/theme/aux/button.rs b/extensions/pagetop-bootsier/src/theme/aux/button.rs index b32bd17d..0d1df87d 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/button.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/button.rs @@ -23,7 +23,7 @@ impl ButtonColor { const BTN_OUTLINE_PREFIX: &str = "btn-outline-"; const BTN_LINK: &str = "btn-link"; - /// Añade la clase `btn-*` a la cadena de clases. + // Añade la clase `btn-*` a la cadena de clases. #[inline] pub(crate) fn push_class(self, classes: &mut String) { if let Self::Default = self { @@ -65,6 +65,7 @@ impl ButtonColor { /// assert_eq!(ButtonColor::Link.to_class(), "btn-link"); /// assert_eq!(ButtonColor::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { match self { Self::Default => String::new(), @@ -105,7 +106,7 @@ impl ButtonSize { const BTN_SM: &str = "btn-sm"; const BTN_LG: &str = "btn-lg"; - /// Añade la clase de tamaño `btn-sm` o `btn-lg` a la cadena de clases. + // Añade la clase de tamaño `btn-sm` o `btn-lg` a la cadena de clases. #[inline] pub(crate) fn push_class(self, classes: &mut String) { if let Self::Default = self { @@ -131,6 +132,7 @@ impl ButtonSize { /// assert_eq!(ButtonSize::Large.to_class(), "btn-lg"); /// assert_eq!(ButtonSize::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { match self { Self::Default => String::new(), diff --git a/extensions/pagetop-bootsier/src/theme/aux/color.rs b/extensions/pagetop-bootsier/src/theme/aux/color.rs index f49c36b6..480ff3d8 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/color.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/color.rs @@ -23,7 +23,7 @@ pub enum Color { } impl Color { - /// Devuelve el nombre del color. + // Devuelve el nombre del color. #[rustfmt::skip] #[inline] pub(crate) const fn as_str(self) -> &'static str { @@ -94,7 +94,7 @@ impl Opacity { const OPACITY: &str = "opacity"; const OPACITY_PREFIX: &str = "-opacity"; - /// Devuelve el sufijo para `*opacity-*`, o `None` si no define ninguna clase. + // Devuelve el sufijo para `*opacity-*`, o `None` si no define ninguna clase. #[rustfmt::skip] #[inline] const fn suffix(self) -> Option<&'static str> { @@ -109,8 +109,8 @@ impl Opacity { } } - /// Añade la opacidad a la cadena de clases usando el prefijo dado (`bg`, `border`, `text`, o - /// vacío para `opacity-*`). + // Añade la opacidad a la cadena de clases usando el prefijo dado (`bg`, `border`, `text`, o + // vacío para `opacity-*`). #[inline] pub(crate) fn push_class(self, classes: &mut String, prefix: &str) { if let Some(suffix) = self.suffix() { @@ -127,20 +127,20 @@ impl Opacity { } } - /// Devuelve la clase de opacidad con el prefijo dado (`bg`, `border`, `text`, o vacío para - /// `opacity-*`). - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(Opacity::Opaque.class_with(""), "opacity-100"); - /// assert_eq!(Opacity::Half.class_with("bg"), "bg-opacity-50"); - /// assert_eq!(Opacity::SemiTransparent.class_with("text"), "text-opacity-25"); - /// assert_eq!(Opacity::Default.class_with("bg"), ""); - /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str) -> String { + // Devuelve la clase de opacidad con el prefijo dado (`bg`, `border`, `text`, o vacío para + // `opacity-*`). + // + // # Ejemplos + // + // ```rust + // # use pagetop_bootsier::prelude::*; + // assert_eq!(Opacity::Opaque.class_with(""), "opacity-100"); + // assert_eq!(Opacity::Half.class_with("bg"), "bg-opacity-50"); + // assert_eq!(Opacity::SemiTransparent.class_with("text"), "text-opacity-25"); + // assert_eq!(Opacity::Default.class_with("bg"), ""); + // ``` + #[inline] + pub(crate) fn class_with(self, prefix: &str) -> String { if let Some(suffix) = self.suffix() { let base_len = if prefix.is_empty() { Self::OPACITY.len() @@ -206,7 +206,7 @@ impl ColorBg { const BG: &str = "bg"; const BG_PREFIX: &str = "bg-"; - /// Devuelve el sufijo de la clase `bg-*`, o `None` si no define ninguna clase. + // Devuelve el sufijo de la clase `bg-*`, o `None` si no define ninguna clase. #[rustfmt::skip] #[inline] const fn suffix(self) -> Option<&'static str> { @@ -223,7 +223,7 @@ impl ColorBg { } } - /// Añade la clase de fondo `bg-*` a la cadena de clases. + // Añade la clase de fondo `bg-*` a la cadena de clases. #[inline] pub(crate) fn push_class(self, classes: &mut String) { if let Some(suffix) = self.suffix() { @@ -253,6 +253,7 @@ impl ColorBg { /// assert_eq!(ColorBg::Transparent.to_class(), "bg-transparent"); /// assert_eq!(ColorBg::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { if let Some(suffix) = self.suffix() { let base_len = match self { @@ -304,7 +305,7 @@ impl ColorText { const TEXT: &str = "text"; const TEXT_PREFIX: &str = "text-"; - /// Devuelve el sufijo de la clase `text-*`, o `None` si no define ninguna clase. + // Devuelve el sufijo de la clase `text-*`, o `None` si no define ninguna clase. #[rustfmt::skip] #[inline] const fn suffix(self) -> Option<&'static str> { @@ -321,7 +322,7 @@ impl ColorText { } } - /// Añade la clase de texto `text-*` a la cadena de clases. + // Añade la clase de texto `text-*` a la cadena de clases. #[inline] pub(crate) fn push_class(self, classes: &mut String) { if let Some(suffix) = self.suffix() { @@ -351,6 +352,7 @@ impl ColorText { /// assert_eq!(ColorText::Black.to_class(), "text-black"); /// assert_eq!(ColorText::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { if let Some(suffix) = self.suffix() { let base_len = match self { diff --git a/extensions/pagetop-bootsier/src/theme/aux/layout.rs b/extensions/pagetop-bootsier/src/theme/aux/layout.rs index a1255dc0..1d351582 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/layout.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/layout.rs @@ -25,8 +25,8 @@ pub enum ScaleSize { } impl ScaleSize { - /// Devuelve el sufijo para el tamaño (`"-0"`, `"-1"`, etc.), o `None` si no define ninguna - /// clase, o `""` para el tamaño automático. + // Devuelve el sufijo para el tamaño (`"-0"`, `"-1"`, etc.), o `None` si no define ninguna + // clase, o `""` para el tamaño automático. #[rustfmt::skip] #[inline] const fn suffix(self) -> Option<&'static str> { @@ -42,7 +42,7 @@ impl ScaleSize { } } - /// Añade el tamaño a la cadena de clases usando el prefijo dado. + // Añade el tamaño a la cadena de clases usando el prefijo dado. #[inline] pub(crate) fn push_class(self, classes: &mut String, prefix: &str) { if !prefix.is_empty() { @@ -57,18 +57,18 @@ impl ScaleSize { } /* Devuelve la clase del tamaño para el prefijo, o una cadena vacía si no aplica (reservado). - /// - /// # Ejemplo - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(ScaleSize::Auto.class_with("border"), "border"); - /// assert_eq!(ScaleSize::Zero.class_with("m"), "m-0"); - /// assert_eq!(ScaleSize::Three.class_with("p"), "p-3"); - /// assert_eq!(ScaleSize::None.class_with("border"), ""); - /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str) -> String { + // + // # Ejemplo + // + // ```rust + // # use pagetop_bootsier::prelude::*; + // assert_eq!(ScaleSize::Auto.class_with("border"), "border"); + // assert_eq!(ScaleSize::Zero.class_with("m"), "m-0"); + // assert_eq!(ScaleSize::Three.class_with("p"), "p-3"); + // assert_eq!(ScaleSize::None.class_with("border"), ""); + // ``` + #[inline] + pub(crate) fn class_with(self, prefix: &str) -> String { if !prefix.is_empty() { if let Some(suffix) = self.suffix() { let mut class = String::with_capacity(prefix.len() + suffix.len()); diff --git a/extensions/pagetop-bootsier/src/theme/aux/rounded.rs b/extensions/pagetop-bootsier/src/theme/aux/rounded.rs index 69976142..20e061d6 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/rounded.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/rounded.rs @@ -29,8 +29,8 @@ pub enum RoundedRadius { impl RoundedRadius { const ROUNDED: &str = "rounded"; - /// Devuelve el sufijo para `*rounded-*`, o `None` si no define ninguna clase, o `""` para el - /// redondeo por defecto. + // Devuelve el sufijo para `*rounded-*`, o `None` si no define ninguna clase, o `""` para el + // redondeo por defecto. #[rustfmt::skip] #[inline] const fn suffix(self) -> Option<&'static str> { @@ -48,8 +48,8 @@ impl RoundedRadius { } } - /// Añade el redondeo de esquinas a la cadena de clases usando el prefijo dado (`rounded-top`, - /// `rounded-bottom-start`, o vacío para `rounded-*`). + // Añade el redondeo de esquinas a la cadena de clases usando el prefijo dado (`rounded-top`, + // `rounded-bottom-start`, o vacío para `rounded-*`). #[inline] pub(crate) fn push_class(self, classes: &mut String, prefix: &str) { if let Some(suffix) = self.suffix() { @@ -65,21 +65,21 @@ impl RoundedRadius { } } - /// Devuelve la clase para el redondeo de esquinas con el prefijo dado (`rounded-top`, - /// `rounded-bottom-start`, o vacío para `rounded-*`). - /// - /// # Ejemplos - /// - /// ```rust - /// # use pagetop_bootsier::prelude::*; - /// assert_eq!(RoundedRadius::Scale2.class_with(""), "rounded-2"); - /// assert_eq!(RoundedRadius::Zero.class_with("rounded-top"), "rounded-top-0"); - /// assert_eq!(RoundedRadius::Scale3.class_with("rounded-top-end"), "rounded-top-end-3"); - /// assert_eq!(RoundedRadius::Circle.class_with(""), "rounded-circle"); - /// assert_eq!(RoundedRadius::None.class_with("rounded-bottom-start"), ""); - /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str) -> String { + // Devuelve la clase para el redondeo de esquinas con el prefijo dado (`rounded-top`, + // `rounded-bottom-start`, o vacío para `rounded-*`). + // + // # Ejemplos + // + // ```rust + // # use pagetop_bootsier::prelude::*; + // assert_eq!(RoundedRadius::Scale2.class_with(""), "rounded-2"); + // assert_eq!(RoundedRadius::Zero.class_with("rounded-top"), "rounded-top-0"); + // assert_eq!(RoundedRadius::Scale3.class_with("rounded-top-end"), "rounded-top-end-3"); + // assert_eq!(RoundedRadius::Circle.class_with(""), "rounded-circle"); + // assert_eq!(RoundedRadius::None.class_with("rounded-bottom-start"), ""); + // ``` + #[inline] + pub(crate) fn class_with(self, prefix: &str) -> String { if let Some(suffix) = self.suffix() { let base_len = if prefix.is_empty() { Self::ROUNDED.len() diff --git a/extensions/pagetop-bootsier/src/theme/classes/border.rs b/extensions/pagetop-bootsier/src/theme/classes/border.rs index 2da7bfbb..3095498c 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/border.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/border.rs @@ -145,6 +145,7 @@ impl Border { /// `"border border-top-0 border-end-3 border-primary border-opacity-50"`, etc.). /// /// Si no se define ningún tamaño, color ni opacidad, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); diff --git a/extensions/pagetop-bootsier/src/theme/classes/color.rs b/extensions/pagetop-bootsier/src/theme/classes/color.rs index 4f5b4650..162b7849 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/color.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/color.rs @@ -76,6 +76,7 @@ impl Background { /// Devuelve las clases de fondo como cadena (`"bg-primary"`, `"bg-body-secondary bg-opacity-50"`, etc.). /// /// Si no se define ni color ni opacidad, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); @@ -188,6 +189,7 @@ impl Text { /// etc.). /// /// Si no se define ni color ni opacidad, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); diff --git a/extensions/pagetop-bootsier/src/theme/classes/layout.rs b/extensions/pagetop-bootsier/src/theme/classes/layout.rs index 1f388450..e9d7e248 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/layout.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/layout.rs @@ -48,7 +48,7 @@ impl Margin { // **< Margin HELPERS >************************************************************************* - /// Devuelve el prefijo `m*` según el lado. + // Devuelve el prefijo `m*` según el lado. #[rustfmt::skip] #[inline] const fn side_prefix(&self) -> &'static str { @@ -63,7 +63,7 @@ impl Margin { } } - /// Devuelve el sufijo del tamaño (`auto`, `0`..`5`), o `None` si no define clase. + // Devuelve el sufijo del tamaño (`auto`, `0`..`5`), o `None` si no define clase. #[rustfmt::skip] #[inline] const fn size_suffix(&self) -> Option<&'static str> { @@ -80,8 +80,8 @@ impl Margin { } /* Añade la clase de **margin** a la cadena de clases (reservado). - /// - /// No añade nada si `size` es `ScaleSize::None`. + // + // No añade nada si `size` es `ScaleSize::None`. #[inline] pub(crate) fn push_class(self, classes: &mut String) { let Some(size) = self.size_suffix() else { @@ -94,6 +94,7 @@ impl Margin { /// Devuelve la clase de **margin** como cadena (`"mt-3"`, `"ms-lg-auto"`, etc.). /// /// Si `size` es `ScaleSize::None`, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let Some(size) = self.size_suffix() else { return String::new(); @@ -147,7 +148,7 @@ impl Padding { // **< Padding HELPERS >************************************************************************ - /// Devuelve el prefijo `p*` según el lado. + // Devuelve el prefijo `p*` según el lado. #[rustfmt::skip] #[inline] const fn prefix(&self) -> &'static str { @@ -162,9 +163,9 @@ impl Padding { } } - /// Devuelve el sufijo del tamaño (`0`..`5`), o `None` si no define clase. - /// - /// Nota: `ScaleSize::Auto` **no aplica** a padding ⇒ devuelve `None`. + // Devuelve el sufijo del tamaño (`0`..`5`), o `None` si no define clase. + // + // Nota: `ScaleSize::Auto` **no aplica** a padding ⇒ devuelve `None`. #[rustfmt::skip] #[inline] const fn suffix(&self) -> Option<&'static str> { @@ -181,8 +182,8 @@ impl Padding { } /* Añade la clase de **padding** a la cadena de clases (reservado). - /// - /// No añade nada si `size` es `ScaleSize::None` o `ScaleSize::Auto`. + // + // No añade nada si `size` es `ScaleSize::None` o `ScaleSize::Auto`. #[inline] pub(crate) fn push_class(self, classes: &mut String) { let Some(size) = self.suffix() else { @@ -191,9 +192,10 @@ impl Padding { self.breakpoint.push_class(classes, self.prefix(), size); } */ - /// Devuelve la clase de **padding** como cadena (`"px-2"`, `"pe-sm-4"`, etc.). - /// - /// Si `size` es `ScaleSize::None` o `ScaleSize::Auto`, devuelve `""`. + // Devuelve la clase de **padding** como cadena (`"px-2"`, `"pe-sm-4"`, etc.). + // + // Si `size` es `ScaleSize::None` o `ScaleSize::Auto`, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let Some(size) = self.suffix() else { return String::new(); diff --git a/extensions/pagetop-bootsier/src/theme/classes/rounded.rs b/extensions/pagetop-bootsier/src/theme/classes/rounded.rs index 077740e1..58d50b86 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/rounded.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/rounded.rs @@ -160,6 +160,7 @@ impl Rounded { /// `"rounded-top rounded-bottom-start-4 rounded-bottom-end-circle"`, etc.). /// /// Si no se define ningún radio, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); diff --git a/extensions/pagetop-bootsier/src/theme/container/component.rs b/extensions/pagetop-bootsier/src/theme/container/component.rs index b105abb1..068d24a3 100644 --- a/extensions/pagetop-bootsier/src/theme/container/component.rs +++ b/extensions/pagetop-bootsier/src/theme/container/component.rs @@ -6,23 +6,19 @@ use crate::prelude::*; /// /// Envuelve un contenido con la etiqueta HTML indicada por [`container::Kind`]. Sólo se renderiza /// si existen componentes hijos (*children*). -#[derive(AutoDefault, Getters)] +#[rustfmt::skip] +#[derive(AutoDefault)] pub struct Container { - #[getters(skip)] - id: AttrId, - /// Devuelve las clases CSS asociadas al contenedor. - classes: Classes, - /// Devuelve el tipo semántico del contenedor. - container_kind: container::Kind, - /// Devuelve el comportamiento para el ancho del contenedor. + id : AttrId, + classes : AttrClasses, + container_kind : container::Kind, container_width: container::Width, - /// Devuelve la lista de componentes (`children`) del contenedor. - children: Children, + children : Children, } impl Component for Container { fn new() -> Self { - Self::default() + Container::default() } fn id(&self) -> Option { @@ -30,7 +26,7 @@ impl Component for Container { } fn setup_before_prepare(&mut self, _cx: &mut Context) { - self.alter_classes(ClassesOp::Prepend, self.container_width().to_class()); + self.alter_classes(ClassesOp::Prepend, self.width().to_class()); } fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { @@ -38,9 +34,9 @@ impl Component for Container { if output.is_empty() { return PrepareMarkup::None; } - let style = match self.container_width() { + let style = match self.width() { container::Width::FluidMax(w) if w.is_measurable() => { - Some(util::join!("max-width: ", w.to_string(), ";")) + Some(join!("max-width: ", w.to_string(), ";")) } _ => None, }; @@ -82,7 +78,7 @@ impl Component for Container { impl Container { /// Crea un contenedor de tipo `Main` (`
`). pub fn main() -> Self { - Self { + Container { container_kind: container::Kind::Main, ..Default::default() } @@ -90,7 +86,7 @@ impl Container { /// Crea un contenedor de tipo `Header` (`
`). pub fn header() -> Self { - Self { + Container { container_kind: container::Kind::Header, ..Default::default() } @@ -98,7 +94,7 @@ impl Container { /// Crea un contenedor de tipo `Footer` (`