diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d4cbc9c..cd0d873a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ also specify classes on headers now - `zola serve/build` can now run from anywhere in a zola directory - Add XML support to `load_data` - `skip_prefixes` is now checked before parsing external link URLs +- Add `render` attribute to taxonomies configuration in `config.toml`, for when you don't want to render +any pages related to that taxonomy ## 0.15.3 (2022-01-23) diff --git a/components/config/src/config/taxonomies.rs b/components/config/src/config/taxonomies.rs index 6d324a65..8932a175 100644 --- a/components/config/src/config/taxonomies.rs +++ b/components/config/src/config/taxonomies.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] pub struct TaxonomyConfig { /// The name used in the URL, usually the plural @@ -9,10 +9,24 @@ pub struct TaxonomyConfig { /// by this much pub paginate_by: Option, pub paginate_path: Option, - /// Whether to generate a feed only for each taxonomy term, defaults to false + /// Whether the taxonomy will be rendered, defaults to `true` + pub render: bool, + /// Whether to generate a feed only for each taxonomy term, defaults to `false` pub feed: bool, } +impl Default for TaxonomyConfig { + fn default() -> Self { + Self { + name: String::new(), + paginate_by: None, + paginate_path: None, + render: true, + feed: false, + } + } +} + impl TaxonomyConfig { pub fn is_paginated(&self) -> bool { if let Some(paginate_by) = self.paginate_by { diff --git a/components/content/src/lib.rs b/components/content/src/lib.rs index 6789c43a..87412888 100644 --- a/components/content/src/lib.rs +++ b/components/content/src/lib.rs @@ -17,5 +17,5 @@ pub use library::Library; pub use page::Page; pub use pagination::Paginator; pub use section::Section; -pub use taxonomies::{Taxonomy, TaxonomyItem}; +pub use taxonomies::{Taxonomy, TaxonomyTerm}; pub use types::*; diff --git a/components/content/src/pagination.rs b/components/content/src/pagination.rs index 70d731db..c779ffda 100644 --- a/components/content/src/pagination.rs +++ b/components/content/src/pagination.rs @@ -10,13 +10,13 @@ use utils::templates::{check_template_fallbacks, render_template}; use crate::library::Library; use crate::ser::{SectionSerMode, SerializingPage, SerializingSection}; -use crate::taxonomies::{Taxonomy, TaxonomyItem}; +use crate::taxonomies::{Taxonomy, TaxonomyTerm}; use crate::Section; #[derive(Clone, Debug, PartialEq)] enum PaginationRoot<'a> { Section(&'a Section), - Taxonomy(&'a Taxonomy, &'a TaxonomyItem), + Taxonomy(&'a Taxonomy, &'a TaxonomyTerm), } /// A list of all the pages in the paginator with their index and links @@ -90,7 +90,7 @@ impl<'a> Paginator<'a> { /// It will always at least create one pager (the first) even if there are not enough pages to paginate pub fn from_taxonomy( taxonomy: &'a Taxonomy, - item: &'a TaxonomyItem, + item: &'a TaxonomyTerm, library: &'a Library, tera: &Tera, theme: &Option, @@ -393,7 +393,7 @@ mod tests { paginate_by: Some(2), ..TaxonomyConfig::default() }; - let taxonomy_item = TaxonomyItem { + let taxonomy_item = TaxonomyTerm { name: "Something".to_string(), slug: "something".to_string(), path: "/some-tags/something/".to_string(), diff --git a/components/content/src/taxonomies.rs b/components/content/src/taxonomies.rs index 15cc7da4..682adb0e 100644 --- a/components/content/src/taxonomies.rs +++ b/components/content/src/taxonomies.rs @@ -17,7 +17,7 @@ use crate::{Page, SortBy}; use crate::sorting::sort_pages; #[derive(Debug, Clone, PartialEq, Serialize)] -pub struct SerializedTaxonomyItem<'a> { +pub struct SerializedTaxonomyTerm<'a> { name: &'a str, slug: &'a str, path: &'a str, @@ -25,15 +25,15 @@ pub struct SerializedTaxonomyItem<'a> { pages: Vec>, } -impl<'a> SerializedTaxonomyItem<'a> { - pub fn from_item(item: &'a TaxonomyItem, library: &'a Library) -> Self { +impl<'a> SerializedTaxonomyTerm<'a> { + pub fn from_item(item: &'a TaxonomyTerm, library: &'a Library) -> Self { let mut pages = vec![]; for p in &item.pages { pages.push(SerializingPage::new(&library.pages[p], Some(library), false)); } - SerializedTaxonomyItem { + SerializedTaxonomyTerm { name: &item.name, slug: &item.slug, path: &item.path, @@ -45,7 +45,7 @@ impl<'a> SerializedTaxonomyItem<'a> { /// A taxonomy with all its pages #[derive(Debug, Clone)] -pub struct TaxonomyItem { +pub struct TaxonomyTerm { pub name: String, pub slug: String, pub path: String, @@ -53,7 +53,7 @@ pub struct TaxonomyItem { pub pages: Vec, } -impl TaxonomyItem { +impl TaxonomyTerm { pub fn new( name: &str, lang: &str, @@ -75,11 +75,11 @@ impl TaxonomyItem { let (mut pages, ignored_pages) = sort_pages(taxo_pages, SortBy::Date); // We still append pages without dates at the end pages.extend(ignored_pages); - TaxonomyItem { name: name.to_string(), permalink, path, slug: item_slug, pages } + TaxonomyTerm { name: name.to_string(), permalink, path, slug: item_slug, pages } } - pub fn serialize<'a>(&'a self, library: &'a Library) -> SerializedTaxonomyItem<'a> { - SerializedTaxonomyItem::from_item(self, library) + pub fn serialize<'a>(&'a self, library: &'a Library) -> SerializedTaxonomyTerm<'a> { + SerializedTaxonomyTerm::from_item(self, library) } pub fn merge(&mut self, other: Self) { @@ -87,7 +87,7 @@ impl TaxonomyItem { } } -impl PartialEq for TaxonomyItem { +impl PartialEq for TaxonomyTerm { fn eq(&self, other: &Self) -> bool { self.permalink == other.permalink } @@ -98,13 +98,13 @@ pub struct SerializedTaxonomy<'a> { kind: &'a TaxonomyConfig, lang: &'a str, permalink: &'a str, - items: Vec>, + items: Vec>, } impl<'a> SerializedTaxonomy<'a> { pub fn from_taxonomy(taxonomy: &'a Taxonomy, library: &'a Library) -> Self { - let items: Vec = - taxonomy.items.iter().map(|i| SerializedTaxonomyItem::from_item(i, library)).collect(); + let items: Vec = + taxonomy.items.iter().map(|i| SerializedTaxonomyTerm::from_item(i, library)).collect(); SerializedTaxonomy { kind: &taxonomy.kind, lang: &taxonomy.lang, @@ -121,7 +121,7 @@ pub struct Taxonomy { pub slug: String, pub permalink: String, // this vec is sorted by the count of item - pub items: Vec, + pub items: Vec, } impl Taxonomy { @@ -129,7 +129,7 @@ impl Taxonomy { let mut sorted_items = vec![]; let slug = tax_found.slug; for (name, pages) in tax_found.terms { - sorted_items.push(TaxonomyItem::new(name, tax_found.lang, &slug, &pages, config)); + sorted_items.push(TaxonomyTerm::new(name, tax_found.lang, &slug, &pages, config)); } sorted_items.sort_by(|a, b| match a.slug.cmp(&b.slug) { @@ -166,7 +166,7 @@ impl Taxonomy { pub fn render_term( &self, - item: &TaxonomyItem, + item: &TaxonomyTerm, tera: &Tera, config: &Config, library: &Library, @@ -174,7 +174,7 @@ impl Taxonomy { let mut context = Context::new(); context.insert("config", &config.serialize(&self.lang)); context.insert("lang", &self.lang); - context.insert("term", &SerializedTaxonomyItem::from_item(item, library)); + context.insert("term", &SerializedTaxonomyTerm::from_item(item, library)); context.insert("taxonomy", &self.kind); context.insert( "current_url", @@ -199,8 +199,8 @@ impl Taxonomy { ) -> Result { let mut context = Context::new(); context.insert("config", &config.serialize(&self.lang)); - let terms: Vec = - self.items.iter().map(|i| SerializedTaxonomyItem::from_item(i, library)).collect(); + let terms: Vec = + self.items.iter().map(|i| SerializedTaxonomyTerm::from_item(i, library)).collect(); context.insert("terms", &terms); context.insert("lang", &self.lang); context.insert("taxonomy", &self.kind); @@ -245,7 +245,6 @@ impl<'a> TaxonomyFound<'a> { } pub fn find_taxonomies(config: &Config, pages: &AHashMap) -> Result> { - // lang -> tax names -> def let mut taxonomies_def = AHashMap::new(); let mut taxonomies_slug = AHashMap::new(); diff --git a/components/markdown/benches/all.rs b/components/markdown/benches/all.rs index 57fc1eaa..5b4f9157 100644 --- a/components/markdown/benches/all.rs +++ b/components/markdown/benches/all.rs @@ -4,9 +4,9 @@ extern crate test; use std::collections::HashMap; use config::Config; -use utils::types::InsertAnchor; use libs::tera::Tera; use markdown::{render_content, RenderContext}; +use utils::types::InsertAnchor; static CONTENT: &str = r#" # Modus cognitius profanam ne duae virtutis mundi diff --git a/components/markdown/src/markdown.rs b/components/markdown/src/markdown.rs index b602c49f..92740dbe 100644 --- a/components/markdown/src/markdown.rs +++ b/components/markdown/src/markdown.rs @@ -21,7 +21,6 @@ const CONTINUE_READING: &str = ""; const ANCHOR_LINK_TEMPLATE: &str = "anchor-link.html"; static EMOJI_REPLACER: Lazy = Lazy::new(EmojiReplacer::new); - /// Efficiently insert multiple element in their specified index. /// The elements should sorted in ascending order by their index. /// diff --git a/components/site/src/feed.rs b/components/site/src/feed.rs index 7f5ff6d9..8db2cc46 100644 --- a/components/site/src/feed.rs +++ b/components/site/src/feed.rs @@ -6,7 +6,7 @@ use libs::tera::Context; use serde::Serialize; use crate::Site; -use content::{Page, TaxonomyItem}; +use content::{Page, TaxonomyTerm}; use errors::Result; use utils::templates::render_template; @@ -18,7 +18,7 @@ pub struct SerializedFeedTaxonomyItem<'a> { } impl<'a> SerializedFeedTaxonomyItem<'a> { - pub fn from_item(item: &'a TaxonomyItem) -> Self { + pub fn from_item(item: &'a TaxonomyTerm) -> Self { SerializedFeedTaxonomyItem { name: &item.name, slug: &item.slug, diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index 97ddfe58..35bb00f9 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -1,9 +1,9 @@ pub mod feed; pub mod link_checking; +mod minify; pub mod sass; pub mod sitemap; pub mod tpls; -mod minify; use std::collections::HashMap; use std::fs::remove_dir_all; @@ -817,6 +817,9 @@ impl Site { /// Renders all taxonomies pub fn render_taxonomies(&self) -> Result<()> { for taxonomy in &self.taxonomies { + if !taxonomy.kind.render { + continue; + } self.render_taxonomy(taxonomy)?; } diff --git a/components/site/src/sitemap.rs b/components/site/src/sitemap.rs index db63a75a..6179c67d 100644 --- a/components/site/src/sitemap.rs +++ b/components/site/src/sitemap.rs @@ -98,6 +98,9 @@ pub fn find_entries<'a>( let mut taxonomies_entries = vec![]; for taxonomy in taxonomies { + if !taxonomy.kind.render { + continue; + } let name = &taxonomy.kind.name; let mut terms = vec![SitemapEntry::new(Cow::Owned(config.make_permalink(name)), None)]; for item in &taxonomy.items { diff --git a/components/site/tests/site.rs b/components/site/tests/site.rs index bb9d8377..169687b4 100644 --- a/components/site/tests/site.rs +++ b/components/site/tests/site.rs @@ -545,6 +545,7 @@ fn can_build_site_with_pagination_for_taxonomy() { name: "tags".to_string(), paginate_by: Some(2), paginate_path: None, + render: true, feed: true, }); site.load().unwrap(); diff --git a/components/templates/src/global_fns/content.rs b/components/templates/src/global_fns/content.rs index c082dff1..4ab744cc 100644 --- a/components/templates/src/global_fns/content.rs +++ b/components/templates/src/global_fns/content.rs @@ -186,7 +186,7 @@ impl TeraFn for GetTaxonomy { mod tests { use super::*; use config::{Config, TaxonomyConfig}; - use content::TaxonomyItem; + use content::TaxonomyTerm; #[test] fn can_get_taxonomy() { @@ -196,8 +196,8 @@ mod tests { let taxo_config_fr = TaxonomyConfig { name: "tags".to_string(), ..TaxonomyConfig::default() }; let library = Arc::new(RwLock::new(Library::new())); - let tag = TaxonomyItem::new("Programming", &config.default_language, "tags", &[], &config); - let tag_fr = TaxonomyItem::new("Programmation", "fr", "tags", &[], &config); + let tag = TaxonomyTerm::new("Programming", &config.default_language, "tags", &[], &config); + let tag_fr = TaxonomyTerm::new("Programmation", "fr", "tags", &[], &config); let tags = Taxonomy { kind: taxo_config, lang: config.default_language.clone(), @@ -265,8 +265,8 @@ mod tests { let taxo_config = TaxonomyConfig { name: "tags".to_string(), ..TaxonomyConfig::default() }; let taxo_config_fr = TaxonomyConfig { name: "tags".to_string(), ..TaxonomyConfig::default() }; - let tag = TaxonomyItem::new("Programming", &config.default_language, "tags", &[], &config); - let tag_fr = TaxonomyItem::new("Programmation", "fr", "tags", &[], &config); + let tag = TaxonomyTerm::new("Programming", &config.default_language, "tags", &[], &config); + let tag_fr = TaxonomyTerm::new("Programmation", "fr", "tags", &[], &config); let tags = Taxonomy { kind: taxo_config, lang: config.default_language.clone(), diff --git a/components/utils/src/fs.rs b/components/utils/src/fs.rs index fa2d83bb..afd6e44a 100644 --- a/components/utils/src/fs.rs +++ b/components/utils/src/fs.rs @@ -88,9 +88,8 @@ pub fn copy_file_if_needed(src: &Path, dest: &Path, hard_link: bool) -> Result<( if hard_link { std::fs::hard_link(src, dest)? } else { - let src_metadata = metadata(src).with_context(|| { - format!("Failed to get metadata of {}", src.display()) - })?; + let src_metadata = metadata(src) + .with_context(|| format!("Failed to get metadata of {}", src.display()))?; let src_mtime = FileTime::from_last_modification_time(&src_metadata); if Path::new(&dest).is_file() { let target_metadata = metadata(&dest)?; diff --git a/components/utils/src/site.rs b/components/utils/src/site.rs index 21f26b3b..3561c3fc 100644 --- a/components/utils/src/site.rs +++ b/components/utils/src/site.rs @@ -3,7 +3,6 @@ use std::collections::HashMap; use errors::{anyhow, Result}; - /// Result of a successful resolution of an internal link. #[derive(Debug, PartialEq, Clone)] pub struct ResolvedInternalLink { @@ -47,7 +46,7 @@ pub fn resolve_internal_link( mod tests { use std::collections::HashMap; - use super::{resolve_internal_link}; + use super::resolve_internal_link; #[test] fn can_resolve_valid_internal_link() { diff --git a/docs/content/documentation/templates/taxonomies.md b/docs/content/documentation/templates/taxonomies.md index 1cc8220d..064623b7 100644 --- a/docs/content/documentation/templates/taxonomies.md +++ b/docs/content/documentation/templates/taxonomies.md @@ -29,8 +29,7 @@ name: String, paginate_by: Number?; paginate_path: String?; feed: Bool; -lang: String; -permalink: String; +render: Bool; ```