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("/")]asyncfnindex(pool:web::Data<DbPool>, template_manager:web::Data<tera::Tera>)->implResponder{let conn = pool.get().expect("Problemas al traer la base de datos");// Consulta para obtener todos los registrosmatchweb::block(move||{posts.load::<Post>(&conn)}).await{Ok(data)=>{let data = data.unwrap();// Enviamos, a través del contexto, los datos al HTMLletmut ctx =tera::Context::new(); ctx.insert("posts",&data);// Pasamos los datos al template index.htmlHttpResponse::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.
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title></head><body> {% for post in posts %}
<div><h1><ahref="/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}")]asyncfnget_post( pool:web::Data<DbPool>, template_manager:web::Data<tera::Tera>, blog_slug:web::Path<String>)->implResponder{let conn = pool.get().expect("Problemas al traer la base de datos");let url_slug = blog_slug.into_inner();matchweb::block(move||{posts.filter(slug.eq(url_slug)).load::<Post>(&conn)}).await{Ok(data)=>{let data = data.unwrap();// Si el post no existe, devolvemos 404if data.len()==0{returnHttpResponse::NotFound().finish();}let data =&data[0];// Enviamos, a través del contexto, los datos del post al HTMLletmut 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.
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!