From 896a80572baec5b2bebc5ab90bb1c1b6da5402ba Mon Sep 17 00:00:00 2001 From: ltdk Date: Sat, 20 Jul 2024 20:03:27 -0400 Subject: [PATCH 1/2] Include unrendered pages in sections, add render property to templates --- components/content/src/library.rs | 6 +++--- components/content/src/ser.rs | 4 ++++ docs/content/documentation/templates/pages-sections.md | 3 +++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/components/content/src/library.rs b/components/content/src/library.rs index 990de93eac..95bbf6e867 100644 --- a/components/content/src/library.rs +++ b/components/content/src/library.rs @@ -99,6 +99,9 @@ impl Library { .get_mut(&self.taxo_name_to_slug[taxa_name]) .expect("taxa not found"); + if !page.meta.render { + continue; + } if !taxa_def.contains_key(term) { taxa_def.insert(term.to_string(), Vec::new()); } @@ -295,9 +298,6 @@ impl Library { // Then once we took care of the sections, we find the pages of each section for (path, page) in self.pages.iter_mut() { - if !page.meta.render { - continue; - } let parent_filename = &index_filename_by_lang[&page.lang]; add_translation(&page.file.canonical, path); let mut parent_section_path = page.file.parent.join(parent_filename); diff --git a/components/content/src/ser.rs b/components/content/src/ser.rs index 919d0d1bb6..bdc5ff401c 100644 --- a/components/content/src/ser.rs +++ b/components/content/src/ser.rs @@ -64,6 +64,7 @@ pub struct SerializingPage<'a> { word_count: Option, reading_time: Option, assets: &'a [String], + render: bool, draft: bool, lang: &'a str, lower: Option>>, @@ -128,6 +129,7 @@ impl<'a> SerializingPage<'a> { word_count: page.word_count, reading_time: page.reading_time, assets: &page.serialized_assets, + render: page.meta.render, draft: page.meta.draft, lang: &page.lang, lower, @@ -144,6 +146,7 @@ pub struct SerializingSection<'a> { colocated_path: &'a Option, content: &'a str, permalink: &'a str, + render: bool, draft: bool, ancestors: &'a [String], title: &'a Option, @@ -207,6 +210,7 @@ impl<'a> SerializingSection<'a> { relative_path: §ion.file.relative, colocated_path: §ion.file.colocated_path, ancestors: §ion.ancestors, + render: section.meta.render, draft: section.meta.draft, content: §ion.content, permalink: §ion.permalink, diff --git a/docs/content/documentation/templates/pages-sections.md b/docs/content/documentation/templates/pages-sections.md index 97f9559614..1d5f123cfc 100644 --- a/docs/content/documentation/templates/pages-sections.md +++ b/docs/content/documentation/templates/pages-sections.md @@ -23,6 +23,7 @@ updated: String?; slug: String; path: String; authors: Array; +render: Bool; draft: Bool; // the path, split on '/' components: Array; @@ -77,6 +78,8 @@ content: String; title: String?; description: String?; path: String; +render: Bool; +draft: Bool; // the path, split on '/' components: Array; permalink: String; From 4dc73537a199fec94f1e12581c831dbeee81f2b2 Mon Sep 17 00:00:00 2001 From: ltdk Date: Wed, 24 Jul 2024 18:04:18 -0400 Subject: [PATCH 2/2] Add additional tests for unrendered pages/sections: * They can be accessed through templates directly and through sections * Unrendered pages are not added to sitemaps * Unrendered pages are not added to taxonomies --- components/site/tests/common.rs | 17 ++++- components/site/tests/site.rs | 93 +++++++++++++++++------- test_site/content/posts/access-render.md | 9 +++ test_site/content/posts/render.md | 4 + test_site/templates/access_render.html | 15 ++++ 5 files changed, 108 insertions(+), 30 deletions(-) create mode 100644 test_site/content/posts/access-render.md create mode 100644 test_site/templates/access_render.html diff --git a/components/site/tests/common.rs b/components/site/tests/common.rs index f5caaf1824..267bdf8019 100644 --- a/components/site/tests/common.rs +++ b/components/site/tests/common.rs @@ -22,7 +22,7 @@ macro_rules! file_exists { #[macro_export] macro_rules! file_contains { - ($root: expr, $path: expr, $text: expr) => {{ + (@impl $root: expr, $path: expr) => {{ use std::io::prelude::*; let mut path = $root.clone(); for component in $path.split('/') { @@ -31,11 +31,24 @@ macro_rules! file_contains { let mut file = std::fs::File::open(&path).expect(&format!("Failed to open {:?}", $path)); let mut s = String::new(); file.read_to_string(&mut s).unwrap(); - println!("{}", s); + println!("{path:?} {s}"); + s + }}; + ($root: expr, $path: expr, $text: expr) => {{ + let s = file_contains!(@impl $root, $path); s.contains($text) }}; } +#[macro_export] +macro_rules! file_contains_regex { + ($root: expr, $path: expr, $pat: expr) => {{ + let s = file_contains!(@impl $root, $path); + let re = libs::regex::Regex::new($pat).unwrap(); + re.is_match(&s) + }}; +} + /// We return the tmpdir otherwise it would get out of scope and be deleted /// The tests can ignore it if they dont need it by prefixing it with a `_` pub fn build_site(name: &str) -> (Site, TempDir, PathBuf) { diff --git a/components/site/tests/site.rs b/components/site/tests/site.rs index bf0811e15a..f86181caab 100644 --- a/components/site/tests/site.rs +++ b/components/site/tests/site.rs @@ -21,7 +21,7 @@ fn can_parse_site() { let library = site.library.read().unwrap(); // Correct number of pages (sections do not count as pages, draft are ignored) - assert_eq!(library.pages.len(), 36); + assert_eq!(library.pages.len(), 37); let posts_path = path.join("content").join("posts"); // Make sure the page with a url doesn't have any sections @@ -44,7 +44,7 @@ fn can_parse_site() { let posts_section = library.sections.get(&posts_path.join("_index.md")).unwrap(); assert_eq!(posts_section.subsections.len(), 2); - assert_eq!(posts_section.pages.len(), 10); // 11 with 1 draft == 10 + assert_eq!(posts_section.pages.len(), 12); // 13 with 1 draft == 12 assert_eq!(posts_section.ancestors, vec![index_section.file.relative.clone()]); // Make sure we remove all the pwd + content from the sections @@ -155,6 +155,33 @@ fn can_build_site_without_live_reload() { "posts/tutorials/devops/nix.md" )); + assert!(file_exists!(public, "posts/access-render/index.html")); + + // render = false pages can still be accessed directly + assert!(file_contains!( + public, + "posts/access-render/index.html", + "Path of unrendered page: /posts/render/" + )); + // render = false pages can still be accessed through sections + assert!(file_contains_regex!( + public, + "posts/access-render/index.html", + r#"Pages in section with unrendered page:
    (
  • [^>]+
  • )*
  • /posts/render/
  • "# + )); + // render = false sections can still be accessed directly + assert!(file_contains!( + public, + "posts/access-render/index.html", + "Pages in unrendered section:
    • " + )); + // render = false pages don't show up in taxonomies + assert!(!file_contains!(public, "podcast-authors/some-person/atom.xml", "/posts/render/")); + assert!(!file_contains!(public, "categories/a-category/atom.xml", "/posts/render/")); + // render = false pages don't even add terms to taxonomies + assert!(!file_exists!(public, "podcast-authors/other-person/atom.xml")); + assert!(!file_exists!(public, "categories/b-category/atom.xml")); + // 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")); @@ -216,6 +243,8 @@ fn can_build_site_without_live_reload() { assert!(!file_contains!(public, "sitemap.xml", "draft")); // render: false sections are not in the sitemap either assert!(!file_contains!(public, "sitemap.xml", "posts/2018/")); + // render: false pages are not in the sitemap either + assert!(!file_contains!(public, "sitemap.xml", "posts/render/")); // robots.txt has been rendered from the template assert!(file_contains!(public, "robots.txt", "User-agent: zola")); @@ -299,15 +328,19 @@ fn can_build_site_with_taxonomies() { let mut pages = vec![]; let pages_data = std::mem::replace(&mut library.pages, AHashMap::new()); - for (i, (_, mut page)) in pages_data.into_iter().enumerate() { - page.meta.taxonomies = { - let mut taxonomies = HashMap::new(); - taxonomies.insert( - "categories".to_string(), - vec![if i % 2 == 0 { "A" } else { "B" }.to_string()], - ); - taxonomies - }; + let mut i = 0; + for (_, mut page) in pages_data.into_iter() { + if page.meta.render { + page.meta.taxonomies = { + let mut taxonomies = HashMap::new(); + taxonomies.insert( + "categories".to_string(), + vec![if i % 2 == 0 { "A" } else { "B" }.to_string()], + ); + taxonomies + }; + i += 1; + } pages.push(page); } for p in pages { @@ -417,7 +450,7 @@ fn can_build_site_with_pagination_for_section() { "posts/page/1/index.html", "http-equiv=\"refresh\" content=\"0; url=https://replace-this-with-your-url.com/posts/\"" )); - assert!(file_contains!(public, "posts/index.html", "Num pagers: 5")); + assert!(file_contains!(public, "posts/index.html", "Num pagers: 6")); 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_prev")); @@ -430,12 +463,12 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!( public, "posts/index.html", - "Last: https://replace-this-with-your-url.com/posts/page/5/" + "Last: https://replace-this-with-your-url.com/posts/page/6/" )); assert!(!file_contains!(public, "posts/index.html", "has_prev")); assert!(file_exists!(public, "posts/page/2/index.html")); - assert!(file_contains!(public, "posts/page/2/index.html", "Num pagers: 5")); + assert!(file_contains!(public, "posts/page/2/index.html", "Num pagers: 6")); assert!(file_contains!(public, "posts/page/2/index.html", "Page size: 2")); assert!(file_contains!(public, "posts/page/2/index.html", "Current index: 2")); assert!(file_contains!(public, "posts/page/2/index.html", "has_prev")); @@ -448,11 +481,11 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!( public, "posts/page/2/index.html", - "Last: https://replace-this-with-your-url.com/posts/page/5/" + "Last: https://replace-this-with-your-url.com/posts/page/6/" )); assert!(file_exists!(public, "posts/page/3/index.html")); - assert!(file_contains!(public, "posts/page/3/index.html", "Num pagers: 5")); + assert!(file_contains!(public, "posts/page/3/index.html", "Num pagers: 6")); assert!(file_contains!(public, "posts/page/3/index.html", "Page size: 2")); assert!(file_contains!(public, "posts/page/3/index.html", "Current index: 3")); assert!(file_contains!(public, "posts/page/3/index.html", "has_prev")); @@ -465,11 +498,11 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!( public, "posts/page/3/index.html", - "Last: https://replace-this-with-your-url.com/posts/page/5/" + "Last: https://replace-this-with-your-url.com/posts/page/6/" )); assert!(file_exists!(public, "posts/page/4/index.html")); - assert!(file_contains!(public, "posts/page/4/index.html", "Num pagers: 5")); + assert!(file_contains!(public, "posts/page/4/index.html", "Num pagers: 6")); assert!(file_contains!(public, "posts/page/4/index.html", "Page size: 2")); assert!(file_contains!(public, "posts/page/4/index.html", "Current index: 4")); assert!(file_contains!(public, "posts/page/4/index.html", "has_prev")); @@ -482,7 +515,7 @@ fn can_build_site_with_pagination_for_section() { assert!(file_contains!( public, "posts/page/4/index.html", - "Last: https://replace-this-with-your-url.com/posts/page/5/" + "Last: https://replace-this-with-your-url.com/posts/page/6/" )); // sitemap contains the pager pages @@ -589,15 +622,19 @@ fn can_build_site_with_pagination_for_taxonomy() { let mut pages = vec![]; let pages_data = std::mem::replace(&mut library.pages, AHashMap::new()); - for (i, (_, mut page)) in pages_data.into_iter().enumerate() { - page.meta.taxonomies = { - let mut taxonomies = HashMap::new(); - taxonomies.insert( - "tags".to_string(), - vec![if i % 2 == 0 { "A" } else { "B" }.to_string()], - ); - taxonomies - }; + let mut i = 0; + for (_, mut page) in pages_data.into_iter() { + if page.meta.render { + page.meta.taxonomies = { + let mut taxonomies = HashMap::new(); + taxonomies.insert( + "tags".to_string(), + vec![if i % 2 == 0 { "A" } else { "B" }.to_string()], + ); + taxonomies + }; + i += 1; + } pages.push(page); } for p in pages { diff --git a/test_site/content/posts/access-render.md b/test_site/content/posts/access-render.md new file mode 100644 index 0000000000..580b327f94 --- /dev/null +++ b/test_site/content/posts/access-render.md @@ -0,0 +1,9 @@ ++++ +title = 'render = false tests' +slug = 'access-render' +template = 'access_render.html' +date = 2000-01-01 ++++ + +This post exists to test that unrendered sections and pages are still accessible +via templates. diff --git a/test_site/content/posts/render.md b/test_site/content/posts/render.md index 63af6b7568..178b783eea 100644 --- a/test_site/content/posts/render.md +++ b/test_site/content/posts/render.md @@ -3,6 +3,10 @@ title = "Page with content but without generated folder" description = "" date = 2017-04-01 render = false + +[taxonomies] +categories = ["a-category", "b-category"] +podcast_authors = ["Some Person", "Other Person"] +++ Don't generate a folder for this page diff --git a/test_site/templates/access_render.html b/test_site/templates/access_render.html new file mode 100644 index 0000000000..e311637aa9 --- /dev/null +++ b/test_site/templates/access_render.html @@ -0,0 +1,15 @@ +{% extends "index.html" %} + +{% block content %} + {% set unrendered_page = get_page(path='posts/render.md') %} + {% set section_with_unrendered = get_section(path='posts/_index.md') %} + {% set unrendered_section = get_section(path='posts/2018/_index.md') %} + Path of unrendered page: {{ unrendered_page.path | safe }} + Pages in section with unrendered page:
        {% for page in section_with_unrendered.pages -%} +
      • {{ page.path | safe }}
      • + {%- endfor %}
      + Pages in unrendered section:
        {% for page in unrendered_section.pages -%} +
      • {{ page.path | safe }}
      • + {%- endfor %}
      +{% endblock content %} +