show top tags on index page

This commit is contained in:
2024-04-30 23:10:12 +02:00
parent 76085120c1
commit 8f5069e207
11 changed files with 175 additions and 43 deletions

View File

@ -10,6 +10,7 @@ mod pages;
mod post_list;
mod post_parser;
mod router;
mod tag_list;
// mod template;
#[tokio::main]

View File

@ -1,8 +1,12 @@
use askama::Template;
use axum::http::StatusCode;
use crate::components::{
site_footer::{render_site_footer, SiteFooter},
site_header::HeaderProps,
use crate::{
components::{
site_footer::{render_site_footer, SiteFooter},
site_header::HeaderProps,
},
tag_list::get_popular_blog_tags,
};
#[derive(Template)]
@ -10,12 +14,24 @@ use crate::components::{
pub struct IndexTemplate {
site_footer: SiteFooter,
header_props: HeaderProps,
blog_tags: Vec<String>,
}
pub async fn render_index() -> IndexTemplate {
let site_footer = render_site_footer().await;
IndexTemplate {
pub async fn render_index() -> Result<IndexTemplate, StatusCode> {
let site_footer = tokio::spawn(render_site_footer());
let blog_tags = tokio::spawn(get_popular_blog_tags());
let blog_tags = blog_tags
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)??;
let site_footer = site_footer
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(IndexTemplate {
site_footer,
header_props: HeaderProps::default(),
}
blog_tags,
})
}

View File

@ -51,7 +51,6 @@ pub async fn render_post_list(tag: Option<Path<String>>) -> Result<PostListTempl
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
// TODO if we have a tag we want to go back to all posts, otherwise we don't
let header_props = match tag {
Some(_) => HeaderProps::with_back_link(Link {
href: "/blog".to_string(),
@ -68,6 +67,3 @@ pub async fn render_post_list(tag: Option<Path<String>>) -> Result<PostListTempl
header_props,
})
}
// TODO Do we want pagination or not? Ask designer/ We don't want itt
// TODO when tags are true render different "see all post" message

View File

@ -0,0 +1,34 @@
use crate::{pages::post::PostMetadata, post_list::get_post_list};
use axum::http::StatusCode;
use std::collections::HashMap;
use tracing::debug;
pub async fn get_popular_blog_tags() -> Result<Vec<String>, StatusCode> {
const TAGS_LENGTH: usize = 7;
let post_list = get_post_list::<PostMetadata>().await?;
let tags_sum = post_list
.into_iter()
.flat_map(|post| post.metadata.tags)
.fold(HashMap::new(), |mut acc, tag| {
*acc.entry(tag).or_insert(0) += 1;
acc
});
let mut sorted_tags_by_count: Vec<_> = tags_sum.into_iter().collect();
sorted_tags_by_count.sort_by_key(|&(_, count)| std::cmp::Reverse(count));
// Log the counts
for (tag, count) in &sorted_tags_by_count {
debug!("Tag: {}, Count: {}", tag, count);
}
let popular_blog_tags = sorted_tags_by_count
.into_iter()
.map(|tag_count| tag_count.0)
.filter(|tag| tag != "dev")
.take(TAGS_LENGTH)
.collect::<Vec<String>>();
Ok(popular_blog_tags)
}