Allow RFC3339 datetimes in filenames

Closes #537
This commit is contained in:
Vincent Prouillet 2018-11-30 22:20:58 +01:00
parent 0cf8e8ca1c
commit 814cec99e2
3 changed files with 32 additions and 11 deletions

View file

@ -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)

View file

@ -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<datetime>(\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<slug>.+$)"
).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
<!-- more -->"#
.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();

View file

@ -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`