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.

241 lines
7.5KB

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