Allow taxonomies to not be rendered

Closes #1750
This commit is contained in:
Vincent Prouillet 2022-04-27 21:09:02 +02:00
parent 844576e32e
commit 84951d39e3
15 changed files with 62 additions and 44 deletions

View file

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

View file

@ -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<usize>,
pub paginate_path: Option<String>,
/// 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 {

View file

@ -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::*;

View file

@ -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<String>,
@ -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(),

View file

@ -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<SerializingPage<'a>>,
}
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<PathBuf>,
}
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<SerializedTaxonomyItem<'a>>,
items: Vec<SerializedTaxonomyTerm<'a>>,
}
impl<'a> SerializedTaxonomy<'a> {
pub fn from_taxonomy(taxonomy: &'a Taxonomy, library: &'a Library) -> Self {
let items: Vec<SerializedTaxonomyItem> =
taxonomy.items.iter().map(|i| SerializedTaxonomyItem::from_item(i, library)).collect();
let items: Vec<SerializedTaxonomyTerm> =
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<TaxonomyItem>,
pub items: Vec<TaxonomyTerm>,
}
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<String> {
let mut context = Context::new();
context.insert("config", &config.serialize(&self.lang));
let terms: Vec<SerializedTaxonomyItem> =
self.items.iter().map(|i| SerializedTaxonomyItem::from_item(i, library)).collect();
let terms: Vec<SerializedTaxonomyTerm> =
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<PathBuf, Page>) -> Result<Vec<Taxonomy>> {
// lang -> tax names -> def
let mut taxonomies_def = AHashMap::new();
let mut taxonomies_slug = AHashMap::new();

View file

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

View file

@ -21,7 +21,6 @@ const CONTINUE_READING: &str = "<span id=\"continue-reading\"></span>";
const ANCHOR_LINK_TEMPLATE: &str = "anchor-link.html";
static EMOJI_REPLACER: Lazy<EmojiReplacer> = Lazy::new(EmojiReplacer::new);
/// Efficiently insert multiple element in their specified index.
/// The elements should sorted in ascending order by their index.
///

View file

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

View file

@ -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)?;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,8 +29,7 @@ name: String,
paginate_by: Number?;
paginate_path: String?;
feed: Bool;
lang: String;
permalink: String;
render: Bool;
```