use super::{ pagination::{render_paginated, PaginatableTemplate, PaginationInfo}, util::output_rendered_template, util::templates::{filters, TemplateCommon}, HtmlContent, Post, }; use askama::Template; use chrono::Datelike; use std::collections::HashMap; pub fn generate(posts: &[Post]) { let mut years: HashMap>> = HashMap::new(); for post in posts { let year_posts = years.entry(post.metadata.date.year()).or_default(); year_posts.push(post); } let mut years = years.into_iter().collect::>(); years.sort_by_key(|(year, _)| *year); years.reverse(); output_rendered_template(&ArchiveTemplate { years: &years }, "archive/index.html") .expect("generating archive"); for (year, posts) in years { let template = YearTemplate { year, posts: &[], pagination_info: Default::default(), }; render_paginated(&template, &posts, year.to_string()).expect("generate year"); } } #[derive(Template)] #[template(path = "archive.html")] struct ArchiveTemplate<'a> { years: &'a Vec<(i32, Vec<&'a Post>)>, } impl<'a> TemplateCommon for ArchiveTemplate<'a> {} impl<'a> ArchiveTemplate<'a> { fn permalink(&self) -> &'static str { "/archive/" } } #[derive(Template)] #[template(path = "year.html")] struct YearTemplate<'a> { year: i32, posts: &'a [&'a Post], pagination_info: PaginationInfo, } impl<'a> TemplateCommon for YearTemplate<'a> {} impl<'a> PaginatableTemplate<'a> for YearTemplate<'a> { fn with_posts( &'a self, posts: &'a [&'a Post], pagination_info: PaginationInfo, ) -> Self { Self { posts, pagination_info, ..*self } } } impl<'a> YearTemplate<'a> { fn permalink(&self) -> String { format!("/{}/", self.year) } }