v6/src/generator/archive.rs

78 lines
1.9 KiB
Rust

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<HtmlContent>]) {
let mut years: HashMap<i32, Vec<&Post<HtmlContent>>> = 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::<Vec<_>>();
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<HtmlContent>>)>,
}
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<HtmlContent>],
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<HtmlContent>],
pagination_info: PaginationInfo,
) -> Self {
Self {
posts,
pagination_info,
..*self
}
}
}
impl<'a> YearTemplate<'a> {
fn permalink(&self) -> String {
format!("/{}/", self.year)
}
}