Files
zero2prod/src/templates.rs
Alphonse Paix 4cb1d2b6fd
Some checks failed
Rust / Test (push) Has been cancelled
Rust / Rustfmt (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Code coverage (push) Has been cancelled
Compute dashboard stats
Track open rate for new post notifications (user clicked the button in
the link or not). No data about the user is collected during the
process, it only uses an ID inserted by the issue delivery worker.
2025-09-24 04:30:27 +02:00

147 lines
3.3 KiB
Rust

use crate::{domain::PostEntry, routes::DashboardStats};
use askama::Template;
use uuid::Uuid;
#[derive(Template)]
pub enum MessageTemplate {
#[template(path = "../templates/success.html")]
Success { message: String },
#[template(path = "../templates/error.html")]
Error { message: String },
}
#[derive(Template)]
#[template(path = "../templates/500.html")]
pub struct InternalErrorTemplate;
#[derive(Template)]
#[template(path = "../templates/login.html")]
pub struct LoginTemplate;
#[derive(Template)]
#[template(path = "../templates/dashboard.html")]
pub struct DashboardTemplate {
pub username: String,
pub idempotency_key_1: String,
pub idempotency_key_2: String,
pub stats: DashboardStats,
}
#[derive(Template)]
#[template(path = "home.html")]
pub struct HomeTemplate;
#[derive(Template)]
#[template(path = "posts.html")]
pub struct PostsTemplate {
pub posts: Vec<PostEntry>,
pub next_page: Option<i64>,
}
#[derive(Template)]
#[template(path = "posts.html", block = "posts")]
pub struct PostListTemplate {
pub posts: Vec<PostEntry>,
pub next_page: Option<i64>,
}
#[derive(Template)]
#[template(path = "post.html")]
pub struct PostTemplate {
pub post: PostEntry,
}
#[derive(Template)]
#[template(path = "confirm.html")]
pub struct ConfirmTemplate;
#[derive(Template)]
#[template(path = "404.html")]
pub struct NotFoundTemplate;
#[derive(Template)]
#[template(path = "unsubscribe_confirm.html")]
pub struct UnsubscribeConfirmTemplate;
#[derive(Template)]
#[template(path = "unsubscribe.html")]
pub struct UnsubscribeTemplate;
#[derive(Template)]
#[template(path = "email/new_post.html")]
pub struct NewPostEmailTemplate<'a> {
pub base_url: &'a str,
pub post_title: &'a str,
pub post_id: &'a Uuid,
pub post_excerpt: &'a str,
}
#[derive(Template)]
#[template(path = "email/standalone.html")]
pub struct StandaloneEmailTemplate<'a> {
pub base_url: &'a str,
pub html_content: &'a str,
pub text_content: &'a str,
}
pub trait EmailTemplate: Sync {
fn html(&self) -> String;
fn text(&self) -> String;
}
impl<'a> EmailTemplate for NewPostEmailTemplate<'a> {
fn html(&self) -> String {
self.render().unwrap()
}
fn text(&self) -> String {
format!(
r#"New post available!
Hello there!
I just published a new post that I think you'll find interesting:
"{}"
Read the full post: {}/posts/{}?origin=EMAIL_ID
This post covers practical insights and real-world examples that I hope will be valuable for your backend development journey.
Thanks for being a subscriber!
Best regards,
Alphonse
---
zero2prod - Building better backends with Rust
Visit the blog: {}
Unsubscribe: {}/unsubscribe/confirm?token=UNSUBSCRIBE_TOKEN
You're receiving this because you subscribed to the zero2prod newsletter."#,
self.post_title, self.base_url, self.post_id, self.base_url, self.base_url,
)
}
}
impl<'a> EmailTemplate for StandaloneEmailTemplate<'a> {
fn html(&self) -> String {
self.render().unwrap()
}
fn text(&self) -> String {
format!(
r#"{}
---
zero2prod - Building better backends with Rust
Visit the blog: {}
Unsubscribe: {}/unsubscribe/confirm?token=UNSUBSCRIBE_TOKEN
You're receiving this because you subscribed to the zero2prod newsletter."#,
self.text_content, self.base_url, self.base_url
)
}
}