You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
9.1KB

  1. //! What we are sending to the templates when rendering them
  2. use std::collections::HashMap;
  3. use tera::{Map, Value};
  4. use content::{Page, Section};
  5. use library::Library;
  6. use rendering::Header;
  7. #[derive(Clone, Debug, PartialEq, Serialize)]
  8. pub struct TranslatedContent<'a> {
  9. lang: &'a str,
  10. permalink: &'a str,
  11. title: &'a Option<String>,
  12. }
  13. impl<'a> TranslatedContent<'a> {
  14. // copypaste eh, not worth creating an enum imo
  15. pub fn find_all_sections(section: &'a Section, library: &'a Library) -> Vec<Self> {
  16. let mut translations = vec![];
  17. for key in &section.translations {
  18. let other = library.get_section_by_key(*key);
  19. translations.push(TranslatedContent {
  20. lang: &other.lang,
  21. permalink: &other.permalink,
  22. title: &other.meta.title,
  23. });
  24. }
  25. translations
  26. }
  27. pub fn find_all_pages(page: &'a Page, library: &'a Library) -> Vec<Self> {
  28. let mut translations = vec![];
  29. for key in &page.translations {
  30. let other = library.get_page_by_key(*key);
  31. translations.push(TranslatedContent {
  32. lang: &other.lang,
  33. permalink: &other.permalink,
  34. title: &other.meta.title,
  35. });
  36. }
  37. translations
  38. }
  39. }
  40. #[derive(Clone, Debug, PartialEq, Serialize)]
  41. pub struct SerializingPage<'a> {
  42. relative_path: &'a str,
  43. content: &'a str,
  44. permalink: &'a str,
  45. slug: &'a str,
  46. ancestors: Vec<String>,
  47. title: &'a Option<String>,
  48. description: &'a Option<String>,
  49. date: &'a Option<String>,
  50. year: Option<i32>,
  51. month: Option<u32>,
  52. day: Option<u32>,
  53. taxonomies: &'a HashMap<String, Vec<String>>,
  54. extra: &'a Map<String, Value>,
  55. path: &'a str,
  56. components: &'a [String],
  57. summary: &'a Option<String>,
  58. word_count: Option<usize>,
  59. reading_time: Option<usize>,
  60. assets: &'a [String],
  61. draft: bool,
  62. lang: &'a str,
  63. lighter: Option<Box<SerializingPage<'a>>>,
  64. heavier: Option<Box<SerializingPage<'a>>>,
  65. earlier: Option<Box<SerializingPage<'a>>>,
  66. later: Option<Box<SerializingPage<'a>>>,
  67. translations: Vec<TranslatedContent<'a>>,
  68. }
  69. impl<'a> SerializingPage<'a> {
  70. /// Grabs all the data from a page, including sibling pages
  71. pub fn from_page(page: &'a Page, library: &'a Library) -> Self {
  72. let mut year = None;
  73. let mut month = None;
  74. let mut day = None;
  75. if let Some(d) = page.meta.datetime_tuple {
  76. year = Some(d.0);
  77. month = Some(d.1);
  78. day = Some(d.2);
  79. }
  80. let pages = library.pages();
  81. let lighter = page
  82. .lighter
  83. .map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
  84. let heavier = page
  85. .heavier
  86. .map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
  87. let earlier = page
  88. .earlier
  89. .map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
  90. let later = page
  91. .later
  92. .map(|k| Box::new(Self::from_page_basic(pages.get(k).unwrap(), Some(library))));
  93. let ancestors = page
  94. .ancestors
  95. .iter()
  96. .map(|k| library.get_section_by_key(*k).file.relative.clone())
  97. .collect();
  98. let translations = TranslatedContent::find_all_pages(page, library);
  99. SerializingPage {
  100. relative_path: &page.file.relative,
  101. ancestors,
  102. content: &page.content,
  103. permalink: &page.permalink,
  104. slug: &page.slug,
  105. title: &page.meta.title,
  106. description: &page.meta.description,
  107. extra: &page.meta.extra,
  108. date: &page.meta.date,
  109. year,
  110. month,
  111. day,
  112. taxonomies: &page.meta.taxonomies,
  113. path: &page.path,
  114. components: &page.components,
  115. summary: &page.summary,
  116. word_count: page.word_count,
  117. reading_time: page.reading_time,
  118. assets: &page.serialized_assets,
  119. draft: page.is_draft(),
  120. lang: &page.lang,
  121. lighter,
  122. heavier,
  123. earlier,
  124. later,
  125. translations,
  126. }
  127. }
  128. /// Same as from_page but does not fill sibling pages
  129. pub fn from_page_basic(page: &'a Page, library: Option<&'a Library>) -> Self {
  130. let mut year = None;
  131. let mut month = None;
  132. let mut day = None;
  133. if let Some(d) = page.meta.datetime_tuple {
  134. year = Some(d.0);
  135. month = Some(d.1);
  136. day = Some(d.2);
  137. }
  138. let ancestors = if let Some(ref lib) = library {
  139. page.ancestors
  140. .iter()
  141. .map(|k| lib.get_section_by_key(*k).file.relative.clone())
  142. .collect()
  143. } else {
  144. vec![]
  145. };
  146. let translations = if let Some(ref lib) = library {
  147. TranslatedContent::find_all_pages(page, lib)
  148. } else {
  149. vec![]
  150. };
  151. SerializingPage {
  152. relative_path: &page.file.relative,
  153. ancestors,
  154. content: &page.content,
  155. permalink: &page.permalink,
  156. slug: &page.slug,
  157. title: &page.meta.title,
  158. description: &page.meta.description,
  159. extra: &page.meta.extra,
  160. date: &page.meta.date,
  161. year,
  162. month,
  163. day,
  164. taxonomies: &page.meta.taxonomies,
  165. path: &page.path,
  166. components: &page.components,
  167. summary: &page.summary,
  168. word_count: page.word_count,
  169. reading_time: page.reading_time,
  170. assets: &page.serialized_assets,
  171. draft: page.is_draft(),
  172. lang: &page.lang,
  173. lighter: None,
  174. heavier: None,
  175. earlier: None,
  176. later: None,
  177. translations,
  178. }
  179. }
  180. }
  181. #[derive(Clone, Debug, PartialEq, Serialize)]
  182. pub struct SerializingSection<'a> {
  183. relative_path: &'a str,
  184. content: &'a str,
  185. permalink: &'a str,
  186. ancestors: Vec<String>,
  187. title: &'a Option<String>,
  188. description: &'a Option<String>,
  189. extra: &'a HashMap<String, Value>,
  190. path: &'a str,
  191. components: &'a [String],
  192. word_count: Option<usize>,
  193. reading_time: Option<usize>,
  194. lang: &'a str,
  195. assets: &'a [String],
  196. pages: Vec<SerializingPage<'a>>,
  197. subsections: Vec<&'a str>,
  198. translations: Vec<TranslatedContent<'a>>,
  199. }
  200. impl<'a> SerializingSection<'a> {
  201. pub fn from_section(section: &'a Section, library: &'a Library) -> Self {
  202. let mut pages = Vec::with_capacity(section.pages.len());
  203. let mut subsections = Vec::with_capacity(section.subsections.len());
  204. for k in &section.pages {
  205. pages.push(library.get_page_by_key(*k).to_serialized_basic(library));
  206. }
  207. for k in &section.subsections {
  208. subsections.push(library.get_section_path_by_key(*k));
  209. }
  210. let ancestors = section
  211. .ancestors
  212. .iter()
  213. .map(|k| library.get_section_by_key(*k).file.relative.clone())
  214. .collect();
  215. let translations = TranslatedContent::find_all_sections(section, library);
  216. SerializingSection {
  217. relative_path: &section.file.relative,
  218. ancestors,
  219. content: &section.content,
  220. permalink: &section.permalink,
  221. title: &section.meta.title,
  222. description: &section.meta.description,
  223. extra: &section.meta.extra,
  224. path: &section.path,
  225. components: &section.components,
  226. word_count: section.word_count,
  227. reading_time: section.reading_time,
  228. assets: &section.serialized_assets,
  229. lang: &section.lang,
  230. pages,
  231. subsections,
  232. translations,
  233. }
  234. }
  235. /// Same as from_section but doesn't fetch pages and sections
  236. pub fn from_section_basic(section: &'a Section, library: Option<&'a Library>) -> Self {
  237. let ancestors = if let Some(ref lib) = library {
  238. section
  239. .ancestors
  240. .iter()
  241. .map(|k| lib.get_section_by_key(*k).file.relative.clone())
  242. .collect()
  243. } else {
  244. vec![]
  245. };
  246. let translations = if let Some(ref lib) = library {
  247. TranslatedContent::find_all_sections(section, lib)
  248. } else {
  249. vec![]
  250. };
  251. SerializingSection {
  252. relative_path: &section.file.relative,
  253. ancestors,
  254. content: &section.content,
  255. permalink: &section.permalink,
  256. title: &section.meta.title,
  257. description: &section.meta.description,
  258. extra: &section.meta.extra,
  259. path: &section.path,
  260. components: &section.components,
  261. word_count: section.word_count,
  262. reading_time: section.reading_time,
  263. assets: &section.serialized_assets,
  264. lang: &section.lang,
  265. pages: vec![],
  266. subsections: vec![],
  267. translations,
  268. }
  269. }
  270. }