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.

214 lines
7.0KB

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