This commit is contained in:
		| @@ -3,6 +3,7 @@ layout: blog | ||||
| title: Introduction to JavaScript Application testing  | ||||
| segments: | ||||
|   - blog | ||||
|   - featured | ||||
| published: true | ||||
| date: 2021-05-07T14:44:57.102Z # update date accordingly | ||||
| tags: | ||||
|   | ||||
| @@ -3,6 +3,7 @@ layout: blog | ||||
| title: "DevBreak #5 Joys and concerns of Engineering manager with Pavol Dudrík" | ||||
| segments: | ||||
|   - broadcasts | ||||
|   - featured | ||||
| published: true | ||||
| date: 2023-02-04T20:22:21.191Z | ||||
| thumbnail: /images/uploads/devbreak.jpeg | ||||
|   | ||||
| @@ -5,7 +5,7 @@ use crate::post_utils::post_parser::deserialize_date; | ||||
|  | ||||
| pub const BLOG_POST_PATH: &str = "_posts/blog"; | ||||
|  | ||||
| #[derive(Deserialize, Debug)] | ||||
| #[derive(Deserialize, Debug, Clone)] | ||||
| pub struct BlogPostMetadata { | ||||
|     pub title: String, | ||||
|     pub segments: Vec<String>, | ||||
|   | ||||
| @@ -1,15 +0,0 @@ | ||||
| use axum::http::StatusCode; | ||||
|  | ||||
| use crate::post_utils::{post_listing::get_post_list, post_parser::ParseResult}; | ||||
|  | ||||
| use super::blog_post_model::{BlogPostMetadata, BLOG_POST_PATH}; | ||||
|  | ||||
| pub async fn get_featured_blog_posts() -> Result<Vec<ParseResult<BlogPostMetadata>>, StatusCode> { | ||||
|     let mut post_list = get_post_list::<BlogPostMetadata>(BLOG_POST_PATH).await?; | ||||
|     post_list.retain(|post| post.metadata.segments.contains(&"featured".to_string())); | ||||
|     post_list.retain(|post| post.metadata.published); | ||||
|     post_list.sort_by_key(|post| post.metadata.date); | ||||
|     post_list.reverse(); | ||||
|  | ||||
|     Ok(post_list) | ||||
| } | ||||
| @@ -1,2 +1 @@ | ||||
| pub mod blog_post_model; | ||||
| pub mod featured_blog_posts; | ||||
|   | ||||
| @@ -1,12 +1,17 @@ | ||||
| use std::rc::Rc; | ||||
|  | ||||
| use askama::Template; | ||||
| use axum::http::StatusCode; | ||||
| use tokio::try_join; | ||||
|  | ||||
| use crate::{ | ||||
|     blog_posts::{blog_post_model::BlogPostMetadata, featured_blog_posts::get_featured_blog_posts}, | ||||
|     blog_posts::blog_post_model::{BlogPostMetadata, BLOG_POST_PATH}, | ||||
|     components::site_header::HeaderProps, | ||||
|     filters, | ||||
|     post_utils::{post_parser::ParseResult, tags::get_popular_tags}, | ||||
|     post_utils::{ | ||||
|         post_listing::get_post_list, post_parser::ParseResult, segments::ref_get_posts_by_segment, | ||||
|         tags::get_popular_tags, | ||||
|     }, | ||||
|     projects::{featured_projects::get_featured_projects, project_model::ProjectMetadata}, | ||||
| }; | ||||
|  | ||||
| @@ -15,21 +20,38 @@ use crate::{ | ||||
| pub struct IndexTemplate { | ||||
|     header_props: HeaderProps, | ||||
|     blog_tags: Vec<String>, | ||||
|     featured_blog_posts: Vec<ParseResult<BlogPostMetadata>>, | ||||
|     broadcasts_tags: Vec<String>, | ||||
|     featured_blog_posts: Vec<Rc<ParseResult<BlogPostMetadata>>>, | ||||
|     featured_projects: Vec<ParseResult<ProjectMetadata>>, | ||||
|     featured_broadcasts: Vec<Rc<ParseResult<BlogPostMetadata>>>, | ||||
| } | ||||
|  | ||||
| pub async fn render_index() -> Result<IndexTemplate, StatusCode> { | ||||
|     let (blog_tags, featured_blog_posts, featured_projects) = try_join!( | ||||
|     let (blog_tags, broadcasts_tags, all_posts, featured_projects) = try_join!( | ||||
|         get_popular_tags(Some("blog".to_string())), | ||||
|         get_featured_blog_posts(), | ||||
|         get_popular_tags(Some("broadcasts".to_string())), | ||||
|         get_post_list::<BlogPostMetadata>(BLOG_POST_PATH), | ||||
|         get_featured_projects() | ||||
|     )?; | ||||
|  | ||||
|     // Convert the all_posts into Rc<ParseResult<BlogPostMetadata>> | ||||
|     let all_posts_rc: Vec<Rc<ParseResult<BlogPostMetadata>>> = | ||||
|         all_posts.into_iter().map(Rc::new).collect(); | ||||
|  | ||||
|     let featured_blog_posts = | ||||
|         ref_get_posts_by_segment(&all_posts_rc, &["blog".to_string(), "featured".to_string()]); | ||||
|  | ||||
|     let featured_broadcasts = ref_get_posts_by_segment( | ||||
|         &all_posts_rc, | ||||
|         &["broadcasts".to_string(), "featured".to_string()], | ||||
|     ); | ||||
|  | ||||
|     Ok(IndexTemplate { | ||||
|         header_props: HeaderProps::default(), | ||||
|         blog_tags, | ||||
|         broadcasts_tags, | ||||
|         featured_blog_posts, | ||||
|         featured_projects, | ||||
|         featured_broadcasts, | ||||
|     }) | ||||
| } | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| pub mod post_listing; | ||||
| pub mod post_parser; | ||||
| pub mod segments; | ||||
| pub mod tags; | ||||
|   | ||||
| @@ -32,6 +32,7 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Clone)] | ||||
| pub struct ParseResult<Metadata> { | ||||
|     pub body: String, | ||||
|     pub metadata: Metadata, | ||||
|   | ||||
							
								
								
									
										51
									
								
								src/post_utils/segments.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/post_utils/segments.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| use std::rc::Rc; | ||||
|  | ||||
| use crate::blog_posts::blog_post_model::BlogPostMetadata; | ||||
|  | ||||
| use super::post_parser::ParseResult; | ||||
|  | ||||
| // // TODO convert segmetns to enum, find out how to serde to enum vlaue | ||||
| // pub fn get_posts_by_segment( | ||||
| //     post_list: &Vec<ParseResult<BlogPostMetadata>>, | ||||
| //     segments: &Vec<String>, | ||||
| // ) -> Vec<ParseResult<BlogPostMetadata>> { | ||||
| //     let mut filtered_posts: Vec<ParseResult<BlogPostMetadata>> = post_list | ||||
| //         .iter() | ||||
| //         .filter(|post| { | ||||
| //             segments | ||||
| //                 .iter() | ||||
| //                 .all(|segment| post.metadata.segments.contains(segment)) | ||||
| //         }) // Filter by segments | ||||
| //         .filter(|post| post.metadata.published) // Filter only published posts | ||||
| //         .cloned() | ||||
| //         .collect(); | ||||
|  | ||||
| //     // Sort by date in descending order | ||||
| //     filtered_posts.sort_by_key(|post| post.metadata.date); | ||||
| //     filtered_posts.reverse(); | ||||
|  | ||||
| //     filtered_posts | ||||
| // } | ||||
|  | ||||
| pub fn ref_get_posts_by_segment( | ||||
|     post_list: &[Rc<ParseResult<BlogPostMetadata>>], | ||||
|     segments: &[String], | ||||
| ) -> Vec<Rc<ParseResult<BlogPostMetadata>>> { | ||||
|     let mut filtered_posts: Vec<Rc<ParseResult<BlogPostMetadata>>> = post_list | ||||
|         .iter() // Use iter() to borrow instead of consuming the original vector | ||||
|         .filter(|post| { | ||||
|             let post = post.as_ref(); | ||||
|             segments | ||||
|                 .iter() | ||||
|                 .all(|segment| post.metadata.segments.contains(segment)) | ||||
|         }) // Filter by segments | ||||
|         .filter(|post| post.metadata.published) // Filter only published posts | ||||
|         .cloned() | ||||
|         .collect(); // Collect references to ParseResult<BlogPostMetadata> | ||||
|  | ||||
|     // Sort by date in descending order | ||||
|     filtered_posts.sort_by_key(|post| post.metadata.date); | ||||
|     filtered_posts.reverse(); | ||||
|  | ||||
|     filtered_posts | ||||
| } | ||||
| @@ -76,6 +76,33 @@ | ||||
|   <section id="showcase" class="col-span-2"> | ||||
|     {% include "sections/showcase.html" %} | ||||
|   </section> | ||||
|  | ||||
|   <section id="broadcasts" class="col-span-2"> | ||||
|     {% let segment = "broadcasts".to_string() %} | ||||
|     <h2 class="text-blue-950 font-bold text-2xl md:text-4xl m-5"><a href="/broadcasts" class="text-blue-950 no-underline">Broadcasts</a></h2> | ||||
|     <section id="broadcast-tags"> | ||||
|       <ul class="mx-5"> | ||||
|        {% for tag in broadcasts_tags %} | ||||
|         <li class="inline-block mx-0.5 p-0.5 md:text-xl"> | ||||
|           <a href="/{{segment}}/tags/{{tag}}" class="text-pink-950">#{{tag|capitalize}}</a> | ||||
|         </li> | ||||
|         {% endfor %} | ||||
|       </ul> | ||||
|     </section> | ||||
|     <hr class="border-slate-300 m-5"> | ||||
|  | ||||
|     <ul class="mx-5"> | ||||
|      {% for post in featured_broadcasts %} | ||||
|       <li> | ||||
|         {% include "components/blog_post_preview.html" %} | ||||
|         <hr class="border-slate-300 my-5 md:my-8"> | ||||
|       </li> | ||||
|      {% endfor %} | ||||
|     </ul> | ||||
|     <section class="text-center my-3 md:text-lg"> | ||||
|      <a href="/broadcasts">see all broadcasts</a>  | ||||
|     </section> | ||||
|   </section> | ||||
| </section> <!-- /.index-container --> | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user