Asi se pasa el ‘state’ usando .app_data() en lugar de .data() que ha quedado obsoleto (deprecated).
// --snip--
App::new()
.service(index)
.app_data(web::Data::new(pool.clone()))
.app_data(web::Data::new(tera))
// --snip --
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
Es momento de realizar el típico ¡Hola Mundo! Pero esta vez con un motor de renderizado de HTML como Tera.
Prepara tu proyecto para el renderizado de un HTML básico con Tera de la siguiente manera.
Comienza instalando la dependencia de Tera en el Cargo.toml
.
[dependencies]
tera = "1.10.0"
Impórtalo en el main.rs
y configura el servidor HTTP para que reconozca la instancia de Tera y renderize los templates.
// Importamos TERA
use tera::Tera;
// ...
HttpServer::new(move || {
// Instanciamos TERA y le indicamos en qué directorio buscar los templates
let tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
App::new()
.service(index)
.service(new_post)
.service(tera_test)
.app_data(web::Data::new(pool.clone()))
.app_data(web::Data::new(tera.clone()))
}).bind(("127.0.0.1", 8080)).unwrap().run().await
Crea un directorio al cual llamaremos /templates
en la raíz de tu proyecto (a la altura de src
) con un archivo llamado tera_test.html
con un HTML básico en su interior.
<!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>Rust | Tera</title>
</head>
<body>
Mi primer template HTML con Rust y Tera
</body>
</html>
Finalmente, crea el endpoint que renderizará nuestro tera_test.html
.
#[get("/tera_test")]
async fn tera_test(template_manager: web::Data<tera::Tera>) -> impl Responder {
// Creamos un contexto para pasarle datos al template
let mut ctx = tera::Context::new();
// Enviamos el template que queremos localizándolo por su nombre
HttpResponse::Ok().content_type("text/html").body(
template_manager.render("tera_test.html", &ctx).unwrap()
)
}
Si todo ha ido bien, simplemente ingresando a 127.0.0.1:8080/tera_test
visualizarás el contenido del template.
De esta forma, ya puedes crear toda una página web estática con Rust y Tera. Pero aún queda lo mejor, enviar datos dinámicamente al template.
Contribución creada por: Kevin Fiorentino.
Aportes 4
Preguntas 0
Asi se pasa el ‘state’ usando .app_data() en lugar de .data() que ha quedado obsoleto (deprecated).
// --snip--
App::new()
.service(index)
.app_data(web::Data::new(pool.clone()))
.app_data(web::Data::new(tera))
// --snip --
Para que me funcionara tuve que poner unwrap al manifest dir y el nuevl app_data como comento Jose paredes
HttpServer::new(move || {
let tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
App::new()
.service(index)
.service(new_post)
.app_data(web::Data::new(pool.clone()))
.app_data(web::Data::new(tera))
})
.bind(("0.0.0.0", 9900))?
.run()
.await
Hubiese sido bueno aprender a configurar un logger para cuando hay problemas debuguear junto a la clase.
Cree otro template llamados posts.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Templates con Tera</title>
<style>
body {
font-family: Arial, sans-serif;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
padding: 10px;
border: 1px solid #000;
}
</style>
</head>
<body>
<h1>Templates con Tera</h1>
<table>
<thead>
<tr>
<th>Title</th>
<th>Body</th>
</tr>
</thead>
<tbody>
{% for post in posts %}
<tr>
<td>{{ post.title }}</td>
<td>{{ post.body }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
Modifique #[get("/")] para que renderizara el resultado de la consulta de la tabla:
#[get("/")]
async fn index(pool: web::Data<DbPool>, template_manager: web::Data<tera::Tera>) -> impl Responder {
let mut conn = pool.get().expect("Problemas al traer la BD");
match web::block(move || posts.load::<Post>(&mut conn)).await {
Ok(data) => {
let mut context = tera::Context::new();
context.insert("posts", &data.unwrap());
let rendered = template_manager
.render("posts.html", &context)
.unwrap_or_else(|err| format!("Error al renderizar: {}", err));
HttpResponse::Ok().content_type("text/html").body(rendered)
}
Err(err) => HttpResponse::Ok().body(format!("Error al recibir la data: {}", err)),
}
}
El resultado:
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?