show top tags on index page
This commit is contained in:
@ -10,6 +10,7 @@ mod pages;
|
||||
mod post_list;
|
||||
mod post_parser;
|
||||
mod router;
|
||||
mod tag_list;
|
||||
// mod template;
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
@ -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
|
||||
|
34
axum_server/src/tag_list.rs
Normal file
34
axum_server/src/tag_list.rs
Normal 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)
|
||||
}
|
Reference in New Issue
Block a user