filter listing by tag

This commit is contained in:
Michal Vanko 2024-01-16 21:56:29 +01:00
parent 7f4e3e27e1
commit c44c2243de
2 changed files with 23 additions and 4 deletions

View File

@ -1,5 +1,5 @@
use askama::Template; use askama::Template;
use axum::http::StatusCode; use axum::{extract::Path, http::StatusCode};
use tokio::fs::read_dir; use tokio::fs::read_dir;
use tracing::info; use tracing::info;
@ -11,10 +11,13 @@ use super::post::PostMetadata;
#[template(path = "post_list.html")] #[template(path = "post_list.html")]
pub struct PostListTemplate { pub struct PostListTemplate {
pub posts: Vec<ParseResult<PostMetadata>>, pub posts: Vec<ParseResult<PostMetadata>>,
// TODO tags and pagination pub tag: Option<String>,
} }
pub async fn render_post_list() -> Result<PostListTemplate, StatusCode> { pub async fn render_post_list(tag: Option<Path<String>>) -> 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 path = "../_posts/blog/"; let path = "../_posts/blog/";
let mut dir = read_dir(path) let mut dir = read_dir(path)
.await .await
@ -33,7 +36,22 @@ pub async fn render_post_list() -> Result<PostListTemplate, StatusCode> {
posts.push(post); posts.push(post);
} }
Ok(PostListTemplate { posts }) let posts = match &tag {
Some(tag) => posts
.into_iter()
.filter(|post| {
post.metadata
.tags
.iter()
.map(|post_tag| post_tag.to_lowercase())
.collect::<String>()
.contains(&tag.to_lowercase())
})
.collect(),
None => posts,
};
Ok(PostListTemplate { posts, tag })
} }
// TODO Do we want pagination or not? Ask designer // TODO Do we want pagination or not? Ask designer

View File

@ -7,6 +7,7 @@ pub fn get_router() -> Router {
Router::new() Router::new()
.route("/", get(render_index)) .route("/", get(render_index))
.route("/blog", get(render_post_list)) .route("/blog", get(render_post_list))
.route("/blog/tags/:tag", get(render_post_list))
.route("/blog/:post_id", get(render_post)) .route("/blog/:post_id", get(render_post))
.layer( .layer(
TraceLayer::new_for_http().make_span_with(|request: &Request<_>| { TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {