Add all tags in posts

This commit is contained in:
Florian RICHER 2024-02-18 19:49:06 +01:00
parent 91f2e4c116
commit 0436136cdd
2 changed files with 52 additions and 9 deletions

View file

@ -9,6 +9,7 @@ cfg_if::cfg_if! {
pub posts: Vec<Arc<Post>>,
pub posts_by_slug: HashMap<String, Arc<Post>>,
pub posts_by_tag: HashMap<String, Vec<Arc<Post>>>,
pub tags: Vec<String>,
}
impl Data {
@ -21,6 +22,8 @@ cfg_if::cfg_if! {
.map(Arc::new)
.collect::<Vec<_>>();
let mut tags : Vec<String> = Vec::new();
let mut posts_by_slug : HashMap<String, Arc<Post>> = HashMap::new();
let mut posts_by_tag : HashMap<String, Vec<Arc<Post>>> = HashMap::new();
@ -28,19 +31,26 @@ cfg_if::cfg_if! {
posts_by_slug.insert(post.metadata.slug.clone(), post.clone());
for tag in &post.metadata.tags {
let tag = tag.to_lowercase();
let posts = posts_by_tag.entry(tag).or_default();
let tag_lower = tag.to_lowercase();
if let None = tags.iter().find(|t| t.to_lowercase().eq(&tag_lower)) {
tags.push(tag.clone());
}
let posts = posts_by_tag.entry(tag_lower).or_default();
posts.push(post.clone());
}
}
log::info!("Loaded {} posts", posts.len());
log::info!("Found {} tags", posts_by_tag.len());
log::info!("Found {} tags in global", tags.len());
log::info!("Found {} tags from posts", posts_by_tag.len());
Ok(Self {
posts,
posts_by_slug,
posts_by_tag,
tags
})
}
}

View file

@ -32,6 +32,16 @@ pub async fn get_posts(
)
}
#[server]
pub async fn get_tags() -> Result<Vec<String>, ServerFnError> {
let data : actix_web::web::Data<crate::app::models::Data> = leptos_actix::extract().await?;
let data = data.into_inner();
let mut tags = data.tags.clone();
tags.sort();
Ok(tags)
}
#[server]
pub async fn get_post(
slug: String
@ -117,6 +127,7 @@ pub fn PostList() -> impl IntoView {
let query = use_query_map();
let tag = move || query.with(|query| query.get("tag").cloned());
let posts = create_resource(move || tag(), move |_| get_posts(tag()));
let tags = create_resource(|| (), move |_| get_tags());
let posts_view = move || {
posts.and_then(|posts| {
@ -126,18 +137,40 @@ pub fn PostList() -> impl IntoView {
})
};
let tags_view = move || {
tags.and_then(|tags| {
tags.iter()
.map(|tag| {
let tag = tag.clone();
view! { <A class="tag" href=format!("/posts?tag={}", tag.clone())>{tag}</A> }
})
.collect_view()
})
};
let filter_view = move || {
tag().map(|tag| Some(view! {
<div class="mx-auto max-w-3xl mb-5">
Tag sélectionné : <A class="tag" href="/posts".to_string()>{tag}<leptos_icons::Icon icon=icondata::IoClose class="scale-125 ml-1 inline" /></A>
</div>
}))
match tag() {
Some(tag) => {
view! {
<A class="tag" href="/posts".to_string()>{tag}<leptos_icons::Icon icon=icondata::IoClose class="scale-125 ml-1 inline" /></A>
}.into_view()
},
None => {
view! {
<div class="flex flex-wrap gap-2">
{tags_view}
</div>
}.into_view()
}
}
};
view! {
<Suspense fallback=move || view! { <Loading title="Chargement des posts...".to_string() /> }>
<Nav/>
{filter_view}
<div class="mx-auto max-w-3xl mb-5">
{filter_view}
</div>
<main class="posts">
<div class="posts__cards">{posts_view}</div>
</main>