# Cómo crear un paquete desde cero Este tutorial describe cómo se ha creado el módulo `pagetop-jquery` para incluir la librería [jQuery](https://jquery.com) en las páginas web generadas por otros módulos o aplicaciones desarrolladas con **PageTop**. # Primeros pasos Para este tutorial se suponen conocimientos de programación con [Rust](https://www.rust-lang.org), del gestor de paquetes [`cargo`](https://doc.rust-lang.org/stable/cargo), así como de la [API de PageTop](https://docs.rs/pagetop). Los ejemplos están pensados para entornos Linux pero no deberían ser muy diferentes en otros sistemas operativos. ## Crear el proyecto La forma más sencilla de empezar es rompiendo el hielo con el gestor de paquetes `cargo` siguiendo los mismos pasos que en cualquier otro proyecto Rust: ```bash cargo new --lib pagetop-jquery ``` Accede al proyecto recién creado y añade la dependiencia a **PageTop**: ```bash cd pagetop-jquery cargo add pagetop ``` ## Soporte multilingüe La [API de localización](https://docs.rs/pagetop/latest/pagetop/locale/index.html) de **PageTop** proporciona soporte multilingüe a los módulos. Primero crea la estructura de carpetas para los archivos de los textos en inglés y español (únicos idiomas soportados actualmente): ```bash mkdir src/locale mkdir src/locale/en-US mkdir src/locale/es-ES ``` Crea el archivo `src\locale\en-US\module.flt` con las siguientes asignaciones para identificar y describir el módulo: ```ini package_name = jQuery support package_description = Integrate the jQuery library into web pages generated by other modules. ``` Y su archivo equivalente `src\locale\es-ES\module.flt` para las mismas asignaciones en español: ```ini package_name = Soporte a jQuery package_description = Incorpora la librería jQuery en páginas web generadas por otros módulos. ``` Estas primeras asignaciones suelen ser habituales en todos los módulos. ## Iniciar el módulo Para desarrollar un módulo **PageTop** hay que implementar los métodos necesarios del *trait* [`ModuleTrait`](https://docs.rs/pagetop/latest/pagetop/core/module/trait.ModuleTrait.html) sobre una estructura vacía que se puede inicializar en el archivo `src/lib.rs`: ```rust use pagetop::prelude::*; static_locales!(LOCALES_JQUERY); #[derive(AssignHandle)] pub struct JQuery; impl ModuleTrait for JQuery { fn name(&self) -> L10n { L10n::t("package_name", &LOCALES_JQUERY) } fn description(&self) -> L10n { L10n::t("package_description", &LOCALES_JQUERY) } } ``` La función [`handle()`](https://docs.rs/pagetop/latest/pagetop/core/module/trait.ModuleTrait.html#method.handle) es la única que obligatoriamente debe implementarse porque permite asignar al módulo un identificador único creado previamente con la macro [`create_handle!()`](https://docs.rs/pagetop/latest/pagetop/macro.create_handle.html). El soporte multilingüe se incorpora con la macro [`static_locales!()`](https://docs.rs/pagetop/latest/pagetop/macro.static_locales.html) asignando un identificador a la ruta de los archivos de localización (que puede omitirse si la ruta es `src/locale`). Las funciones [`name()`](https://docs.rs/pagetop/latest/pagetop/core/module/trait.ModuleTrait.html#method.name) y [`description()`](https://docs.rs/pagetop/latest/pagetop/core/module/trait.ModuleTrait.html#method.description) son opcionales, aunque se recomienda su implementación para identificar y describir adecuadamente el módulo. Hacen uso del componente [`L10n`](https://docs.rs/pagetop/latest/pagetop/base/component/struct.L10n.html) y de los archivos de localización creados en el apartado anterior para devolver los textos en el idioma del contexto. # Archivos estáticos Seguimos en el directorio del proyecto, al mismo nivel de `src`. Es buena práctica crear una carpeta de nombre `static` para los archivos estáticos. En ella descargaremos los archivos `jquery.min.js` y `jquery.min.map` de la librería **jQuery**: ```bash mkdir static ``` ## Crear el archivo build.rs Para que estos archivos estáticos formen parte del binario de la aplicación hay que añadir dos nuevas dependencias al proyecto: ```bash cargo add static-files cargo add pagetop-build --build ``` Y crear un archivo `build.rs` con el siguiente código para incorporar el directorio `./static` en los recursos de compilación del proyecto: ```rust use pagetop_build::StaticFilesBundle; fn main() -> std::io::Result<()> { StaticFilesBundle::from_dir("./static") .with_name("jquery") .build() } ``` En este momento el proyecto tiene la siguiente estructura de directorios y archivos: ```bash pagetop-jquery/ ├── src/ │ ├── locale/ │ │ ├── en-ES/ │ │ │ └── module.flt │ │ └── es-ES/ │ │ └── module.flt │ └── lib.rs ├── static/ │ ├── jquery.min.js │ └── jquery.min.map └── Cargo.toml ``` ## Declarar los archivos en el módulo En `src/lib.rs` incorpora los recursos estáticos con `static_files!()` usando como identificador el nombre proporcionado al *bundle* de archivos en `build.rs` con `.with_name("jquery")`, pero ahora sin las comillas dobles: ```rust static_files!(jquery); ``` Y en la implementación de `JQuery` añade la función `configure_service()` para configurar el servicio web que responderá a las peticiones cuando el *path* comience por `/jquery/*` usando la macro [`configure_service_for_static_files!()`](): ```rust impl ModuleTrait for JQuery { ... fn configure_service(&self, cfg: &mut service::web::ServiceConfig) { configure_service_for_static_files!(cfg, jquery => "/jquery"); } ... } ``` De esta forma, a la petición `/jquery/jquery.min.js` el servidor web responderá devolviendo el archivo estático `./static/jquery.min.js`. # La API del módulo Este módulo proporciona funciones públicas para añadir o quitar del contexto los recursos de **jQuery**: -------------------- ***Notas*** * Puede que el código del módulo no sea el mismo que aquí se reproduce. El sentido de este tutorial es proporcionar una explicación sencilla de los principales elementos de un módulo.