Creación de Templates Dinámicos con Tera en Rust
Clase 17 de 21 • Curso de Backend con Rust: Bases de Datos, Controladores y Templates
Contenido del curso
- 2

Uso de ORM Diesel en Aplicaciones Web para Blogs
02:55 - 3
Errores Comunes al Instalar y Usar Diesel en Rust
00:31 - 4

Instalación de Diesel y configuración de base de datos en Rust
05:16 - 5

Creación de Modelos y Migraciones en Rust con Diesel
14:23 - 6

Inserción de Datos en Bases de Datos con Diesel
07:55 - 7

Consultas SQL: Cómo Filtrar y Ordenar Datos Específicos
08:16 - 8

Edición de Registros en Bases de Datos con Diesel
04:40 - 9

Eliminación de Registros en Bases de Datos con Diesel
03:01
- 10

Configuración de Actix Web Framework en Rust
02:41 - 11

Configuración de Actix y conexión con bases de datos en Rust
10:42 - 12

Uso de Match Case en Rust para Control de Flujo
07:46 - 13

Mostrar datos de la base de datos en navegador con Actix
11:39 - 14

Creación de API RESTful para Blog con Postman y Rust
19:10 quiz de Actix web framework (controlador)
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.
Pasaje de variables 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.
Captura de parámetros
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.