A static site generator written in Rust
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

render.rs 4.5KB

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