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.

90 lines
3.3KB

  1. use tera::{Tera, Context};
  2. use errors::Result;
  3. static DEFAULT_TPL: &str = include_str!("default_tpl.html");
  4. macro_rules! render_default_tpl {
  5. ($filename: expr, $url: expr) => {
  6. {
  7. let mut context = Context::new();
  8. context.add("filename", $filename);
  9. context.add("url", $url);
  10. Tera::one_off(DEFAULT_TPL, &context, true).map_err(|e| e.into())
  11. }
  12. };
  13. }
  14. /// Renders the given template with the given context, but also ensures that, if the default file
  15. /// is not found, it will look up for the equivalent template for the current theme if there is one.
  16. /// Lastly, if it's a default template (index, section or page), it will just return an empty string
  17. /// to avoid an error if there isn't a template with that name
  18. pub fn render_template(name: &str, tera: &Tera, context: &Context, theme: Option<String>) -> Result<String> {
  19. if tera.templates.contains_key(name) {
  20. return tera
  21. .render(name, context)
  22. .map_err(|e| e.into());
  23. }
  24. if let Some(ref t) = theme {
  25. return tera
  26. .render(&format!("{}/templates/{}", t, name), context)
  27. .map_err(|e| e.into());
  28. }
  29. // maybe it's a default one?
  30. match name {
  31. "index.html" | "section.html" => {
  32. render_default_tpl!(name, "https://www.getgutenberg.io/documentation/templates/pages-sections/#section-variables")
  33. },
  34. "page.html" => {
  35. render_default_tpl!(name, "https://www.getgutenberg.io/documentation/templates/pages-sections/#page-variables")
  36. },
  37. "tag.html" | "tags.html" | "category.html" | "categories.html" => {
  38. render_default_tpl!(name, "https://www.getgutenberg.io/documentation/templates/tags-categories/")
  39. },
  40. _ => bail!("Tried to render `{}` but the template wasn't found", name)
  41. }
  42. }
  43. /// Rewrites the path from extend/macros of the theme used to ensure
  44. /// that they will point to the right place (theme/templates/...)
  45. /// Include is NOT supported as it would be a pain to add and using blocks
  46. /// or macros is always better anyway for themes
  47. pub fn rewrite_theme_paths(tera: &mut Tera, theme: &str) {
  48. // We want to match the paths in the templates to the new names
  49. for tpl in tera.templates.values_mut() {
  50. // First the parent if there is none
  51. if let Some(ref p) = tpl.parent.clone() {
  52. tpl.parent = Some(format!("{}/templates/{}", theme, p));
  53. }
  54. // Next the macros import
  55. let mut updated = vec![];
  56. for &(ref filename, ref namespace) in &tpl.imported_macro_files {
  57. updated.push((format!("{}/templates/{}", theme, filename), namespace.to_string()));
  58. }
  59. tpl.imported_macro_files = updated;
  60. }
  61. }
  62. #[cfg(test)]
  63. mod tests {
  64. use tera::Tera;
  65. use super::{rewrite_theme_paths};
  66. #[test]
  67. fn can_rewrite_all_paths_of_theme() {
  68. let mut tera = Tera::parse("test-templates/*.html").unwrap();
  69. rewrite_theme_paths(&mut tera, "hyde");
  70. // special case to make the test work: we also rename the files to
  71. // match the imports
  72. for (key, val) in tera.templates.clone() {
  73. tera.templates.insert(format!("hyde/templates/{}", key), val.clone());
  74. }
  75. tera.build_inheritance_chains().unwrap();
  76. }
  77. }