Add all tags in posts
This commit is contained in:
parent
91f2e4c116
commit
0436136cdd
2 changed files with 52 additions and 9 deletions
|
@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue