aboutsummaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-14 21:42:19 -0800
committerFuwn <[email protected]>2026-02-14 21:42:19 -0800
commit00c444373e8901e9a53e8a72fdc74b3ba84d9dcf (patch)
treee6a8c40c6206dab63b028421b8f63ae4bdbb1e98 /src/modules
parentfeat(blog): Sort blog listings and recent posts by true chronological date (diff)
downloadlocus-00c444373e8901e9a53e8a72fdc74b3ba84d9dcf.tar.xz
locus-00c444373e8901e9a53e8a72fdc74b3ba84d9dcf.zip
fix(blog): Remove extra whitespace on category pages without descriptions
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/blog/module.rs132
1 files changed, 100 insertions, 32 deletions
diff --git a/src/modules/blog/module.rs b/src/modules/blog/module.rs
index e16861a..bcb61da 100644
--- a/src/modules/blog/module.rs
+++ b/src/modules/blog/module.rs
@@ -73,38 +73,9 @@ pub fn module(router: &mut windmark::router::Router) {
);
};
let category_posts = visible_posts_for_blog(&posts, &category.notion_id);
- let post_listing = category_posts
- .iter()
- .map(|post| {
- let post_slug = slugify(&post.title);
-
- format!(
- "=> /blog/{}/{} {}{}",
- blog_slug,
- post_slug,
- post.title,
- post
- .description
- .as_ref()
- .filter(|description_text| !description_text.is_empty())
- .map_or_else(String::new, |description_text| format!(
- " ― {description_text}"
- ))
- )
- })
- .collect::<Vec<_>>()
- .join("\n");
success(
- &format!(
- "# {} ({})\n\n{}\n\n{}\n\n## Really Simple Syndication\n\nAccess \
- {0}'s RSS feed\n\n=> /blog/{}.xml here!",
- category.title,
- category_posts.len(),
- category.description.as_deref().unwrap_or(""),
- post_listing,
- blog_slug,
- ),
+ &render_blog_page(category, blog_slug.as_str(), &category_posts),
&context,
)
},
@@ -180,6 +151,51 @@ fn construct_header(post: &BlogPost) -> String {
fn slugify(text: &str) -> String { text.replace(' ', "_").to_lowercase() }
+fn render_blog_page(
+ category: &BlogCategory,
+ blog_slug: &str,
+ category_posts: &[&BlogPost],
+) -> String {
+ let post_listing = category_posts
+ .iter()
+ .map(|post| {
+ let post_slug = slugify(&post.title);
+
+ format!(
+ "=> /blog/{}/{} {}{}",
+ blog_slug,
+ post_slug,
+ post.title,
+ post
+ .description
+ .as_ref()
+ .filter(|description_text| !description_text.is_empty())
+ .map_or_else(String::new, |description_text| format!(
+ " ― {description_text}"
+ ))
+ )
+ })
+ .collect::<Vec<_>>()
+ .join("\n");
+ let description_block = category
+ .description
+ .as_deref()
+ .filter(|description_text| !description_text.is_empty())
+ .map_or_else(String::new, |description_text| {
+ format!("{description_text}\n\n")
+ });
+
+ format!(
+ "# {} ({})\n\n{}{post_listing}\n\n## Really Simple Syndication\n\nAccess \
+ {}'s RSS feed\n\n=> /blog/{}.xml here!",
+ category.title,
+ category_posts.len(),
+ description_block,
+ category.title,
+ blog_slug,
+ )
+}
+
fn parse_chronological_sort_key(raw_date: Option<&str>) -> i64 {
raw_date
.and_then(|date_text| {
@@ -427,8 +443,9 @@ pub fn refresh_loop() {
#[cfg(test)]
mod tests {
use super::{
- build_global_posts, build_rss_feed, find_visible_post_by_slug, slugify,
- visible_posts_for_blog, BLOG_CATEGORIES, BLOG_POSTS,
+ build_global_posts, build_rss_feed, find_visible_post_by_slug,
+ render_blog_page, slugify, visible_posts_for_blog, BLOG_CATEGORIES,
+ BLOG_POSTS,
};
use crate::modules::blog::config::{BlogCategory, BlogPost};
@@ -653,4 +670,55 @@ mod tests {
]
);
}
+
+ #[test]
+ fn render_blog_page_without_description_has_single_spacing_before_listing() {
+ let category = BlogCategory {
+ title: "The Daily".to_string(),
+ description: None,
+ priority: 1,
+ notion_id: "blog-id".to_string(),
+ };
+ let post = BlogPost {
+ title: "Entry One".to_string(),
+ description: None,
+ author: None,
+ created_raw: None,
+ created: None,
+ last_modified: None,
+ content: "content".to_string(),
+ blog_id: "blog-id".to_string(),
+ hidden: false,
+ };
+ let rendered = render_blog_page(&category, "the_daily", &[&post]);
+
+ assert!(rendered.contains("# The Daily (1)\n\n=> /blog/the_daily/entry_one Entry One"));
+ assert!(!rendered.contains("# The Daily (1)\n\n\n"));
+ }
+
+ #[test]
+ fn render_blog_page_with_description_keeps_expected_spacing() {
+ let category = BlogCategory {
+ title: "The Daily".to_string(),
+ description: Some("desc".to_string()),
+ priority: 1,
+ notion_id: "blog-id".to_string(),
+ };
+ let post = BlogPost {
+ title: "Entry One".to_string(),
+ description: None,
+ author: None,
+ created_raw: None,
+ created: None,
+ last_modified: None,
+ content: "content".to_string(),
+ blog_id: "blog-id".to_string(),
+ hidden: false,
+ };
+ let rendered = render_blog_page(&category, "the_daily", &[&post]);
+
+ assert!(rendered.contains(
+ "# The Daily (1)\n\ndesc\n\n=> /blog/the_daily/entry_one Entry One"
+ ));
+ }
}