broadcasts and 404 errors
Some checks failed
test / cargo test (push) Failing after 59s

This commit is contained in:
2024-10-02 15:32:40 +02:00
parent 4f09373df3
commit 2979e21285
23 changed files with 236 additions and 60 deletions

View File

@ -1,6 +1,6 @@
use askama::Template;
use axum::{
extract::{OriginalUri, Path, RawQuery},
extract::{OriginalUri, Path},
http::StatusCode,
};
use tokio::try_join;
@ -9,7 +9,7 @@ use tracing::debug;
use crate::{
blog_posts::{
blog_post_model::{BlogPostMetadata, BLOG_POST_PATH},
tag_list::get_popular_blog_tags,
tag_list::{get_popular_tags, get_posts_by_tag},
},
components::site_header::{HeaderProps, Link},
filters,
@ -21,10 +21,11 @@ use crate::{
#[template(path = "blog_post_list.html")]
pub struct PostListTemplate {
pub title: String,
pub og_title: String,
pub segment: String,
pub posts: Vec<ParseResult<BlogPostMetadata>>,
pub tag: Option<String>,
pub header_props: HeaderProps,
pub blog_tags: Vec<String>,
pub tags: Vec<String>,
pub featured_projects: Vec<ParseResult<ProjectMetadata>>,
pub current_url: String,
}
@ -37,30 +38,17 @@ pub async fn render_blog_post_list(
let tag = tag.map(|Path(tag)| tag);
let (blog_tags, featured_projects, mut post_list) = try_join!(
get_popular_blog_tags(),
get_popular_tags(Some("blog".to_string())),
get_featured_projects(),
get_post_list::<BlogPostMetadata>(BLOG_POST_PATH)
)?;
post_list.sort_by_key(|post| post.metadata.date);
post_list.retain(|post| post.metadata.published);
post_list.retain(|post| post.metadata.segments.contains(&"blog".to_string()));
post_list.reverse();
let posts = match &tag {
Some(tag) => post_list
.into_iter()
.filter(|post| {
post.metadata
.tags
.iter()
.map(|post_tag| post_tag.to_lowercase())
.collect::<String>()
.contains(&tag.to_lowercase())
})
.collect(),
None => post_list,
};
let posts = get_posts_by_tag(post_list, &tag);
let header_props = match tag {
Some(_) => HeaderProps::with_back_link(Link {
href: "/blog".to_string(),
@ -71,18 +59,19 @@ pub async fn render_blog_post_list(
debug!("uri:{:?}", original_uri);
let title = if let Some(tag) = &tag {
format!("{tag} blog posts")
let (title, og_title) = if let Some(tag) = &tag {
(format!("#{tag}"), format!("{tag} blog posts"))
} else {
"Blog posts".to_string()
("Blog posts".to_string(), "Blog posts".to_string())
};
Ok(PostListTemplate {
title,
og_title,
segment: "blog".to_string(),
posts,
tag,
header_props,
blog_tags,
tags: blog_tags,
featured_projects,
current_url: original_uri.to_string(),
})

View File

@ -1,4 +1,5 @@
use askama::Template;
use axum::extract::OriginalUri;
use axum::{extract::Path, http::StatusCode};
use chrono::{DateTime, Utc};
@ -17,15 +18,38 @@ pub struct BlogPostTemplate {
pub body: String,
pub date: DateTime<Utc>,
pub tags: Vec<String>,
pub segment: String,
pub header_props: HeaderProps,
pub slug: String,
pub thumbnail: Option<String>,
}
pub async fn render_blog_post(Path(post_id): Path<String>) -> Result<BlogPostTemplate, StatusCode> {
pub async fn render_blog_post(
Path(post_id): Path<String>,
OriginalUri(original_uri): OriginalUri,
) -> Result<BlogPostTemplate, StatusCode> {
let path = format!("{}/{}.md", BLOG_POST_PATH, post_id);
let parse_post = parse_post::<BlogPostMetadata>(&path, true);
let parsed = parse_post.await?;
let segment = if original_uri.to_string().starts_with("/blog") {
"blog"
} else if original_uri.to_string().starts_with("/broadcasts") {
"broadcasts"
} else {
"blog"
};
let header_props = match segment {
"blog" => HeaderProps::with_back_link(Link {
href: "/blog".to_string(),
label: "All posts".to_string(),
}),
"broadcasts" => HeaderProps::with_back_link(Link {
href: "/broadcasts".to_string(),
label: "All broadcasts".to_string(),
}),
_ => HeaderProps::default(),
};
Ok(BlogPostTemplate {
title: parsed.metadata.title,
@ -33,10 +57,8 @@ pub async fn render_blog_post(Path(post_id): Path<String>) -> Result<BlogPostTem
tags: parsed.metadata.tags,
body: parsed.body,
slug: parsed.slug,
segment: segment.to_string(),
thumbnail: parsed.metadata.thumbnail,
header_props: HeaderProps::with_back_link(Link {
href: "/blog".to_string(),
label: "All posts".to_string(),
}),
header_props,
})
}

View File

@ -0,0 +1,66 @@
use axum::{
extract::{OriginalUri, Path},
http::StatusCode,
};
use tokio::try_join;
use tracing::debug;
use crate::{
blog_posts::{
blog_post_model::{BlogPostMetadata, BLOG_POST_PATH},
tag_list::{get_popular_tags, get_posts_by_tag},
},
components::site_header::{HeaderProps, Link},
post_utils::post_listing::get_post_list,
projects::featured_projects::get_featured_projects,
};
use super::blog_post_list::PostListTemplate;
pub async fn render_broadcast_post_list(
tag: Option<Path<String>>,
OriginalUri(original_uri): OriginalUri,
) -> Result<PostListTemplate, StatusCode> {
// I will forget what happens here in a week. But essentially it's pattern matching and shadowing
let tag = tag.map(|Path(tag)| tag);
let (popular_tags, featured_projects, mut post_list) = try_join!(
get_popular_tags(Some("broadcasts".to_string())),
get_featured_projects(),
get_post_list::<BlogPostMetadata>(BLOG_POST_PATH)
)?;
post_list.sort_by_key(|post| post.metadata.date);
post_list.retain(|post| post.metadata.published);
post_list.retain(|post| post.metadata.segments.contains(&"broadcasts".to_string()));
post_list.reverse();
let posts = get_posts_by_tag(post_list, &tag);
let header_props = match tag {
Some(_) => HeaderProps::with_back_link(Link {
href: "/broadcasts".to_string(),
label: "All broadcasts".to_string(),
}),
None => HeaderProps::default(),
};
debug!("uri:{:?}", original_uri);
let title = if let Some(tag) = &tag {
format!("#{tag} broadcasts")
} else {
"Broadcasts".to_string()
};
Ok(PostListTemplate {
title: title.clone(),
og_title: title,
segment: "broadcasts".to_string(),
posts,
header_props,
tags: popular_tags,
featured_projects,
current_url: original_uri.to_string(),
})
}

View File

@ -5,7 +5,7 @@ use tokio::try_join;
use crate::{
blog_posts::{
blog_post_model::BlogPostMetadata, featured_blog_posts::get_featured_blog_posts,
tag_list::get_popular_blog_tags,
tag_list::get_popular_tags,
},
components::site_header::HeaderProps,
filters,
@ -24,7 +24,7 @@ pub struct IndexTemplate {
pub async fn render_index() -> Result<IndexTemplate, StatusCode> {
let (blog_tags, featured_blog_posts, featured_projects) = try_join!(
get_popular_blog_tags(),
get_popular_tags(Some("blog".to_string())),
get_featured_blog_posts(),
get_featured_projects()
)?;

View File

@ -1,6 +1,8 @@
pub mod admin;
pub mod blog_post_list;
pub mod blog_post_page;
pub mod broadcast_list;
pub mod contact;
pub mod index;
pub mod project_list;
pub mod showcase;

View File

@ -0,0 +1,16 @@
use askama::Template;
use axum::http::StatusCode;
use crate::components::site_header::HeaderProps;
#[derive(Template)]
#[template(path = "egg_fetcher_page.html")]
pub struct EggFetcherShowcaseTemplate {
header_props: HeaderProps,
}
pub async fn render_egg_fetcher() -> Result<EggFetcherShowcaseTemplate, StatusCode> {
Ok(EggFetcherShowcaseTemplate {
header_props: HeaderProps::default(),
})
}

View File

@ -0,0 +1 @@
pub mod egg_fetcher;