diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f827df..c5a5d22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix deleting markdown file in `zola serve` - Fix pagination for taxonomies being broken and add missing documentation for it - Add missing pager pages from the sitemap +- Allow and parse full RFC339 datetimes in filenames ## 0.5.0 (2018-11-17) diff --git a/components/library/src/content/page.rs b/components/library/src/content/page.rs index 96fe524..2010e98 100644 --- a/components/library/src/content/page.rs +++ b/components/library/src/content/page.rs @@ -20,8 +20,11 @@ use content::file_info::FileInfo; use content::ser::SerializingPage; lazy_static! { - // Check whether a string starts with yyyy-mm-dd{-,_} - static ref DATE_IN_FILENAME: Regex = Regex::new(r"^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))(_|-)").unwrap(); + // Based on https://regex101.com/r/H2n38Z/1/tests + // A regex parsing RFC3339 date followed by {_,-}, some characters and ended by .md + static ref RFC3339_DATE: Regex = Regex::new( + r"^(?P(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9])))?)(_|-)(?P.+$)" + ).unwrap(); } #[derive(Clone, Debug, PartialEq)] @@ -113,11 +116,11 @@ impl Page { page.word_count = Some(word_count); page.reading_time = Some(reading_time); - let mut has_date_in_name = false; - if DATE_IN_FILENAME.is_match(&page.file.name) { - has_date_in_name = true; + let mut slug_from_dated_filename = None; + if let Some(ref caps) = RFC3339_DATE.captures(&page.file.name.replace(".md", "")) { + slug_from_dated_filename = Some(caps.name("slug").unwrap().as_str().to_string()); if page.meta.date.is_none() { - page.meta.date = Some(page.file.name[..10].to_string()); + page.meta.date = Some(caps.name("datetime").unwrap().as_str().to_string()); page.meta.date_to_datetime(); } } @@ -132,9 +135,8 @@ impl Page { slugify(&page.file.name) } } else { - if has_date_in_name { - // skip the date + the {_,-} - slugify(&page.file.name[11..]) + if let Some(slug) = slug_from_dated_filename { + slugify(&slug) } else { slugify(&page.file.name) } @@ -507,7 +509,7 @@ Hello world } #[test] - fn can_get_date_from_filename() { + fn can_get_date_from_short_date_in_filename() { let config = Config::default(); let content = r#" +++ @@ -523,6 +525,24 @@ Hello world assert_eq!(page.slug, "hello"); } + #[test] + fn can_get_date_from_full_rfc3339_date_in_filename() { + let config = Config::default(); + let content = r#" ++++ ++++ +Hello world +"# + .to_string(); + let res = Page::parse(Path::new("2018-10-02T15:00:00Z-hello.md"), &content, &config); + assert!(res.is_ok()); + let page = res.unwrap(); + + assert_eq!(page.meta.date, Some("2018-10-02T15:00:00Z".to_string())); + assert_eq!(page.slug, "hello"); + } + + #[test] fn frontmatter_date_override_filename_date() { let config = Config::default(); diff --git a/docs/content/documentation/content/page.md b/docs/content/documentation/content/page.md index a1c7bd8..70ef3f1 100644 --- a/docs/content/documentation/content/page.md +++ b/docs/content/documentation/content/page.md @@ -16,7 +16,7 @@ create a **page** at `[base_url]/about`). If the file is given any name *other* than `index.md` or `_index.md`, then it will create a page with that name (without the `.md`). So naming a file in the root of your content directory `about.md` would also create a page at `[base_url]/about`. -Another exception to that rule is that a filename starting with a YYYY-mm-dd date followed by +Another exception to that rule is that a filename starting with a datetime (YYYY-mm-dd or [a RFC3339 datetime](https://www.ietf.org/rfc/rfc3339.txt)) followed by an underscore (`_`) or a dash (`-`) will use that date as the page date, unless already set in the front-matter. The page name will be anything after `_`/`-` so a filename like `2018-10-10-hello-world.md` will be available at `[base_url]/hello-world`