diff --git a/CHANGELOG.md b/CHANGELOG.md index c2948db..4114eea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - Add `section` to a page Tera context if there is one - Reverse `order` sorting to be more intuitive: they are now desc, think of them as 1st, 2nd in the list +- Add `aliases` to pages for when you are changing urls but want to redirect +to the new one ## 0.0.6 (2017-05-24) diff --git a/README.md b/README.md index f26e0f1..d64f980 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ A front-matter has only optional variables: - category: only one category is allowed - draft: whether the post is a draft or not - template: if you want to change the template used to render that specific page +- aliases: which URL to redirect to the new: useful when you changed a page URL and don't want to 404 Even if your front-matter is empty, you will need to put the `+++`. You can also, like in the config, add your own variables in a `[extra]` table. diff --git a/src/front_matter/page.rs b/src/front_matter/page.rs index 9613c8f..67a1c9e 100644 --- a/src/front_matter/page.rs +++ b/src/front_matter/page.rs @@ -28,6 +28,9 @@ pub struct PageFrontMatter { pub category: Option, /// Integer to use to order content. Lowest is at the bottom, highest first pub order: Option, + /// All aliases for that page. Gutenberg will create HTML templates that will + #[serde(skip_serializing)] + pub aliases: Option>, /// Specify a template different from `page.html` to use for that page #[serde(skip_serializing)] pub template: Option, @@ -100,6 +103,7 @@ impl Default for PageFrontMatter { tags: None, category: None, order: None, + aliases: None, template: None, extra: None, } diff --git a/src/site.rs b/src/site.rs index 2e7fec7..cfdba8b 100644 --- a/src/site.rs +++ b/src/site.rs @@ -337,6 +337,8 @@ impl Site { /// Deletes the `public` directory and builds the site pub fn build(&self) -> Result<()> { self.clean()?; + // Render aliases first to allow overwriting + self.render_aliases()?; self.render_sections()?; self.render_orphan_pages()?; self.render_sitemap()?; @@ -352,6 +354,25 @@ impl Site { self.copy_static_directory() } + pub fn render_aliases(&self) -> Result<()> { + for page in self.pages.values() { + if let Some(ref aliases) = page.meta.aliases { + for alias in aliases { + let mut output_path = self.output_path.to_path_buf(); + for component in alias.split("/") { + output_path.push(&component); + + if !output_path.exists() { + create_directory(&output_path)?; + } + } + create_file(&output_path.join("index.html"), &render_redirect_template(&page.permalink, &self.tera)?)?; + } + } + } + Ok(()) + } + /// Renders robots.txt pub fn render_robots(&self) -> Result<()> { ensure_directory_exists(&self.output_path)?; diff --git a/test_site/content/posts/fixed-slug.md b/test_site/content/posts/fixed-slug.md index f28cfc3..ccba64a 100644 --- a/test_site/content/posts/fixed-slug.md +++ b/test_site/content/posts/fixed-slug.md @@ -3,6 +3,7 @@ title = "Fixed slug" description = "" slug = "something-else" date = "2017-01-01" +aliases = ["/an-old-url/old-page"] +++ A simple page with a slug defined diff --git a/tests/site.rs b/tests/site.rs index b650202..d247fd5 100644 --- a/tests/site.rs +++ b/tests/site.rs @@ -118,6 +118,10 @@ fn can_build_site_without_live_reload() { assert!(file_exists!(public, "posts/tutorials/programming/index.html")); // TODO: add assertion for syntax highlighting + // aliases work + assert!(file_exists!(public, "an-old-url/old-page/index.html")); + assert!(file_contains!(public, "an-old-url/old-page/index.html", "something-else")); + // No tags or categories assert_eq!(file_exists!(public, "categories/index.html"), false); assert_eq!(file_exists!(public, "tags/index.html"), false);