No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

19 Días
18 Hrs
36 Min
30 Seg

Template para el index y los posts

17/21
Recursos

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.

Aportes 1

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

El motor de plantillas es muy similar a cualquier otro. Me hizo recordar a Angular + Twig de PHP.