El motor de plantillas es muy similar a cualquier otro. Me hizo recordar a Angular + Twig de PHP.
Bienvenida al curso
Desarrollo Web Avanzado con Rust: Crea un Gestor de Blog
Gestión de modelos en el backend con el ORM Diesel
Uso de ORM Diesel en Aplicaciones Web para Blogs
Errores Comunes al Instalar y Usar Diesel en Rust
Instalación de Diesel y configuración de base de datos en Rust
Creación de Modelos y Migraciones en Rust con Diesel
Inserción de Datos en Bases de Datos con Diesel
Consultas SQL: Cómo Filtrar y Ordenar Datos Específicos
Edición de Registros en Bases de Datos con Diesel
Eliminación de Registros en Bases de Datos con Diesel
Actix web framework (controlador)
Configuración de Actix Web Framework en Rust
Configuración de Actix y conexión con bases de datos en Rust
Uso de Match Case en Rust para Control de Flujo
Mostrar datos de la base de datos en navegador con Actix
Creación de API RESTful para Blog con Postman y Rust
Quiz: Actix web framework (controlador)
Tera templates (vistas)
Instalación y uso de Tera para plantillas en proyectos ROS
Integración de Tera y Creación de Templates en Proyectos Rust
Creación de Templates Dinámicos con Tera en Rust
Plantillas Tera y Bootstrap para Frontend Web
Quiz: Tera templates (vistas)
Despliegue del proyecto
Despliegue de Aplicaciones Rust en Heroku con Docker
Implementación de GitHub Actions para Despliegue en Heroku
Quiz: Despliegue del proyecto
Continúa tu aprendizaje
Despliegue de Aplicaciones Web con Rust
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Puedes crear tantas páginas HTML como tu aplicación necesite. En cualquier página web es fundamental poder enviar información dinámicamente al template.
Vamos a crear una página HTML para mostrar todos los registros. Para esto, modifica el index de tu aplicación para que devuelva un “contexto” y lograr pasarle datos a tu HTML.
#[get("/")]
async fn index(pool: web::Data<DbPool>, template_manager: web::Data<tera::Tera>) -> impl Responder {
let conn = pool.get().expect("Problemas al traer la base de datos");
// Consulta para obtener todos los registros
match web::block(move || {posts.load::<Post>(&conn)}).await {
Ok(data) => {
let data = data.unwrap();
// Enviamos, a través del contexto, los datos al HTML
let mut ctx = tera::Context::new();
ctx.insert("posts", &data);
// Pasamos los datos al template index.html
HttpResponse::Ok().content_type("text/html").body(
template_manager.render("index.html", &ctx).unwrap()
)
},
Err(err) => HttpResponse::Ok().body("Error al recibir la data")
}
}
En cuanto al HTML, Tera utiliza un lenguaje especial y muy fácil de utilizar para mostrar los datos o crear un ciclo for.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% for post in posts %}
<div>
<h1>
<a href="/blog/{{post.slug}}">{{ post.title }} </a>
</h1>
<p>{{ post.body }}</p>
</div>
{% endfor %}
</body>
</html>
A la vez que mostramos el título y la descripción del registro, estamos generando un enlace HTML para redireccionar a la página exclusiva del registro.
Para crear una página exclusiva para cada registro, normalmente se pasa un ID o una clave única del mismo a través de los parámetros de URL. Vamos a crear una nueva página para capturar esta información y renderizar un solo registro.
// Capturamos el parámetro por URL
#[get("/blog/{blog_slug}")]
async fn get_post(
pool: web::Data<DbPool>,
template_manager: web::Data<tera::Tera>,
blog_slug: web::Path<String>
) -> impl Responder {
let conn = pool.get().expect("Problemas al traer la base de datos");
let url_slug = blog_slug.into_inner();
match web::block(move || {posts.filter(slug.eq(url_slug)).load::<Post>(&conn)}).await {
Ok(data) => {
let data = data.unwrap();
// Si el post no existe, devolvemos 404
if data.len() == 0 {
return HttpResponse::NotFound().finish();
}
let data = &data[0];
// Enviamos, a través del contexto, los datos del post al HTML
let mut ctx = tera::Context::new();
ctx.insert("post", data);
HttpResponse::Ok().content_type("text/html").body(
template_manager.render("post.html", &ctx).unwrap()
)
},
Err(err) => HttpResponse::Ok().body("Error al recibir la data")
}
}
El URL está compuesto por una variable dinámica /blog/{blog_slug}
la cual podemos capturar como parámetro gracias a blog_slug: web::Path<String>
. Con este dato, buscamos y devolvemos el registro correspondiente o devolvemos 404 si el mismo no existe.
Mientras que en el HTML, solo muestras la información de un solo registro.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ post.title }}</title>
</head>
<body>
<div>
<h1>{{ post.title }}</h1>
<p>{{ post.body }}</p>
<a href="/">Volver</a>
</div>
</body>
</html>
De esta forma, ya sabes exponer un servidor HTTP con Rust y Actix, conectarte a una base de datos SQL con Diesel y renderizar la información en un template HTML con Tera. Hemos completado todo el stack necesario para desarrollar tu primera página web con Rust. ¡Felicidades!
Contribución creada por: Kevin Fiorentino.
Aportes 1
Preguntas 0
El motor de plantillas es muy similar a cualquier otro. Me hizo recordar a Angular + Twig de PHP.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?