Files
zero2prod/src/templates.rs
Alphonse Paix f9ae3f42a6
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
More tests, not found page and dashboard fixes
When post was deleted, website shows a 404 page insead of an 500 page.
Also made the dashboard empty page message more explicit.
2025-09-26 20:31:30 +02:00

176 lines
4.1 KiB
Rust

use crate::{
domain::{PostEntry, SubscriberEntry},
routes::{AppError, DashboardStats},
};
use askama::Template;
use axum::response::{Html, IntoResponse};
use uuid::Uuid;
pub struct HtmlTemplate<T>(pub T);
impl<T> IntoResponse for HtmlTemplate<T>
where
T: Template,
{
fn into_response(self) -> axum::response::Response {
match self.0.render() {
Ok(html) => Html(html).into_response(),
Err(err) => AppError::unexpected_page(anyhow::anyhow!(err)).into_response(),
}
}
}
#[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,
pub subscribers: Vec<SubscriberEntry>,
pub current_page: i64,
pub max_page: i64,
}
#[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 = "dashboard.html", block = "subs")]
pub struct SubListTemplate {
pub subscribers: Vec<SubscriberEntry>,
pub current_page: i64,
pub max_page: i64,
}
#[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
)
}
}