2018-10-24 09:40:57 +00:00
|
|
|
//! What we are sending to the templates when rendering them
|
|
|
|
use std::collections::HashMap;
|
2021-01-05 20:39:25 +00:00
|
|
|
use std::collections::HashSet;
|
2019-12-06 12:11:30 +00:00
|
|
|
use std::path::Path;
|
2018-10-24 09:40:57 +00:00
|
|
|
|
2019-12-21 21:52:39 +00:00
|
|
|
use serde_derive::Serialize;
|
2018-10-31 07:18:57 +00:00
|
|
|
use tera::{Map, Value};
|
2018-10-24 09:40:57 +00:00
|
|
|
|
2019-12-21 21:52:39 +00:00
|
|
|
use crate::content::{Page, Section};
|
|
|
|
use crate::library::Library;
|
2019-10-14 13:12:19 +00:00
|
|
|
use rendering::Heading;
|
2018-10-24 09:40:57 +00:00
|
|
|
|
2019-01-04 19:31:31 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
|
|
|
pub struct TranslatedContent<'a> {
|
2019-01-29 18:20:03 +00:00
|
|
|
lang: &'a str,
|
2019-01-04 19:31:31 +00:00
|
|
|
permalink: &'a str,
|
|
|
|
title: &'a Option<String>,
|
2019-12-06 12:11:30 +00:00
|
|
|
/// The path to the markdown file; useful for retrieving the full page through
|
|
|
|
/// the `get_page` function.
|
|
|
|
path: &'a Path,
|
2019-01-04 19:31:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> TranslatedContent<'a> {
|
|
|
|
// copypaste eh, not worth creating an enum imo
|
|
|
|
pub fn find_all_sections(section: &'a Section, library: &'a Library) -> Vec<Self> {
|
|
|
|
let mut translations = vec![];
|
|
|
|
|
2021-01-05 20:39:25 +00:00
|
|
|
for key in library
|
|
|
|
.translations
|
|
|
|
.get(§ion.file.canonical)
|
|
|
|
.or(Some(&HashSet::new()))
|
|
|
|
.unwrap()
|
|
|
|
.iter()
|
|
|
|
{
|
2019-01-04 19:31:31 +00:00
|
|
|
let other = library.get_section_by_key(*key);
|
2019-01-04 19:34:20 +00:00
|
|
|
translations.push(TranslatedContent {
|
|
|
|
lang: &other.lang,
|
|
|
|
permalink: &other.permalink,
|
|
|
|
title: &other.meta.title,
|
2019-12-06 12:11:30 +00:00
|
|
|
path: &other.file.path,
|
2019-01-04 19:34:20 +00:00
|
|
|
});
|
2019-01-04 19:31:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
translations
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn find_all_pages(page: &'a Page, library: &'a Library) -> Vec<Self> {
|
|
|
|
let mut translations = vec![];
|
|
|
|
|
2021-01-05 20:39:25 +00:00
|
|
|
for key in
|
|
|
|
library.translations.get(&page.file.canonical).or(Some(&HashSet::new())).unwrap().iter()
|
|
|
|
{
|
2019-01-04 19:31:31 +00:00
|
|
|
let other = library.get_page_by_key(*key);
|
2019-01-04 19:34:20 +00:00
|
|
|
translations.push(TranslatedContent {
|
|
|
|
lang: &other.lang,
|
|
|
|
permalink: &other.permalink,
|
|
|
|
title: &other.meta.title,
|
2019-12-06 12:11:30 +00:00
|
|
|
path: &other.file.path,
|
2019-01-04 19:34:20 +00:00
|
|
|
});
|
2019-01-04 19:31:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
translations
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-24 09:40:57 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
|
|
|
pub struct SerializingPage<'a> {
|
|
|
|
relative_path: &'a str,
|
|
|
|
content: &'a str,
|
|
|
|
permalink: &'a str,
|
|
|
|
slug: &'a str,
|
|
|
|
ancestors: Vec<String>,
|
|
|
|
title: &'a Option<String>,
|
|
|
|
description: &'a Option<String>,
|
2019-10-07 14:39:33 +00:00
|
|
|
updated: &'a Option<String>,
|
2018-10-24 09:40:57 +00:00
|
|
|
date: &'a Option<String>,
|
|
|
|
year: Option<i32>,
|
|
|
|
month: Option<u32>,
|
|
|
|
day: Option<u32>,
|
|
|
|
taxonomies: &'a HashMap<String, Vec<String>>,
|
|
|
|
extra: &'a Map<String, Value>,
|
|
|
|
path: &'a str,
|
|
|
|
components: &'a [String],
|
|
|
|
summary: &'a Option<String>,
|
2019-10-14 13:12:19 +00:00
|
|
|
toc: &'a [Heading],
|
2018-10-24 09:40:57 +00:00
|
|
|
word_count: Option<usize>,
|
|
|
|
reading_time: Option<usize>,
|
2018-10-24 09:49:09 +00:00
|
|
|
assets: &'a [String],
|
2018-10-24 09:40:57 +00:00
|
|
|
draft: bool,
|
2019-01-29 18:20:03 +00:00
|
|
|
lang: &'a str,
|
2018-10-24 09:40:57 +00:00
|
|
|
lighter: Option<Box<SerializingPage<'a>>>,
|
|
|
|
heavier: Option<Box<SerializingPage<'a>>>,
|
|
|
|
earlier: Option<Box<SerializingPage<'a>>>,
|
|
|
|
later: Option<Box<SerializingPage<'a>>>,
|
2019-01-04 19:31:31 +00:00
|
|
|
translations: Vec<TranslatedContent<'a>>,
|
2018-10-24 09:40:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> SerializingPage<'a> {
|
|
|
|
/// Grabs all the data from a page, including sibling pages
|
|
|
|
pub fn from_page(page: &'a Page, library: &'a Library) -> Self {
|
|
|
|
let mut year = None;
|
|
|
|
let mut month = None;
|
|
|
|
let mut day = None;
|
|
|
|
if let Some(d) = page.meta.datetime_tuple {
|
|
|
|
year = Some(d.0);
|
|
|
|
month = Some(d.1);
|
|
|
|
day = Some(d.2);
|
|
|
|
}
|
|
|
|
let pages = library.pages();
|
2018-10-31 07:18:57 +00:00
|
|
|
let lighter = page
|
|
|
|
.lighter
|
|
|
|
.map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
|
|
|
|
let heavier = page
|
|
|
|
.heavier
|
|
|
|
.map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
|
|
|
|
let earlier = page
|
|
|
|
.earlier
|
|
|
|
.map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
|
|
|
|
let later = page
|
|
|
|
.later
|
|
|
|
.map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
|
|
|
|
let ancestors = page
|
|
|
|
.ancestors
|
|
|
|
.iter()
|
|
|
|
.map(|k| library.get_section_by_key(*k).file.relative.clone())
|
|
|
|
.collect();
|
2018-10-24 09:40:57 +00:00
|
|
|
|
2019-01-04 19:31:31 +00:00
|
|
|
let translations = TranslatedContent::find_all_pages(page, library);
|
|
|
|
|
2018-10-24 09:40:57 +00:00
|
|
|
SerializingPage {
|
|
|
|
relative_path: &page.file.relative,
|
|
|
|
ancestors,
|
|
|
|
content: &page.content,
|
|
|
|
permalink: &page.permalink,
|
|
|
|
slug: &page.slug,
|
|
|
|
title: &page.meta.title,
|
|
|
|
description: &page.meta.description,
|
|
|
|
extra: &page.meta.extra,
|
2019-10-07 14:39:33 +00:00
|
|
|
updated: &page.meta.updated,
|
2018-10-24 09:40:57 +00:00
|
|
|
date: &page.meta.date,
|
|
|
|
year,
|
|
|
|
month,
|
|
|
|
day,
|
|
|
|
taxonomies: &page.meta.taxonomies,
|
|
|
|
path: &page.path,
|
|
|
|
components: &page.components,
|
|
|
|
summary: &page.summary,
|
2019-10-14 13:12:19 +00:00
|
|
|
toc: &page.toc,
|
2018-10-24 09:40:57 +00:00
|
|
|
word_count: page.word_count,
|
|
|
|
reading_time: page.reading_time,
|
2018-10-24 09:49:09 +00:00
|
|
|
assets: &page.serialized_assets,
|
2018-10-24 09:40:57 +00:00
|
|
|
draft: page.is_draft(),
|
2018-12-28 12:24:49 +00:00
|
|
|
lang: &page.lang,
|
2018-10-24 09:40:57 +00:00
|
|
|
lighter,
|
|
|
|
heavier,
|
|
|
|
earlier,
|
|
|
|
later,
|
2019-01-04 19:31:31 +00:00
|
|
|
translations,
|
2018-10-24 09:40:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-01 19:00:21 +00:00
|
|
|
/// currently only used in testing
|
|
|
|
pub fn get_title(&'a self) -> &'a Option<String> {
|
|
|
|
&self.title
|
|
|
|
}
|
|
|
|
|
2018-10-24 09:40:57 +00:00
|
|
|
/// Same as from_page but does not fill sibling pages
|
|
|
|
pub fn from_page_basic(page: &'a Page, library: Option<&'a Library>) -> Self {
|
|
|
|
let mut year = None;
|
|
|
|
let mut month = None;
|
|
|
|
let mut day = None;
|
|
|
|
if let Some(d) = page.meta.datetime_tuple {
|
|
|
|
year = Some(d.0);
|
|
|
|
month = Some(d.1);
|
|
|
|
day = Some(d.2);
|
|
|
|
}
|
|
|
|
let ancestors = if let Some(ref lib) = library {
|
2018-10-31 07:18:57 +00:00
|
|
|
page.ancestors
|
|
|
|
.iter()
|
|
|
|
.map(|k| lib.get_section_by_key(*k).file.relative.clone())
|
|
|
|
.collect()
|
2018-10-24 09:40:57 +00:00
|
|
|
} else {
|
|
|
|
vec![]
|
|
|
|
};
|
|
|
|
|
2019-01-04 19:31:31 +00:00
|
|
|
let translations = if let Some(ref lib) = library {
|
|
|
|
TranslatedContent::find_all_pages(page, lib)
|
|
|
|
} else {
|
|
|
|
vec![]
|
|
|
|
};
|
|
|
|
|
2018-10-24 09:40:57 +00:00
|
|
|
SerializingPage {
|
|
|
|
relative_path: &page.file.relative,
|
|
|
|
ancestors,
|
|
|
|
content: &page.content,
|
|
|
|
permalink: &page.permalink,
|
|
|
|
slug: &page.slug,
|
|
|
|
title: &page.meta.title,
|
|
|
|
description: &page.meta.description,
|
|
|
|
extra: &page.meta.extra,
|
2019-10-07 14:39:33 +00:00
|
|
|
updated: &page.meta.updated,
|
2018-10-24 09:40:57 +00:00
|
|
|
date: &page.meta.date,
|
|
|
|
year,
|
|
|
|
month,
|
|
|
|
day,
|
|
|
|
taxonomies: &page.meta.taxonomies,
|
|
|
|
path: &page.path,
|
|
|
|
components: &page.components,
|
|
|
|
summary: &page.summary,
|
2019-10-14 13:12:19 +00:00
|
|
|
toc: &page.toc,
|
2018-10-24 09:40:57 +00:00
|
|
|
word_count: page.word_count,
|
|
|
|
reading_time: page.reading_time,
|
2018-10-24 09:49:09 +00:00
|
|
|
assets: &page.serialized_assets,
|
2018-10-24 09:40:57 +00:00
|
|
|
draft: page.is_draft(),
|
2018-12-28 12:24:49 +00:00
|
|
|
lang: &page.lang,
|
2018-10-24 09:40:57 +00:00
|
|
|
lighter: None,
|
|
|
|
heavier: None,
|
|
|
|
earlier: None,
|
|
|
|
later: None,
|
2019-01-04 19:31:31 +00:00
|
|
|
translations,
|
2018-10-24 09:40:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
|
|
|
pub struct SerializingSection<'a> {
|
|
|
|
relative_path: &'a str,
|
|
|
|
content: &'a str,
|
|
|
|
permalink: &'a str,
|
|
|
|
ancestors: Vec<String>,
|
|
|
|
title: &'a Option<String>,
|
|
|
|
description: &'a Option<String>,
|
2019-11-26 19:36:52 +00:00
|
|
|
extra: &'a Map<String, Value>,
|
2018-10-24 09:40:57 +00:00
|
|
|
path: &'a str,
|
|
|
|
components: &'a [String],
|
2019-10-14 13:12:19 +00:00
|
|
|
toc: &'a [Heading],
|
2018-10-24 09:40:57 +00:00
|
|
|
word_count: Option<usize>,
|
|
|
|
reading_time: Option<usize>,
|
2019-01-29 18:20:03 +00:00
|
|
|
lang: &'a str,
|
2018-10-31 07:18:57 +00:00
|
|
|
assets: &'a [String],
|
2018-10-24 09:40:57 +00:00
|
|
|
pages: Vec<SerializingPage<'a>>,
|
|
|
|
subsections: Vec<&'a str>,
|
2019-01-04 19:31:31 +00:00
|
|
|
translations: Vec<TranslatedContent<'a>>,
|
2018-10-24 09:40:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> SerializingSection<'a> {
|
|
|
|
pub fn from_section(section: &'a Section, library: &'a Library) -> Self {
|
|
|
|
let mut pages = Vec::with_capacity(section.pages.len());
|
|
|
|
let mut subsections = Vec::with_capacity(section.subsections.len());
|
|
|
|
|
|
|
|
for k in §ion.pages {
|
2019-01-21 16:54:44 +00:00
|
|
|
pages.push(library.get_page_by_key(*k).to_serialized_basic(library));
|
2018-10-24 09:40:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for k in §ion.subsections {
|
|
|
|
subsections.push(library.get_section_path_by_key(*k));
|
|
|
|
}
|
|
|
|
|
2018-10-31 07:18:57 +00:00
|
|
|
let ancestors = section
|
|
|
|
.ancestors
|
|
|
|
.iter()
|
|
|
|
.map(|k| library.get_section_by_key(*k).file.relative.clone())
|
|
|
|
.collect();
|
2019-01-04 19:31:31 +00:00
|
|
|
let translations = TranslatedContent::find_all_sections(section, library);
|
2018-10-24 09:40:57 +00:00
|
|
|
|
|
|
|
SerializingSection {
|
|
|
|
relative_path: §ion.file.relative,
|
|
|
|
ancestors,
|
|
|
|
content: §ion.content,
|
|
|
|
permalink: §ion.permalink,
|
|
|
|
title: §ion.meta.title,
|
|
|
|
description: §ion.meta.description,
|
|
|
|
extra: §ion.meta.extra,
|
|
|
|
path: §ion.path,
|
|
|
|
components: §ion.components,
|
2019-10-14 13:12:19 +00:00
|
|
|
toc: §ion.toc,
|
2018-10-24 09:40:57 +00:00
|
|
|
word_count: section.word_count,
|
|
|
|
reading_time: section.reading_time,
|
2018-10-24 09:49:09 +00:00
|
|
|
assets: §ion.serialized_assets,
|
2018-12-28 12:24:49 +00:00
|
|
|
lang: §ion.lang,
|
2018-10-24 09:40:57 +00:00
|
|
|
pages,
|
|
|
|
subsections,
|
2019-01-04 19:31:31 +00:00
|
|
|
translations,
|
2018-10-24 09:40:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-10 17:21:53 +00:00
|
|
|
/// Same as from_section but doesn't fetch pages
|
2018-10-24 09:40:57 +00:00
|
|
|
pub fn from_section_basic(section: &'a Section, library: Option<&'a Library>) -> Self {
|
2019-08-10 17:21:53 +00:00
|
|
|
let mut ancestors = vec![];
|
|
|
|
let mut translations = vec![];
|
|
|
|
let mut subsections = vec![];
|
|
|
|
if let Some(ref lib) = library {
|
|
|
|
ancestors = section
|
2018-10-31 07:18:57 +00:00
|
|
|
.ancestors
|
|
|
|
.iter()
|
|
|
|
.map(|k| lib.get_section_by_key(*k).file.relative.clone())
|
2019-08-10 17:21:53 +00:00
|
|
|
.collect();
|
|
|
|
translations = TranslatedContent::find_all_sections(section, lib);
|
|
|
|
subsections =
|
|
|
|
section.subsections.iter().map(|k| lib.get_section_path_by_key(*k)).collect();
|
|
|
|
}
|
2019-01-04 19:31:31 +00:00
|
|
|
|
2018-10-24 09:40:57 +00:00
|
|
|
SerializingSection {
|
|
|
|
relative_path: §ion.file.relative,
|
|
|
|
ancestors,
|
|
|
|
content: §ion.content,
|
|
|
|
permalink: §ion.permalink,
|
|
|
|
title: §ion.meta.title,
|
|
|
|
description: §ion.meta.description,
|
|
|
|
extra: §ion.meta.extra,
|
|
|
|
path: §ion.path,
|
|
|
|
components: §ion.components,
|
2019-10-14 13:12:19 +00:00
|
|
|
toc: §ion.toc,
|
2018-10-24 09:40:57 +00:00
|
|
|
word_count: section.word_count,
|
|
|
|
reading_time: section.reading_time,
|
2018-10-24 09:49:09 +00:00
|
|
|
assets: §ion.serialized_assets,
|
2018-12-28 12:24:49 +00:00
|
|
|
lang: §ion.lang,
|
2018-10-24 09:40:57 +00:00
|
|
|
pages: vec![],
|
2019-08-10 17:21:53 +00:00
|
|
|
subsections,
|
2019-01-04 19:31:31 +00:00
|
|
|
translations,
|
2018-10-24 09:40:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|