From 2d949249c3d68e7c37e92055f57ea61e06425a1d Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Sun, 11 Jun 2017 02:52:39 +0900 Subject: [PATCH] Add trailing slash to paths and permalinks. Fix #85 --- CHANGELOG.md | 1 + src/config.rs | 20 ++++++++++++------ src/content/page.rs | 9 +++++--- src/content/pagination.rs | 43 ++++++++++++++++++++------------------- src/content/section.rs | 2 +- tests/site.rs | 24 +++++++++++----------- 6 files changed, 56 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d2f56f3..cc5fcfdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Sort individual tag/category pages by date - Add extra builtin shortcode for Streamable videos +- `path` and `permalink` now end with a `/` ## 0.0.6 (2017-05-24) diff --git a/src/config.rs b/src/config.rs index ec73d168..6f7fd1f5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -90,12 +90,20 @@ impl Config { /// Makes a url, taking into account that the base url might have a trailing slash pub fn make_permalink(&self, path: &str) -> String { - if self.base_url.ends_with('/') && path.starts_with('/') { - format!("{}{}", self.base_url, &path[1..]) + let trailing_bit = if path.ends_with('/') { "" } else { "/" }; + + // Index section with a base url that has a trailing slash + if self.base_url.ends_with('/') && path == "/" { + self.base_url.clone() + } else if path == "/" { + // index section with a base url that doesn't have a trailing slash + format!("{}/", self.base_url) + } else if self.base_url.ends_with('/') && path.starts_with('/') { + format!("{}{}{}", self.base_url, &path[1..], trailing_bit) } else if self.base_url.ends_with('/') { - format!("{}{}", self.base_url, path) + format!("{}{}{}", self.base_url, path, trailing_bit) } else { - format!("{}/{}", self.base_url, path) + format!("{}/{}{}", self.base_url, path, trailing_bit) } } } @@ -192,13 +200,13 @@ hello = "world" fn can_make_url_with_non_trailing_slash_base_url() { let mut config = Config::default(); config.base_url = "http://vincent.is".to_string(); - assert_eq!(config.make_permalink("hello"), "http://vincent.is/hello"); + assert_eq!(config.make_permalink("hello"), "http://vincent.is/hello/"); } #[test] fn can_make_url_with_trailing_slash_path() { let mut config = Config::default(); config.base_url = "http://vincent.is/".to_string(); - assert_eq!(config.make_permalink("/hello"), "http://vincent.is/hello"); + assert_eq!(config.make_permalink("/hello"), "http://vincent.is/hello/"); } } diff --git a/src/content/page.rs b/src/content/page.rs index 667b88cf..ad389178 100644 --- a/src/content/page.rs +++ b/src/content/page.rs @@ -91,6 +91,9 @@ impl Page { format!("{}/{}", page.file.components.join("/"), page.slug) }; } + if !page.path.ends_with('/') { + page.path = format!("{}/", page.path); + } page.permalink = config.make_permalink(&page.path); Ok(page) @@ -231,8 +234,8 @@ Hello world"#; let res = Page::parse(Path::new("content/posts/intro/start.md"), content, &conf); assert!(res.is_ok()); let page = res.unwrap(); - assert_eq!(page.path, "posts/intro/hello-world"); - assert_eq!(page.permalink, "http://hello.com/posts/intro/hello-world"); + assert_eq!(page.path, "posts/intro/hello-world/"); + assert_eq!(page.permalink, "http://hello.com/posts/intro/hello-world/"); } #[test] @@ -246,7 +249,7 @@ Hello world"#; let res = Page::parse(Path::new("start.md"), content, &config); assert!(res.is_ok()); let page = res.unwrap(); - assert_eq!(page.path, "hello-world"); + assert_eq!(page.path, "hello-world/"); assert_eq!(page.permalink, config.make_permalink("hello-world")); } diff --git a/src/content/pagination.rs b/src/content/pagination.rs index 12701750..a94f7311 100644 --- a/src/content/pagination.rs +++ b/src/content/pagination.rs @@ -74,17 +74,18 @@ impl<'a> Paginator<'a> { continue; } - let page_path = format!("{}/{}", paginate_path, index + 1); - let permalink = if section.permalink.ends_with('/') { - format!("{}{}", section.permalink, page_path) + let page_path = format!("{}/{}/", paginate_path, index + 1); + let permalink = format!("{}{}", section.permalink, page_path); + let pager_path = if section.is_index() { + page_path } else { - format!("{}/{}", section.permalink, page_path) + format!("{}{}", section.path, page_path) }; pagers.push(Pager::new( index + 1, page.clone(), permalink, - if section.is_index() { page_path } else { format!("{}/{}", section.path, page_path) } + pager_path, )); } @@ -164,11 +165,11 @@ mod tests { f.paginate_path = Some("page".to_string()); let mut s = Section::new("content/_index.md", f); if !is_index { - s.path = "posts".to_string(); - s.permalink = "https://vincent.is/posts".to_string(); + s.path = "posts/".to_string(); + s.permalink = "https://vincent.is/posts/".to_string(); s.file.components = vec!["posts".to_string()]; } else { - s.permalink = "https://vincent.is".to_string(); + s.permalink = "https://vincent.is/".to_string(); } s } @@ -186,13 +187,13 @@ mod tests { assert_eq!(paginator.pagers[0].index, 1); assert_eq!(paginator.pagers[0].pages.len(), 2); - assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/posts"); - assert_eq!(paginator.pagers[0].path, "posts"); + assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/posts/"); + assert_eq!(paginator.pagers[0].path, "posts/"); assert_eq!(paginator.pagers[1].index, 2); assert_eq!(paginator.pagers[1].pages.len(), 1); - assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/posts/page/2"); - assert_eq!(paginator.pagers[1].path, "posts/page/2"); + assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/posts/page/2/"); + assert_eq!(paginator.pagers[1].path, "posts/page/2/"); } #[test] @@ -208,13 +209,13 @@ mod tests { assert_eq!(paginator.pagers[0].index, 1); assert_eq!(paginator.pagers[0].pages.len(), 2); - assert_eq!(paginator.pagers[0].permalink, "https://vincent.is"); + assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/"); assert_eq!(paginator.pagers[0].path, ""); assert_eq!(paginator.pagers[1].index, 2); assert_eq!(paginator.pagers[1].pages.len(), 1); - assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/page/2"); - assert_eq!(paginator.pagers[1].path, "page/2"); + assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/page/2/"); + assert_eq!(paginator.pagers[1].path, "page/2/"); } #[test] @@ -230,18 +231,18 @@ mod tests { let context = paginator.build_paginator_context(&paginator.pagers[0]); assert_eq!(context["paginate_by"], to_value(2).unwrap()); - assert_eq!(context["first"], to_value("https://vincent.is/posts").unwrap()); - assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2").unwrap()); + assert_eq!(context["first"], to_value("https://vincent.is/posts/").unwrap()); + assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2/").unwrap()); assert_eq!(context["previous"], to_value::>(None).unwrap()); - assert_eq!(context["next"], to_value("https://vincent.is/posts/page/2").unwrap()); + assert_eq!(context["next"], to_value("https://vincent.is/posts/page/2/").unwrap()); assert_eq!(context["current_index"], to_value(1).unwrap()); let context = paginator.build_paginator_context(&paginator.pagers[1]); assert_eq!(context["paginate_by"], to_value(2).unwrap()); - assert_eq!(context["first"], to_value("https://vincent.is/posts").unwrap()); - assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2").unwrap()); + assert_eq!(context["first"], to_value("https://vincent.is/posts/").unwrap()); + assert_eq!(context["last"], to_value("https://vincent.is/posts/page/2/").unwrap()); assert_eq!(context["next"], to_value::>(None).unwrap()); - assert_eq!(context["previous"], to_value("https://vincent.is/posts").unwrap()); + assert_eq!(context["previous"], to_value("https://vincent.is/posts/").unwrap()); assert_eq!(context["current_index"], to_value(2).unwrap()); } } diff --git a/src/content/section.rs b/src/content/section.rs index 4468bceb..b9e6f30f 100644 --- a/src/content/section.rs +++ b/src/content/section.rs @@ -58,7 +58,7 @@ impl Section { let (meta, content) = split_section_content(file_path, content)?; let mut section = Section::new(file_path, meta); section.raw_content = content.clone(); - section.path = section.file.components.join("/"); + section.path = format!("{}/", section.file.components.join("/")); section.permalink = config.make_permalink(§ion.path); Ok(section) } diff --git a/tests/site.rs b/tests/site.rs index d1d65985..6194f8fd 100644 --- a/tests/site.rs +++ b/tests/site.rs @@ -28,7 +28,7 @@ fn can_parse_site() { // Make sure the page with a url doesn't have any sections let url_post = &site.pages[&posts_path.join("fixed-url.md")]; - assert_eq!(url_post.path, "a-fixed-url"); + assert_eq!(url_post.path, "a-fixed-url/"); // Make sure the article in a folder with only asset doesn't get counted as a section let asset_folder_post = &site.pages[&posts_path.join("with-assets").join("index.md")]; @@ -126,8 +126,8 @@ fn can_build_site_without_live_reload() { assert_eq!(file_contains!(public, "index.html", "/livereload.js?port=1112&mindelay=10"), false); // Both pages and sections are in the sitemap - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts/simple")); - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts/simple/")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/posts/")); } #[test] @@ -216,8 +216,8 @@ fn can_build_site_with_categories() { assert_eq!(file_exists!(public, "tags/index.html"), false); // Categories are in the sitemap - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories")); - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories/a")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories/")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/categories/a/")); } #[test] @@ -268,8 +268,8 @@ fn can_build_site_with_tags() { // Categories aren't assert_eq!(file_exists!(public, "categories/index.html"), false); // Tags are in the sitemap - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags")); - assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags/tag-with-space")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags/")); + assert!(file_contains!(public, "sitemap.xml", "https://replace-this-with-your-url.com/tags/tag-with-space/")); } #[test] @@ -327,14 +327,14 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!( public, "posts/page/1/index.html", - "http-equiv=\"refresh\" content=\"0;url=https://replace-this-with-your-url.com/posts\"" + "http-equiv=\"refresh\" content=\"0;url=https://replace-this-with-your-url.com/posts/\"" )); assert!(file_contains!(public, "posts/index.html", "Num pagers: 3")); assert!(file_contains!(public, "posts/index.html", "Page size: 2")); assert!(file_contains!(public, "posts/index.html", "Current index: 1")); assert!(file_contains!(public, "posts/index.html", "has_next")); - assert!(file_contains!(public, "posts/index.html", "First: https://replace-this-with-your-url.com/posts")); - assert!(file_contains!(public, "posts/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3")); + assert!(file_contains!(public, "posts/index.html", "First: https://replace-this-with-your-url.com/posts/")); + assert!(file_contains!(public, "posts/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3/")); assert_eq!(file_contains!(public, "posts/index.html", "has_prev"), false); assert!(file_exists!(public, "posts/page/2/index.html")); @@ -343,8 +343,8 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!(public, "posts/page/2/index.html", "Current index: 2")); assert!(file_contains!(public, "posts/page/2/index.html", "has_prev")); assert!(file_contains!(public, "posts/page/2/index.html", "has_next")); - assert!(file_contains!(public, "posts/page/2/index.html", "First: https://replace-this-with-your-url.com/posts")); - assert!(file_contains!(public, "posts/page/2/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3")); + assert!(file_contains!(public, "posts/page/2/index.html", "First: https://replace-this-with-your-url.com/posts/")); + assert!(file_contains!(public, "posts/page/2/index.html", "Last: https://replace-this-with-your-url.com/posts/page/3/")); } #[test]