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.

235 lines
7.3KB

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