Late Night Confessions — Building a Website Using Rust, Rocket, Diesel, and Askama — Part 3
Tags: softwareengineering, tutorial, rust
Published: 2021-04-30 11:56:21

---
title: Late Night Confessions — Building a Website Using Rust, Rocket, Diesel, and Askama — Part 3
published: true
date: 2021-04-29 18:52:30 UTC
tags: softwareengineering,tutorial,rust,rustlang
canonical_url: https://medium.com/perimeterx/late-night-confessions-building-a-website-using-rust-rocket-diesel-and-askama-part-3-3f9b7d511bde
cover_image: https://cdn-images-1.medium.com/max/1024/1*yQfRUKZpkaDbefbhcFthiA.jpeg
series: Late Night Confessions — Building a Website Using Rust, Rocket, Diesel, and Askama
---

#### Cover Photo by [Agnis Leznins](https://unsplash.com/@agnis_leznins?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/night-city-streets-rain?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText)

With a working API layer under our belt, it's time to put in the final piece of the puzzle: the presentation layer. This layer consists of static resources (HTML, CSS, JavaScript) and API calls to display and add confessions.

> ✏️ As this tutorial is not frontend focused, I wanted to keep things simple and use vanilla JavaScript, HTML and CSS. I will also not go into too much detail with why or how these are implemented, as we are not really here for frontend stuff, are we? 😎

**Working With Templates**

When we serve **index.html** back to the user, we want it to have a confession already so the user won’t load the page and then wait for the first API call to return the confession. That basically means that our application needs to parse the **index.html** static file, find the right place to inject a confession, and then inject the content in the correct place after fetching a random confession from the database. Now that might work if you have one item to inject, but what if you have two or ten?

That's where templates come into play. Templates allow us to have a static HTML that contains placeholders (aka variables) that the templating engine will replace with the content of our choice. In addition, templates allow us to use tags to control the template logic (if statements, for example). However, we will not be dealing with those in this tutorial.

For Late Night Confessions, I chose Askama as the templating engine because of its easy integration and simple syntax. Let’s create a template for our **index.html** file (trust me, it's easier than you think):

1. In the project root folder, create a new folder called **templates**.
2. Inside the templates folder, create a new file called **index.html** with the following content:

{% gist https://gist.github.com/pxjohnny/9606ae62889856d39cea1c4c28626852 %}

The vast majority of this file is plain old HTML syntax, take a glance at lines 32 and 47— These are Askama variables:

- confession (line 32) — This variable will be replaced by an actual confession from the database.
- total\_confessions (line 47) — This variable will be replaced by the total number of confessions in our database.

And that's basically that for making our HTML an Askama template. Let’s quickly add the **styles.css** and **confessions.js** files to the **site/static** folder and get back to Rust to integrate Askama:

{% gist https://gist.github.com/pxjohnny/ce6e28ff6f917be709b8105869b2fb7c %}

{% gist https://gist.github.com/pxjohnny/5c316a6fbc21e1f35b1e3cfcdbe9adaa %}

A few points of interest in our JavaScript:

- The refreshCard function makes a call to our GET API to get a new random confession and update the UI.
- The event listener for click validates the text area (so it is not empty, somewhat naive, I know, but 🤷‍♂️), and then if all is well, makes a call to our POST API with the new confession. If everything checks out (line 43), we alert the user everything is fine and update the footer note with the updated saved confessions number.
- We listen to the animationend event to update the displayed confession once the timer runs off (lines 53–55).

**Working With Askama**

1. Back in our Rust project, let’s add Askama to the **Cargo.toml** file:

{% gist https://gist.github.com/pxjohnny/7f39ec59bcbc7973d4a91c4ce11928a2 %}

2. As mentioned earlier, Askama works with templates, so the first thing we need to do is tell Askama where our template is and which variables it's going to have:

{% gist https://gist.github.com/pxjohnny/715261e890ea1ce13da6f02a211920a2 %}

🔬 So what do we have here?

- **Line 3** : We derive the Template trait, which is the main trait Askama uses. It includes template related methods such as render.
- **Line 4** : We use the template attribute to specify the path to our template. The path is relative to the templates folder in the project root folder. Other than path you can also specify a source (directly set the template, without a template file) or enable debug using the print sub-attribute. Read more about the different uses of the template attribute on the [official docs](https://docs.rs/askama/0.10.5/askama/#the-template-attribute).
- **Lines 5–8** : We define the fields the struct will hold, which are identical to the variables we defined in the template itself.

3. We now have two functions that need to get a random confession from the database: get\_confession (the handler for the GET API) and root (the handler that renders **index.html** ). To avoid code duplication, let’s extract get\_confession’s confession fetching logic to a new function, get\_random\_confession:

{% gist https://gist.github.com/pxjohnny/62aa564f28191c7649abca4343a1cdc1 %}

Notice that our new function takes a conn variable of type &PgConnection as argument and return a Result of either a Confession (if successful) or diesel’s error type (if there was a database-related error).

4. With the get\_random\_confession function in place, let’s update the get\_confession handler to use the new function as its closure:

{% gist https://gist.github.com/pxjohnny/a96461f6002b8849ae0037c7247968cc %}

5. Lastly, let’s update the root handler to render the template using Askama and set it as the response:

{% gist https://gist.github.com/pxjohnny/cffd297327e9cbfe9d5f47e2140bcc61 %}

🔬 So what do we have here?

- **Line 2** : We changed the return type to Html<String> for success and our CustomError in case of an error.
- **Line 3** : We get a random confession from the database using the new get\_random\_confession function, just like we are doing for the API call to **/api/confession.**
- **Lines 4–6** : We query Postgres for the number of confessions we have saved on it.
- **Lines 8–11** : We initiate the HomepageTemplate struct (a.k.a our template definition) with the data from Postgres.
- **Lines 13–14** : This is where the magic happens. Askama turns our template into an HTML string (line 13), which we return as the handler response (line 14).

And that's basically it! Go ahead and run cargo run and browse to localhost:8000. You should get something similar to the following:

![](https://cdn-images-1.medium.com/max/1024/1*qXZnbKZ9Q4V3XFD7lcmShA.png)<figcaption>A deep and heartwarming confession indeed…</figcaption>

### Summary

Our site creation journey has come to its end, but take a look back at everything you achieved! You now have a web app that is able to handle static files and API requests, uses a Postgres instance for persisting data and takes advantage of templates for quicker and easier HTML manipulation.

I would love to read your comments on this mini-post series over on [Twitter](https://twitter.com/FullStackJ), and please join me on my next Rust post series: “Let’s Build a Fitness Tracking Webapp With Rust and Yew”.

### Credit Where Credit’s Due

- Thank you, [Carla Notarobot](https://www.youtube.com/channel/UCnyWSONkScKMxut5g8iGi0A), for the [starry night CSS animation background](https://www.youtube.com/watch?v=0t6Dmp70kTw)!
- Thank you, [Traf](https://codepen.io/traf), for the [progress bar CSS animation](https://codepen.io/traf/pen/oKbaqQ)!

* * *