A static site generator written in Rust
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.

render.rs 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. use comrak::{markdown_to_html, ComrakOptions};
  2. use config::Config;
  3. use post::Post;
  4. pub fn render_post(layout: &str, post_template: &str, post: &Post, config: &Config) -> String {
  5. layout
  6. .replace(
  7. "{{ page_title }}",
  8. &format!("{} | {}", post.title, config.site_name),
  9. )
  10. .replace(
  11. "{{ contents }}",
  12. &post_template.replace("{{ title }}", &post.title).replace(
  13. "{{ body }}",
  14. &markdown_to_html(&post.body, &ComrakOptions::default()),
  15. ),
  16. )
  17. }
  18. pub fn render_post_listing(
  19. layout: &str,
  20. post_listing_template: &str,
  21. post_item_template: &str,
  22. posts: &Vec<Post>,
  23. config: &Config,
  24. ) -> String {
  25. layout
  26. .replace("{{ page_title }}", &format!("{}", config.site_name))
  27. .replace(
  28. "{{ contents }}",
  29. &post_listing_template.replace(
  30. "{{ post_listing }}",
  31. &posts
  32. .iter()
  33. .map(|ref post| {
  34. post_item_template
  35. .replace("{{ slug }}", &post.slug)
  36. .replace("{{ title }}", &post.title)
  37. })
  38. .collect::<Vec<String>>()
  39. .join("\n"),
  40. ),
  41. )
  42. }
  43. #[cfg(test)]
  44. mod tests {
  45. #[allow(unused_imports)]
  46. use super::{render_post, render_post_listing, Config, Post};
  47. #[test]
  48. fn test_render_post() {
  49. let output = render_post(
  50. "<html><head><title>{{ page_title }}</title></head><body>{{ contents }}</body></html>",
  51. "<article><h1>{{ title }}</h1><div>{{ body }}</div></article>",
  52. &Post {
  53. title: String::from("hello world"),
  54. body: String::from("lorem ipsum dolor sit amet"),
  55. slug: String::from("hello-world"),
  56. },
  57. &Config {
  58. site_name: "Test Site".to_string(),
  59. },
  60. )
  61. .replace("\n", "");
  62. assert_eq!(
  63. "<html><head><title>hello world | Test Site</title></head><body><article><h1>hello world</h1><div><p>lorem ipsum dolor sit amet</p></div></article></body></html>",
  64. &output,
  65. );
  66. }
  67. #[test]
  68. fn test_render_post_listing() {
  69. let posts = vec![
  70. Post {
  71. title: String::from("First post"),
  72. body: String::from("lorem ipsum dolor sit amet"),
  73. slug: String::from("first-post"),
  74. },
  75. Post {
  76. title: String::from("Second post"),
  77. body: String::from("lorem ipsum dolor sit amet"),
  78. slug: String::from("second-post"),
  79. },
  80. Post {
  81. title: String::from("Third post"),
  82. body: String::from("lorem ipsum dolor sit amet"),
  83. slug: String::from("third-post"),
  84. },
  85. ];
  86. let output = render_post_listing(
  87. "<html><head><title>{{ page_title }}</title></head><body>{{ contents }}</body></html>",
  88. "<ul>{{ post_listing }}</ul>",
  89. "<li><a href=\"/{{ slug }}\">{{ title }}</a></li>",
  90. &posts,
  91. &Config {
  92. site_name: "Test Site".to_string(),
  93. },
  94. )
  95. .replace("\n", "");
  96. assert_eq!(
  97. "<html><head><title>Test Site</title></head><body><ul><li><a href=\"/first-post\">First post</a></li><li><a href=\"/second-post\">Second post</a></li><li><a href=\"/third-post\">Third post</a></li></ul></body></html>",
  98. &output,
  99. );
  100. }
  101. }