Contenido del curso
Gestión de modelos en el backend con el ORM Diesel
- 2

Qué es un ORM y por qué usar Diesel
02:55 min - 3

Errores Comunes al Instalar y Usar Diesel en Rust
00:31 min - 4

Instala Diesel ORM en tu proyecto Rust
05:16 min - 5

Modelo Post con Diesel y PostgreSQL
14:22 min - 6

Cómo insertar datos en Diesel con Rust
07:55 min - 7

Queries SELECT con filtros en Diesel
08:16 min - 8

Cómo editar registros con Diesel en Rust
04:40 min - 9

Borrar registros en Diesel con filtros
03:01 min
Actix web framework (controlador)
Tera templates (vistas)
Despliegue del proyecto
Continúa tu aprendizaje
Creación de Templates Dinámicos con Tera en Rust
Resumen
Crear vistas dinámicas en Rust deja de ser un misterio cuando entiendes cómo conectar Tera con tu servidor web. Aquí verás cómo pasar datos desde el contexto, iterar sobre posts y construir rutas para mostrar un blog específico, todo con HTML real.
Este recurso es útil si ya configuraste Tera y quieres dar el siguiente paso: renderizar tu index y una vista de detalle usando datos provenientes de tu base de datos.
¿Cómo paso datos desde Rust hacia un template de Tera?
La pieza central es el Context de Tera. Funciona como un puente entre tu lógica en Rust y los placeholders de tu HTML. Tú insertas variables con ctx.insert y el template las reemplaza al renderizar.
En la función index recibimos el template manager como argumento y creamos un Context vacío. Si en el HTML escribes {{ hello_test }} con dobles llaves, esa variable se sustituye por lo que pases desde el contexto [01:30].
¿Qué es el contexto en Tera? Es la estructura donde guardas las variables que quieres exponer al template. Lo que insertes ahí estará disponible para reemplazar placeholders o iterar dentro del HTML.
¿Cómo recorro una lista de posts dentro del HTML?
Tera incluye una sintaxis de control de flujo basada en {% %}. Para iterar sobre una colección usas un bloque for ... in ... y lo cierras con endfor. Cada iteración tiene acceso al elemento actual, así que puedes leer sus campos directamente.
En el ejemplo, los posts vienen desde la consulta a la base de datos. Antes de pasarlos al contexto necesitas resolver el Result con data.unwrap(), porque la consulta puede contener un error. Luego llamas a ctx.insert("posts", &data) y dentro del HTML iteras así:
html {% for post in posts %}
<h1>{{ post.title }}</h1> <p>{{ post.body | truncate(length=15) }}</p> <a href="/blog/{{ post.slug }}">{{ post.title }}</a> {% endfor %}Lo interesante aquí es el filtro truncate. Aplica un límite de caracteres a un string usando la sintaxis de pipe |, muy parecida a la de otras plantillas. Con truncate(length=15) recortas el body a 15 caracteres y evitas que un post largo rompa tu listado [05:40].
¿Qué hace el filtro truncate en Tera?
Los filtros transforman el valor justo antes de imprimirlo. truncate corta el texto al número de caracteres que indiques, ideal para previews. Otros filtros similares te permiten formatear fechas, escapar HTML o pasar a mayúsculas sin tocar tu código Rust.
¿Cómo creo una ruta dinámica para mostrar un post individual?
La idea es que cada enlace del index lleve a /blog/{slug} y muestre el contenido completo. Para eso defines una nueva función, por ejemplo get_post, y registras la ruta con un parámetro entre llaves: /blog/{blog_slug}.
Dentro de la función accedes al parámetro con web::Path<String>. Ese tipo le dice al framework que extraiga el segmento de la URL y te lo entregue como string. Para usar el valor llamas a .into_inner() y lo guardas en una variable.
¿Qué es web::Path en Actix? Es un extractor que lee parámetros directamente desde la URL. Lo declaras como argumento de tu handler y el framework se encarga de hacer el binding automáticamente.
Con el slug en la mano, ajustas la consulta agregando .filter(slug.eq(blog_slug)). Si el resultado tiene longitud cero, devuelves Response::NotFound().finish(). Si existe, tomas data[0] y lo pasas al contexto bajo el nombre post.
¿Por qué renombrar variables al consultar Diesel?
Al filtrar por slug, el nombre de la columna en el schema choca con el nombre de tu variable local. Una solución directa es renombrar tu variable a url_slug para evitar el conflicto de scope. Es un detalle pequeño pero que rompe la compilación si lo dejas pasar.
¿Cómo organizo los templates de index y post?
Cada vista tiene su propio archivo .html dentro de la carpeta de templates. El de detalle es muy sencillo: muestra el title, el body completo sin truncate y un enlace de regreso al index.
No olvides registrar el nuevo handler en el bloque de services de tu configuración del servidor. Si lo omites, la ruta existe en el código pero el framework no la expone, y obtendrás un 404 sin razón aparente.
Un detalle a cuidar es la barra final en las URLs. En las pruebas, una ruta con / al final no respondía, mientras que la misma sin barra funcionaba sin problema. La forma exacta de la URL importa y conviene mantener consistencia en todos tus enlaces internos.
Con esto ya tienes un blog funcional: un listado en el index con previews truncadas y una vista de detalle accesible por slug. El diseño puede mejorar mucho con CSS, pero la base de renderizado dinámico con Tera ya está lista para el siguiente paso, que es desplegar todo en Heroku.
¿Cómo organizarías tú los filtros y bloques de Tera para mantener tus templates limpios? Cuéntame en los comentarios.