diff --git a/CHANGELOG.md b/CHANGELOG.md index 163f13c3..96329fea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 0.11.0 (unreleased) + +### Breaking +- RSS feed support has been altered to allow, *and default to*, Atom feeds, Atom being technically superior and just as widely-supported in normal use cases. + - New config value `feed_filename`, defaulting to `atom.xml` (change to `rss.xml` to reinstate the old behaviour) + - Config value `rss_limit` is renamed to `feed_limit` + - Config value `languages.*.rss` is renamed to `languages.*.feed` + - Config value `generate_rss` is renamed to `generate_feed` + + Users with existing feeds should either set `feed_filename = "rss.xml"` in config.toml to keep things the same, or set up a 3xx redirect from rss.xml to atom.xml so that existing feed consumers aren’t broken. + +- The feed template variable `last_build_date` is renamed to `last_updated` to more accurately reflect its semantics +- The sitemap template’s `SitemapEntry` type’s `date` field has been renamed to `updated` to reflect that it will use the `updated` front-matter field if available, rather than `date` + +### Other +- Add `updated` front-matter field for pages, which sitemap templates will use for the `SitemapEntry.date` field instead of the `date` front-matter field, and which the default Atom feed template will use +- Add `lang` to the feed template context +- Add `taxonomy` and `term` to the feed template context for taxonomy feeds + ## 0.10.2 (unreleased) - Fix link checker not looking for anchor with capital id/name @@ -17,8 +36,6 @@ ### Breaking - Remove `toc` variable in section/page context and pass it to `page.toc` and `section.toc` instead so they are accessible everywhere -- [Slugification](https://en.wikipedia.org/wiki/Slug_(web_publishing)#Slug) of paths, taxonomies and anchors is now configurable. By default, everything will still be slugified like in previous versions. -See documentation for information on how to disable it. ### Other - Add zenburn syntax highlighting theme diff --git a/components/config/src/config.rs b/components/config/src/config.rs index c0b43c92..393db8de 100644 --- a/components/config/src/config.rs +++ b/components/config/src/config.rs @@ -47,15 +47,15 @@ impl Default for Slugify { pub struct Language { /// The language code pub code: String, - /// Whether to generate a RSS feed for that language, defaults to `false` - pub rss: bool, + /// Whether to generate a feed for that language, defaults to `false` + pub feed: bool, /// Whether to generate search index for that language, defaults to `false` pub search: bool, } impl Default for Language { fn default() -> Self { - Language { code: String::new(), rss: false, search: false } + Language { code: String::new(), feed: false, search: false } } } @@ -68,8 +68,8 @@ pub struct Taxonomy { /// by this much pub paginate_by: Option, pub paginate_path: Option, - /// Whether to generate a RSS feed only for each taxonomy term, defaults to false - pub rss: bool, + /// Whether to generate a feed only for each taxonomy term, defaults to false + pub feed: bool, /// The language for that taxonomy, only used in multilingual sites. /// Defaults to the config `default_language` if not set pub lang: String, @@ -99,7 +99,7 @@ impl Default for Taxonomy { name: String::new(), paginate_by: None, paginate_path: None, - rss: false, + feed: false, lang: String::new(), } } @@ -155,10 +155,13 @@ pub struct Config { /// Defaults to "base16-ocean-dark" pub highlight_theme: String, - /// Whether to generate RSS. Defaults to false - pub generate_rss: bool, - /// The number of articles to include in the RSS feed. Defaults to including all items. - pub rss_limit: Option, + /// Whether to generate a feed. Defaults to false. + pub generate_feed: bool, + /// The number of articles to include in the feed. Defaults to including all items. + pub feed_limit: Option, + /// The filename to use for feeds. Used to find the template, too. + /// Defaults to "atom.xml", with "rss.xml" also having a template provided out of the box. + pub feed_filename: String, /// If set, files from static/ will be hardlinked instead of copied to the output dir. pub hard_link_static: bool, @@ -276,11 +279,12 @@ impl Config { /// Makes a url, taking into account that the base url might have a trailing slash pub fn make_permalink(&self, path: &str) -> String { - let trailing_bit = if path.ends_with('/') || path.ends_with("rss.xml") || path.is_empty() { - "" - } else { - "/" - }; + let trailing_bit = + if path.ends_with('/') || path.ends_with(&self.feed_filename) || path.is_empty() { + "" + } else { + "/" + }; // Index section with a base url that has a trailing slash if self.base_url.ends_with('/') && path == "/" { @@ -384,8 +388,9 @@ impl Default for Config { highlight_theme: "base16-ocean-dark".to_string(), default_language: "en".to_string(), languages: Vec::new(), - generate_rss: false, - rss_limit: None, + generate_feed: false, + feed_limit: None, + feed_filename: "atom.xml".to_string(), hard_link_static: false, taxonomies: Vec::new(), compile_sass: false, @@ -493,10 +498,10 @@ hello = "world" // https://github.com/Keats/gutenberg/issues/486 #[test] - fn doesnt_add_trailing_slash_to_rss() { + fn doesnt_add_trailing_slash_to_feed() { let mut config = Config::default(); config.base_url = "http://vincent.is/".to_string(); - assert_eq!(config.make_permalink("rss.xml"), "http://vincent.is/rss.xml"); + assert_eq!(config.make_permalink("atom.xml"), "http://vincent.is/atom.xml"); } #[test] diff --git a/components/errors/src/lib.rs b/components/errors/src/lib.rs old mode 100755 new mode 100644 diff --git a/components/front_matter/src/page.rs b/components/front_matter/src/page.rs index dba73511..c26371af 100644 --- a/components/front_matter/src/page.rs +++ b/components/front_matter/src/page.rs @@ -16,6 +16,9 @@ pub struct PageFrontMatter { pub title: Option, /// Description in that appears when linked, e.g. on twitter pub description: Option, + /// Updated date + #[serde(default, deserialize_with = "from_toml_datetime")] + pub updated: Option, /// Date if we want to order pages (ie blog post) #[serde(default, deserialize_with = "from_toml_datetime")] pub date: Option, @@ -117,6 +120,7 @@ impl Default for PageFrontMatter { PageFrontMatter { title: None, description: None, + updated: None, date: None, datetime: None, datetime_tuple: None, diff --git a/components/library/src/content/file_info.rs b/components/library/src/content/file_info.rs index 517e1b35..3dc0a537 100644 --- a/components/library/src/content/file_info.rs +++ b/components/library/src/content/file_info.rs @@ -195,7 +195,7 @@ mod tests { #[test] fn can_find_valid_language_in_page() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let mut file = FileInfo::new_page( &Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"), &PathBuf::new(), @@ -208,7 +208,7 @@ mod tests { #[test] fn can_find_valid_language_in_page_with_assets() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let mut file = FileInfo::new_page( &Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"), &PathBuf::new(), @@ -234,7 +234,7 @@ mod tests { #[test] fn errors_on_unknown_language_in_page_with_i18n_on() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("it"), rss: false, search: false }); + config.languages.push(Language { code: String::from("it"), feed: false, search: false }); let mut file = FileInfo::new_page( &Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"), &PathBuf::new(), @@ -246,7 +246,7 @@ mod tests { #[test] fn can_find_valid_language_in_section() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let mut file = FileInfo::new_section( &Path::new("/home/vincent/code/site/content/posts/tutorials/_index.fr.md"), &PathBuf::new(), @@ -273,7 +273,7 @@ mod tests { #[test] fn correct_canonical_after_find_language() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let mut file = FileInfo::new_page( &Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"), &PathBuf::new(), diff --git a/components/library/src/content/page.rs b/components/library/src/content/page.rs index 0c653357..dbea1bd9 100644 --- a/components/library/src/content/page.rs +++ b/components/library/src/content/page.rs @@ -770,7 +770,7 @@ Hello world #[test] fn can_specify_language_in_filename() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let content = r#" +++ +++ @@ -787,7 +787,7 @@ Bonjour le monde"# #[test] fn can_specify_language_in_filename_with_date() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let content = r#" +++ +++ @@ -806,7 +806,7 @@ Bonjour le monde"# #[test] fn i18n_frontmatter_path_overrides_default_permalink() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let content = r#" +++ path = "bonjour" diff --git a/components/library/src/content/section.rs b/components/library/src/content/section.rs index a3aff39f..9630a725 100644 --- a/components/library/src/content/section.rs +++ b/components/library/src/content/section.rs @@ -350,7 +350,7 @@ mod tests { #[test] fn can_specify_language_in_filename() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let content = r#" +++ +++ @@ -372,7 +372,7 @@ Bonjour le monde"# #[test] fn can_make_links_to_translated_sections_without_double_trailing_slash() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let content = r#" +++ +++ @@ -389,7 +389,7 @@ Bonjour le monde"# #[test] fn can_make_links_to_translated_subsections_with_trailing_slash() { let mut config = Config::default(); - config.languages.push(Language { code: String::from("fr"), rss: false, search: false }); + config.languages.push(Language { code: String::from("fr"), feed: false, search: false }); let content = r#" +++ +++ diff --git a/components/library/src/content/ser.rs b/components/library/src/content/ser.rs index ca794481..39e6439c 100644 --- a/components/library/src/content/ser.rs +++ b/components/library/src/content/ser.rs @@ -63,6 +63,7 @@ pub struct SerializingPage<'a> { ancestors: Vec, title: &'a Option, description: &'a Option, + updated: &'a Option, date: &'a Option, year: Option, month: Option, @@ -126,6 +127,7 @@ impl<'a> SerializingPage<'a> { title: &page.meta.title, description: &page.meta.description, extra: &page.meta.extra, + updated: &page.meta.updated, date: &page.meta.date, year, month, @@ -182,6 +184,7 @@ impl<'a> SerializingPage<'a> { title: &page.meta.title, description: &page.meta.description, extra: &page.meta.extra, + updated: &page.meta.updated, date: &page.meta.date, year, month, diff --git a/components/library/src/sorting.rs b/components/library/src/sorting.rs index b790b111..6213c880 100644 --- a/components/library/src/sorting.rs +++ b/components/library/src/sorting.rs @@ -6,7 +6,7 @@ use slotmap::DefaultKey; use crate::content::Page; -/// Used by the RSS feed +/// Used by the feed /// There to not have to import sorting stuff in the site crate #[allow(clippy::trivially_copy_pass_by_ref)] pub fn sort_actual_pages_by_date(a: &&Page, b: &&Page) -> Ordering { diff --git a/components/library/src/taxonomies/mod.rs b/components/library/src/taxonomies/mod.rs index 97be410a..c2f700f1 100644 --- a/components/library/src/taxonomies/mod.rs +++ b/components/library/src/taxonomies/mod.rs @@ -458,7 +458,7 @@ mod tests { #[test] fn can_make_taxonomies_in_multiple_languages() { let mut config = Config::default(); - config.languages.push(Language { rss: false, code: "fr".to_string(), search: false }); + config.languages.push(Language { feed: false, code: "fr".to_string(), search: false }); let mut library = Library::new(2, 0, true); config.taxonomies = vec![ @@ -569,7 +569,7 @@ mod tests { let mut config = Config::default(); config.slugify.taxonomies = SlugifyStrategy::Safe; config.languages.push(Language { - rss: false, + feed: false, code: "fr".to_string(), ..Language::default() }); @@ -602,7 +602,7 @@ mod tests { let mut config = Config::default(); config.slugify.taxonomies = SlugifyStrategy::On; config.languages.push(Language { - rss: false, + feed: false, code: "fr".to_string(), ..Language::default() }); diff --git a/components/rebuild/src/lib.rs b/components/rebuild/src/lib.rs index 694d4cd9..c0918954 100644 --- a/components/rebuild/src/lib.rs +++ b/components/rebuild/src/lib.rs @@ -395,7 +395,17 @@ pub fn after_template_change(site: &mut Site, path: &Path) -> Result<()> { match filename { "sitemap.xml" => site.render_sitemap(), - "rss.xml" => site.render_rss_feed(site.library.read().unwrap().pages_values(), None), + filename if filename == site.config.feed_filename => { + // FIXME: this is insufficient; for multilingual sites, it’s rendering the wrong + // content into the root feed, and it’s not regenerating any of the other feeds (other + // languages or taxonomies with feed enabled). + site.render_feed( + site.library.read().unwrap().pages_values(), + None, + &site.config.default_language, + None, + ) + } "split_sitemap_index.xml" => site.render_sitemap(), "robots.txt" => site.render_robots(), "single.html" | "list.html" => site.render_taxonomies(), diff --git a/components/site/benches/gen.py b/components/site/benches/gen.py index c30709ba..0fe649a9 100644 --- a/components/site/benches/gen.py +++ b/components/site/benches/gen.py @@ -108,7 +108,7 @@ base_url = "https://replace-this-with-your-url.com" theme = "sample" taxonomies = [ - {name = "tags", rss = true}, + {name = "tags", feed = true}, {name = "categories"} ] diff --git a/components/site/benches/site.rs b/components/site/benches/site.rs index 3436f884..f5eb7ccf 100644 --- a/components/site/benches/site.rs +++ b/components/site/benches/site.rs @@ -35,12 +35,19 @@ fn bench_render_sitemap(b: &mut test::Bencher) { } #[bench] -fn bench_render_rss_feed(b: &mut test::Bencher) { +fn bench_render_feed(b: &mut test::Bencher) { let mut site = setup_site("big-blog"); let tmp_dir = tempdir().expect("create temp dir"); let public = &tmp_dir.path().join("public"); site.set_output_path(&public); - b.iter(|| site.render_rss_feed(site.library.read().unwrap().pages_values(), None).unwrap()); + b.iter(|| { + site.render_feed( + site.library.read().unwrap().pages_values(), + None, + &site.config.default_language, + None, + ).unwrap(); + }); } #[bench] diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index a095e3b7..bf39a970 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -8,13 +8,15 @@ use std::sync::{Arc, Mutex, RwLock}; use glob::glob; use rayon::prelude::*; use sass_rs::{compile_file, Options as SassOptions, OutputStyle}; +use serde_derive::Serialize; use tera::{Context, Tera}; -use config::{get_config, Config}; +use config::{get_config, Config, Taxonomy as TaxonomyConfig}; use errors::{bail, Error, ErrorKind, Result}; use front_matter::InsertAnchor; use library::{ find_taxonomies, sort_actual_pages_by_date, Library, Page, Paginator, Section, Taxonomy, + TaxonomyItem, }; use link_checker::check_url; use templates::{global_fns, render_redirect_template, ZOLA_TERA}; @@ -45,6 +47,23 @@ pub struct Site { include_drafts: bool, } +#[derive(Debug, Clone, PartialEq, Serialize)] +struct SerializedTaxonomyItem<'a> { + name: &'a str, + slug: &'a str, + permalink: &'a str, +} + +impl<'a> SerializedTaxonomyItem<'a> { + pub fn from_item(item: &'a TaxonomyItem) -> Self { + SerializedTaxonomyItem { + name: &item.name, + slug: &item.slug, + permalink: &item.permalink, + } + } +} + impl Site { /// Parse a site at the given path. Defaults to the current dir /// Passing in a path is used in tests and when --root argument is passed @@ -626,15 +645,17 @@ impl Site { } /// Inject live reload script tag if in live reload mode - fn inject_livereload(&self, html: String) -> String { + fn inject_livereload(&self, mut html: String) -> String { if let Some(port) = self.live_reload { - return html.replace( - "", - &format!( - r#""#, - port - ), + let script = format!( + r#""#, + port, ); + if let Some(index) = html.rfind("") { + html.insert_str(index, &script); + } else { + html.push_str(&script); + } } html @@ -743,8 +764,9 @@ impl Site { self.render_sitemap()?; let library = self.library.read().unwrap(); - if self.config.generate_rss { - let pages = if self.config.is_multilingual() { + if self.config.generate_feed { + let is_multilingual = self.config.is_multilingual(); + let pages = if is_multilingual { library .pages_values() .iter() @@ -754,16 +776,26 @@ impl Site { } else { library.pages_values() }; - self.render_rss_feed(pages, None)?; + self.render_feed( + pages, + None, + &self.config.default_language, + None, + )?; } for lang in &self.config.languages { - if !lang.rss { + if !lang.feed { continue; } let pages = library.pages_values().iter().filter(|p| p.lang == lang.code).cloned().collect(); - self.render_rss_feed(pages, Some(&PathBuf::from(lang.code.clone())))?; + self.render_feed( + pages, + Some(&PathBuf::from(lang.code.clone())), + &lang.code, + None, + )?; } self.render_404()?; @@ -981,10 +1013,16 @@ impl Site { create_file(&path.join("index.html"), &self.inject_livereload(single_output))?; } - if taxonomy.kind.rss { - self.render_rss_feed( + if taxonomy.kind.feed { + self.render_feed( item.pages.iter().map(|p| library.get_page_by_key(*p)).collect(), Some(&PathBuf::from(format!("{}/{}", taxonomy.kind.name, item.slug))), + if self.config.is_multilingual() && !taxonomy.kind.lang.is_empty() { + &taxonomy.kind.lang + } else { + &self.config.default_language + }, + Some((&taxonomy.kind, &item)), ) } else { Ok(()) @@ -1043,30 +1081,39 @@ impl Site { Ok(()) } - /// Renders a RSS feed for the given path and at the given path - /// If both arguments are `None`, it will render only the RSS feed for the whole + /// Renders a feed for the given path and at the given path + /// If both arguments are `None`, it will render only the feed for the whole /// site at the root folder. - pub fn render_rss_feed( + pub fn render_feed( &self, all_pages: Vec<&Page>, base_path: Option<&PathBuf>, + lang: &str, + taxonomy_and_item: Option<(&TaxonomyConfig, &TaxonomyItem)>, ) -> Result<()> { ensure_directory_exists(&self.output_path)?; let mut context = Context::new(); let mut pages = all_pages.into_iter().filter(|p| p.meta.date.is_some()).collect::>(); - // Don't generate a RSS feed if none of the pages has a date + // Don't generate a feed if none of the pages has a date if pages.is_empty() { return Ok(()); } pages.par_sort_unstable_by(sort_actual_pages_by_date); - context.insert("last_build_date", &pages[0].meta.date.clone()); + context.insert( + "last_updated", + pages.iter() + .filter_map(|page| page.meta.updated.as_ref()) + .chain(pages[0].meta.date.as_ref()) + .max() // I love lexicographically sorted date strings + .unwrap(), // Guaranteed because of pages[0].meta.date + ); let library = self.library.read().unwrap(); // limit to the last n elements if the limit is set; otherwise use all. - let num_entries = self.config.rss_limit.unwrap_or_else(|| pages.len()); + let num_entries = self.config.feed_limit.unwrap_or_else(|| pages.len()); let p = pages .iter() .take(num_entries) @@ -1075,16 +1122,28 @@ impl Site { context.insert("pages", &p); context.insert("config", &self.config); + context.insert("lang", lang); - let rss_feed_url = if let Some(ref base) = base_path { - self.config.make_permalink(&base.join("rss.xml").to_string_lossy().replace('\\', "/")) + let feed_filename = &self.config.feed_filename; + let feed_url = if let Some(ref base) = base_path { + self.config.make_permalink( + &base + .join(feed_filename) + .to_string_lossy() + .replace('\\', "/"), + ) } else { - self.config.make_permalink("rss.xml") + self.config.make_permalink(feed_filename) }; - context.insert("feed_url", &rss_feed_url); + context.insert("feed_url", &feed_url); - let feed = &render_template("rss.xml", &self.tera, context, &self.config.theme)?; + if let Some((taxonomy, item)) = taxonomy_and_item { + context.insert("taxonomy", taxonomy); + context.insert("term", &SerializedTaxonomyItem::from_item(item)); + } + + let feed = &render_template(feed_filename, &self.tera, context, &self.config.theme)?; if let Some(ref base) = base_path { let mut output_path = self.output_path.clone(); @@ -1094,9 +1153,9 @@ impl Site { create_directory(&output_path)?; } } - create_file(&output_path.join("rss.xml"), feed)?; + create_file(&output_path.join(feed_filename), feed)?; } else { - create_file(&self.output_path.join("rss.xml"), feed)?; + create_file(&self.output_path.join(feed_filename), feed)?; } Ok(()) } diff --git a/components/site/src/sitemap.rs b/components/site/src/sitemap.rs index 51bf43c4..afb20928 100644 --- a/components/site/src/sitemap.rs +++ b/components/site/src/sitemap.rs @@ -14,7 +14,7 @@ use tera::{Map, Value}; #[derive(Debug, Serialize)] pub struct SitemapEntry<'a> { pub permalink: Cow<'a, str>, - pub date: Option, + pub updated: Option, pub extra: Option<&'a Map>, } @@ -33,8 +33,8 @@ impl<'a> PartialEq for SitemapEntry<'a> { impl<'a> Eq for SitemapEntry<'a> {} impl<'a> SitemapEntry<'a> { - pub fn new(permalink: Cow<'a, str>, date: Option) -> Self { - SitemapEntry { permalink, date, extra: None } + pub fn new(permalink: Cow<'a, str>, updated: Option) -> Self { + SitemapEntry { permalink, updated, extra: None } } pub fn add_extra(&mut self, extra: &'a Map) { @@ -65,11 +65,10 @@ pub fn find_entries<'a>( .pages_values() .iter() .map(|p| { - let date = match p.meta.date { - Some(ref d) => Some(d.to_string()), - None => None, - }; - let mut entry = SitemapEntry::new(Cow::Borrowed(&p.permalink), date); + let mut entry = SitemapEntry::new( + Cow::Borrowed(&p.permalink), + p.meta.updated.clone().or_else(|| p.meta.date.clone()), + ); entry.add_extra(&p.meta.extra); entry }) diff --git a/components/site/tests/site.rs b/components/site/tests/site.rs index 2c02a683..fb285c04 100644 --- a/components/site/tests/site.rs +++ b/components/site/tests/site.rs @@ -152,7 +152,7 @@ fn can_build_site_without_live_reload() { // We do have categories assert_eq!(file_exists!(public, "categories/index.html"), true); assert_eq!(file_exists!(public, "categories/a-category/index.html"), true); - assert_eq!(file_exists!(public, "categories/a-category/rss.xml"), true); + assert_eq!(file_exists!(public, "categories/a-category/atom.xml"), true); // But no tags assert_eq!(file_exists!(public, "tags/index.html"), false); @@ -232,7 +232,7 @@ fn can_build_site_with_live_reload_and_drafts() { // We do have categories assert_eq!(file_exists!(public, "categories/index.html"), true); assert_eq!(file_exists!(public, "categories/a-category/index.html"), true); - assert_eq!(file_exists!(public, "categories/a-category/rss.xml"), true); + assert_eq!(file_exists!(public, "categories/a-category/atom.xml"), true); // But no tags assert_eq!(file_exists!(public, "tags/index.html"), false); @@ -294,11 +294,11 @@ fn can_build_site_with_taxonomies() { assert!(file_exists!(public, "categories/index.html")); assert!(file_exists!(public, "categories/a/index.html")); assert!(file_exists!(public, "categories/b/index.html")); - assert!(file_exists!(public, "categories/a/rss.xml")); + assert!(file_exists!(public, "categories/a/atom.xml")); assert!(file_contains!( public, - "categories/a/rss.xml", - "https://replace-this-with-your-url.com/categories/a/rss.xml" + "categories/a/atom.xml", + "https://replace-this-with-your-url.com/categories/a/atom.xml" )); // Extending from a theme works assert!(file_contains!(public, "categories/a/index.html", "EXTENDED")); @@ -513,7 +513,7 @@ fn can_build_site_with_pagination_for_taxonomy() { name: "tags".to_string(), paginate_by: Some(2), paginate_path: None, - rss: true, + feed: true, lang: site.config.default_language.clone(), }); site.load().unwrap(); @@ -547,9 +547,9 @@ fn can_build_site_with_pagination_for_taxonomy() { // Tags assert!(file_exists!(public, "tags/index.html")); - // With RSS - assert!(file_exists!(public, "tags/a/rss.xml")); - assert!(file_exists!(public, "tags/b/rss.xml")); + // With Atom + assert!(file_exists!(public, "tags/a/atom.xml")); + assert!(file_exists!(public, "tags/b/atom.xml")); // And pagination! assert!(file_exists!(public, "tags/a/page/1/index.html")); assert!(file_exists!(public, "tags/b/page/1/index.html")); @@ -588,15 +588,15 @@ fn can_build_site_with_pagination_for_taxonomy() { } #[test] -fn can_build_rss_feed() { +fn can_build_feed() { let (_, _tmp_dir, public) = build_site("test_site"); assert!(&public.exists()); - assert!(file_exists!(public, "rss.xml")); + assert!(file_exists!(public, "atom.xml")); // latest article is posts/extra-syntax.md - assert!(file_contains!(public, "rss.xml", "Extra Syntax")); + assert!(file_contains!(public, "atom.xml", "Extra Syntax")); // Next is posts/simple.md - assert!(file_contains!(public, "rss.xml", "Simple article with shortcodes")); + assert!(file_contains!(public, "atom.xml", "Simple article with shortcodes")); } #[test] diff --git a/components/site/tests/site_i18n.rs b/components/site/tests/site_i18n.rs index 7a5fc983..be666776 100644 --- a/components/site/tests/site_i18n.rs +++ b/components/site/tests/site_i18n.rs @@ -115,15 +115,17 @@ fn can_build_multilingual_site() { assert!(file_contains!(public, "sitemap.xml", "https://example.com/fr/blog/something-else/")); assert!(file_contains!(public, "sitemap.xml", "https://example.com/it/blog/something-else/")); - // one rss per language - assert!(file_exists!(public, "rss.xml")); - assert!(file_contains!(public, "rss.xml", "https://example.com/blog/something-else/")); - assert!(!file_contains!(public, "rss.xml", "https://example.com/fr/blog/something-else/")); - assert!(file_exists!(public, "fr/rss.xml")); - assert!(!file_contains!(public, "fr/rss.xml", "https://example.com/blog/something-else/")); - assert!(file_contains!(public, "fr/rss.xml", "https://example.com/fr/blog/something-else/")); - // Italian doesn't have RSS enabled - assert!(!file_exists!(public, "it/rss.xml")); + // one feed per language + assert!(file_exists!(public, "atom.xml")); + assert!(file_contains!(public, "atom.xml", "https://example.com/blog/something-else/")); + assert!(!file_contains!(public, "atom.xml", "https://example.com/fr/blog/something-else/")); + assert!(file_contains!(public, "atom.xml", r#""#)); + assert!(file_exists!(public, "fr/atom.xml")); + assert!(!file_contains!(public, "fr/atom.xml", "https://example.com/blog/something-else/")); + assert!(file_contains!(public, "fr/atom.xml", "https://example.com/fr/blog/something-else/")); + assert!(file_contains!(public, "fr/atom.xml", r#""#)); + // Italian doesn't have feed enabled + assert!(!file_exists!(public, "it/atom.xml")); // Taxonomies are per-language // English @@ -131,7 +133,9 @@ fn can_build_multilingual_site() { assert!(file_contains!(public, "authors/index.html", "Queen")); assert!(!file_contains!(public, "authors/index.html", "Vincent")); assert!(!file_exists!(public, "auteurs/index.html")); - assert!(file_exists!(public, "authors/queen-elizabeth/rss.xml")); + assert!(file_exists!(public, "authors/queen-elizabeth/atom.xml")); + assert!(file_contains!(public, "authors/queen-elizabeth/atom.xml", r#""#)); + assert!(file_contains!(public, "authors/queen-elizabeth/atom.xml", r#" - Queen Elizabeth"#)); assert!(file_exists!(public, "tags/index.html")); assert!(file_contains!(public, "tags/index.html", "hello")); @@ -142,7 +146,7 @@ fn can_build_multilingual_site() { assert!(file_exists!(public, "fr/auteurs/index.html")); assert!(!file_contains!(public, "fr/auteurs/index.html", "Queen")); assert!(file_contains!(public, "fr/auteurs/index.html", "Vincent")); - assert!(!file_exists!(public, "fr/auteurs/vincent-prouillet/rss.xml")); + assert!(!file_exists!(public, "fr/auteurs/vincent-prouillet/atom.xml")); assert!(file_exists!(public, "fr/tags/index.html")); assert!(file_contains!(public, "fr/tags/index.html", "bonjour")); diff --git a/components/templates/src/builtins/404.html b/components/templates/src/builtins/404.html index f7d50b1a..f8414f0e 100644 --- a/components/templates/src/builtins/404.html +++ b/components/templates/src/builtins/404.html @@ -1,10 +1,3 @@ - - - File Not Found: 404. - - -

Oops!

-

File Not Found: 404.

- - +404 Not Found +

404 Not Found

diff --git a/components/templates/src/builtins/atom.xml b/components/templates/src/builtins/atom.xml new file mode 100644 index 00000000..e4e191cc --- /dev/null +++ b/components/templates/src/builtins/atom.xml @@ -0,0 +1,27 @@ + + + {{ config.title }} + {%- if term %} - {{ term.name }} + {%- endif -%} + + {%- if config.description %} + {{ config.description }} + {%- endif %} + + + Zola + {{ last_updated | date(format="%+") }} + {{ feed_url | safe }} + {%- for page in pages %} + + {{ page.title }} + {{ page.date | date(format="%+") }} + {{ page.updated | default(value=page.date) | date(format="%+") }} + + {{ page.permalink | safe }} + {{ page.content }} + + {%- endfor %} + diff --git a/components/templates/src/builtins/internal/alias.html b/components/templates/src/builtins/internal/alias.html index 1759ae78..54f782e2 100644 --- a/components/templates/src/builtins/internal/alias.html +++ b/components/templates/src/builtins/internal/alias.html @@ -1,12 +1,6 @@ - - - - Redirect - - - - - -

Click here to be redirected.

- - + + + + +Redirect +

Click here to be redirected.

diff --git a/components/templates/src/builtins/rss.xml b/components/templates/src/builtins/rss.xml index aecb42bf..a76f6475 100644 --- a/components/templates/src/builtins/rss.xml +++ b/components/templates/src/builtins/rss.xml @@ -7,15 +7,15 @@ Zola {{ config.default_language }} - {{ last_build_date | date(format="%a, %d %b %Y %H:%M:%S %z") }} - {% for page in pages %} - - {{ page.title }} - {{ page.date | date(format="%a, %d %b %Y %H:%M:%S %z") }} - {{ page.permalink | escape_xml | safe }} - {{ page.permalink | escape_xml | safe }} - {% if page.summary %}{{ page.summary }}{% else %}{{ page.content }}{% endif %} - - {% endfor %} + {{ last_updated | date(format="%a, %d %b %Y %H:%M:%S %z") }} + {%- for page in pages %} + + {{ page.title }} + {{ page.date | date(format="%a, %d %b %Y %H:%M:%S %z") }} + {{ page.permalink | escape_xml | safe }} + {{ page.permalink | escape_xml | safe }} + {% if page.summary %}{{ page.summary }}{% else %}{{ page.content }}{% endif %} + + {%- endfor %} diff --git a/components/templates/src/builtins/shortcodes/streamable.html b/components/templates/src/builtins/shortcodes/streamable.html index 0fca7f77..d45fa642 100644 --- a/components/templates/src/builtins/shortcodes/streamable.html +++ b/components/templates/src/builtins/shortcodes/streamable.html @@ -1,7 +1,3 @@
- +
diff --git a/components/templates/src/builtins/shortcodes/vimeo.html b/components/templates/src/builtins/shortcodes/vimeo.html index 99760879..0a4298c7 100644 --- a/components/templates/src/builtins/shortcodes/vimeo.html +++ b/components/templates/src/builtins/shortcodes/vimeo.html @@ -1,4 +1,3 @@
- +
diff --git a/components/templates/src/builtins/shortcodes/youtube.html b/components/templates/src/builtins/shortcodes/youtube.html index 5f10206f..26a7fe54 100644 --- a/components/templates/src/builtins/shortcodes/youtube.html +++ b/components/templates/src/builtins/shortcodes/youtube.html @@ -1,4 +1,3 @@
- +
diff --git a/components/templates/src/builtins/sitemap.xml b/components/templates/src/builtins/sitemap.xml index 0c2608a8..aeb85387 100644 --- a/components/templates/src/builtins/sitemap.xml +++ b/components/templates/src/builtins/sitemap.xml @@ -1,11 +1,11 @@ - {% for sitemap_entry in entries %} - - {{ sitemap_entry.permalink | escape_xml | safe }} - {% if sitemap_entry.date %} - {{ sitemap_entry.date }} - {% endif %} - - {% endfor %} + {%- for sitemap_entry in entries %} + + {{ sitemap_entry.permalink | escape_xml | safe }} + {%- if sitemap_entry.updated %} + {{ sitemap_entry.updated }} + {%- endif %} + + {%- endfor %} diff --git a/components/templates/src/builtins/split_sitemap_index.xml b/components/templates/src/builtins/split_sitemap_index.xml index 740e322a..b44801ce 100644 --- a/components/templates/src/builtins/split_sitemap_index.xml +++ b/components/templates/src/builtins/split_sitemap_index.xml @@ -1,8 +1,8 @@ - {% for sitemap in sitemaps %} - - {{ sitemap }} - - {% endfor %} - \ No newline at end of file + {%- for sitemap in sitemaps %} + + {{ sitemap }} + + {%- endfor %} + diff --git a/components/templates/src/lib.rs b/components/templates/src/lib.rs index 9c04651b..a0ca5947 100644 --- a/components/templates/src/lib.rs +++ b/components/templates/src/lib.rs @@ -11,6 +11,7 @@ lazy_static! { let mut tera = Tera::default(); tera.add_raw_templates(vec![ ("__zola_builtins/404.html", include_str!("builtins/404.html")), + ("__zola_builtins/atom.xml", include_str!("builtins/atom.xml")), ("__zola_builtins/rss.xml", include_str!("builtins/rss.xml")), ("__zola_builtins/sitemap.xml", include_str!("builtins/sitemap.xml")), ("__zola_builtins/robots.txt", include_str!("builtins/robots.txt")), diff --git a/docs/content/documentation/content/linking.md b/docs/content/documentation/content/linking.md index 20bc065c..9ac2402f 100644 --- a/docs/content/documentation/content/linking.md +++ b/docs/content/documentation/content/linking.md @@ -5,8 +5,9 @@ weight = 50 ## Heading id and anchor insertion While rendering the Markdown content, a unique id will automatically be assigned to each heading. -This id is created by converting the heading text to a [slug](https://en.wikipedia.org/wiki/Semantic_URL#Slug) if `slugify_paths` is enabled. -if `slugify_paths` is disabled, whitespaces are replaced by `_` and the following characters are stripped: `#`, `%`, `<`, `>`, `[`, `]`, `(`, `)`, \`, `^`, `{`, `|`, `}`. +This id is created by converting the heading text to a [slug](https://en.wikipedia.org/wiki/Semantic_URL#Slug) if `slugify.anchors` is set to `"on"` (the default). +If `slugify.paths` is set to `"safe"`, whitespaces are replaced by `_` and the following characters are stripped: `#`, `%`, `<`, `>`, `[`, `]`, `(`, `)`, \`, `^`, `{`, `|`, `}`. +If `slugify.paths` is set to `"off"`, no modifications are made, and you may be left with nominally illegal ids. A number is appended at the end if the slug already exists for that article For example: diff --git a/docs/content/documentation/content/multilingual.md b/docs/content/documentation/content/multilingual.md index 9f459708..b9541fa7 100644 --- a/docs/content/documentation/content/multilingual.md +++ b/docs/content/documentation/content/multilingual.md @@ -11,9 +11,9 @@ to your `config.toml`. For example: ```toml languages = [ - {code = "fr", rss = true}, # there will be a RSS feed for French content + {code = "fr", feed = true}, # there will be a feed for French content {code = "fr", search = true}, # there will be a Search Index for French content - {code = "it"}, # there won't be a RSS feed for Italian content + {code = "it"}, # there won't be a feed for Italian content ] ``` diff --git a/docs/content/documentation/content/page.md b/docs/content/documentation/content/page.md index b43790fc..d1f98fc1 100644 --- a/docs/content/documentation/content/page.md +++ b/docs/content/documentation/content/page.md @@ -35,12 +35,13 @@ For any page within your content folder, its output path will be defined by eith - its filename Either way, these proposed path will be sanitized before being used. -If `slugify_paths` is enabled in the site's config - the default - paths are [slugified](https://en.wikipedia.org/wiki/Clean_URL#Slug). -Otherwise, a simpler sanitation is performed, outputting only valid NTFS paths. -The following characters are removed: `<`, `>`, `:`, `/`, `|`, `?`, `*`, `#`, `\\`, `(`, `)`, `[`, `]` as well as newlines and tabulations. +If `slugify.paths` is set to `"on"` in the site's config - the default - paths are [slugified](https://en.wikipedia.org/wiki/Clean_URL#Slug). +If it is set to `"safe"`, only sanitation is performed, with the following characters being removed: `<`, `>`, `:`, `/`, `|`, `?`, `*`, `#`, `\\`, `(`, `)`, `[`, `]` as well as newlines and tabulations. This ensures that the path can be represented on all operating systems. Additionally, trailing whitespace and dots are removed and whitespaces are replaced by `_`. -**NOTE:** To produce URLs containing non-English characters (UTF8), `slugify_paths` needs to be set to `false`. +If `slugify.paths` is set to `"off"`, no modifications are made. + +If you want URLs containing non-ASCII characters, `slugify.paths` needs to be set to `"safe"` or `"off"`. ### Path from frontmatter @@ -56,7 +57,7 @@ slug = "femmes-libres-libération-kurde" This is my article. ``` -This frontmatter will output the article to `[base_url]/zines/femmes-libres-libération-kurde` with `slugify_paths` disabled, and to `[base_url]/zines/femmes-libres-liberation-kurde` with `slugify_enabled` enabled. +This frontmatter will output the article to `[base_url]/zines/femmes-libres-libération-kurde` with `slugify.paths` set to `"safe"` or `"off"`, and to `[base_url]/zines/femmes-libres-liberation-kurde` with the default value for `slugify.paths` of `"on"`. ### Path from filename @@ -66,7 +67,7 @@ When the article's output path is not specified in the frontmatter, it is extrac If the path found starts with a datetime string (`YYYY-mm-dd` or [a RFC3339 datetime](https://www.ietf.org/rfc/rfc3339.txt)) followed by an underscore (`_`) or a dash (`-`), this date is removed from the output path and will be used as the page date (unless already set in the front-matter). Note that the full RFC3339 datetime contains colons, which is not a valid character in a filename on Windows. -The output path extracted from the file path is then slugified or not depending on the `slugify_paths` config, as explained previously. +The output path extracted from the file path is then slugified or not, depending on the `slugify.paths` config, as explained previously. **Example:** The file `content/blog/2018-10-10-hello-world.md` will generated a page available at will be available at `[base_url]/hello-world`. @@ -92,6 +93,10 @@ description = "" # Setting this overrides a date set in the filename. date = +# The last updated date of the post, if different from the date. +# Same format as `date`. +updated = + # The weight as defined on the Section page of the documentation. # If the section variable `sort_by` is set to `weight`, then any page that lacks a `weight` # will not be rendered. diff --git a/docs/content/documentation/content/taxonomies.md b/docs/content/documentation/content/taxonomies.md index e312f169..31efeb97 100644 --- a/docs/content/documentation/content/taxonomies.md +++ b/docs/content/documentation/content/taxonomies.md @@ -13,7 +13,7 @@ A taxonomy has five variables: - `paginate_by`: if this is set to a number, each term page will be paginated by this much. - `paginate_path`: if set, this path will be used by the paginated page and the page number will be appended after it. For example the default would be page/1. -- `rss`: if set to `true`, an RSS feed will be generated for each term. +- `feed`: if set to `true`, a feed will be generated for each term. - `lang`: only set this if you are making a multilingual site and want to indicate which language this taxonomy is for **Example 1:** (one language) @@ -52,7 +52,7 @@ categories = ["programming"] In a similar manner to how section and pages calculate their output path: - the taxonomy name is never slugified -- the taxonomy entry (eg. as specific tag) is slugified when `slugify_paths` is enabled in the configuration +- the taxonomy term (eg. as specific tag) is slugified when `slugify.taxonomies` is enabled (`"on"`, the default) in the configuration The taxonomy pages are then available at the following paths: diff --git a/docs/content/documentation/getting-started/configuration.md b/docs/content/documentation/getting-started/configuration.md index da4079b8..4b106b23 100644 --- a/docs/content/documentation/getting-started/configuration.md +++ b/docs/content/documentation/getting-started/configuration.md @@ -17,11 +17,11 @@ used by Zola as well as their default values are listed below: # The base URL of the site; the only required configuration variable. base_url = "mywebsite.com" -# The site title and description; used in RSS by default. +# The site title and description; used in feeds by default. title = "" description = "" -# The default language; used in RSS. +# The default language; used in feeds. default_language = "en" # The site theme to use. @@ -34,12 +34,17 @@ highlight_code = false # See below for list of allowed values. highlight_theme = "base16-ocean-dark" -# When set to "true", an RSS feed is automatically generated. -generate_rss = false +# When set to "true", a feed is automatically generated. +generate_feed = false -# The number of articles to include in the RSS feed. All items are included if +# The filename to use for the feed. Used as the template filename, too. +# Defaults to "atom.xml", which has a builtin template that renders an Atom 1.0 feed. +# There is also a builtin template "rss.xml" that renders an RSS 2.0 feed. +# feed_filename = "atom.xml" + +# The number of articles to include in the feed. All items are included if # this limit is not set (the default). -# rss_limit = 20 +# feed_limit = 20 # When set to "true", files in the `static` directory are hard-linked. Useful for large # static files. Note that for this to work, both `static` and the @@ -50,10 +55,10 @@ generate_rss = false # The taxonomies to be rendered for the site and their configuration. # Example: # taxonomies = [ -# {name = "tags", rss = true}, # each tag will have its own RSS feed +# {name = "tags", feed = true}, # each tag will have its own feed # {name = "tags", lang = "fr"}, # you can have taxonomies with the same name in multiple languages # {name = "categories", paginate_by = 5}, # 5 items per page for a term -# {name = "authors"}, # Basic definition: no RSS or pagination +# {name = "authors"}, # Basic definition: no feed or pagination # ] # taxonomies = [] @@ -61,9 +66,9 @@ taxonomies = [] # The additional languages for the site. # Example: # languages = [ -# {code = "fr", rss = true}, # there will be a RSS feed for French content +# {code = "fr", feed = true}, # there will be a feed for French content # {code = "fr", search = true}, # there will be a Search Index for French content -# {code = "it"}, # there won't be a RSS feed for Italian content +# {code = "it"}, # there won't be a feed for Italian content # ] # languages = [] diff --git a/docs/content/documentation/templates/feeds.md b/docs/content/documentation/templates/feeds.md new file mode 100644 index 00000000..fb0dec5e --- /dev/null +++ b/docs/content/documentation/templates/feeds.md @@ -0,0 +1,34 @@ ++++ +title = "Feeds" +weight = 50 +aliases = ["/documentation/templates/rss/"] ++++ + +If the site `config.toml` file sets `generate_feed = true`, then Zola will +generate a feed file for the site, named according to the `feed_filename` +setting in `config.toml`, which defaults to `atom.xml`. Given the feed filename +`atom.xml`, the generated file will live at `base_url/atom.xml`, based upon the +`atom.xml` file in the `templates` directory, or the built-in Atom template. + +`feed_filename` can be set to any value, but built-in templates are provided +for `atom.xml` (in the preferred Atom 1.0 format), and `rss.xml` (in the RSS +2.0 format). If you choose a different filename (e.g. `feed.xml`), you will +need to provide a template yourself. + +**Only pages with a date will be available.** + +The feed template gets five variables: + +- `config`: the site config +- `feed_url`: the full url to that specific feed +- `last_updated`: the most recent `updated` or `date` field of any post +- `pages`: see [page variables](@/documentation/templates/pages-sections.md#page-variables) + for a detailed description of what this contains +- `lang`: the language code that applies to all of the pages in the feed, + if the site is multilingual, or `config.default_language` if it is not + +Feeds for taxonomy terms get two more variables, using types from the +[taxonomies templates](@/documentation/templates/taxonomies.md): + +- `taxonomy`: of type `TaxonomyConfig` +- `term`: of type `TaxonomyTerm`, but without `term.pages` (use `pages` instead) diff --git a/docs/content/documentation/templates/overview.md b/docs/content/documentation/templates/overview.md index 1db30acf..4f64e63c 100644 --- a/docs/content/documentation/templates/overview.md +++ b/docs/content/documentation/templates/overview.md @@ -13,7 +13,7 @@ to learn more about it first. All templates live in the `templates` directory. If you are not sure what variables are available in a template, you can place `{{ __tera_context }}` in the template to print the whole context. -A few variables are available on all templates except RSS and the sitemap: +A few variables are available on all templates except feeds and the sitemap: - `config`: the [configuration](@/documentation/getting-started/configuration.md) without any modifications - `current_path`: the path (full URL without `base_url`) of the current page, never starting with a `/` @@ -36,12 +36,13 @@ section variables. The `page.html` template has access to the page variables. The page and section variables are described in more detail in the next section. ## Built-in templates -Zola comes with three built-in templates: `rss.xml`, `sitemap.xml` and -`robots.txt` (each is described in its own section of this documentation). +Zola comes with four built-in templates: `atom.xml` and `rss.xml` (described in +[Feeds](@/documentation/templates/feeds.md)), `sitemap.xml` (described in [Sitemap](@/documentation/templates/sitemap.md)), +and `robots.txt` (described in [Robots.txt](@/documentation/templates/robots.md)). Additionally, themes can add their own templates, which will be applied if not overridden. You can override built-in or theme templates by creating a template with -the same name in the correct path. For example, you can override the RSS template by -creating a `templates/rss.xml` file. +the same name in the correct path. For example, you can override the Atom template by +creating a `templates/atom.xml` file. ## Custom templates In addition to the standard `index.html`, `section.html` and `page.html` templates, diff --git a/docs/content/documentation/templates/pages-sections.md b/docs/content/documentation/templates/pages-sections.md index 91e2f7a0..7d249e30 100644 --- a/docs/content/documentation/templates/pages-sections.md +++ b/docs/content/documentation/templates/pages-sections.md @@ -19,6 +19,8 @@ content: String; title: String?; description: String?; date: String?; +// `updated` will be the same as `date` if `date` is specified but `updated` is not in front-matter +updated: String?; slug: String; path: String; draft: Bool; diff --git a/docs/content/documentation/templates/rss.md b/docs/content/documentation/templates/rss.md deleted file mode 100644 index d2e89f74..00000000 --- a/docs/content/documentation/templates/rss.md +++ /dev/null @@ -1,18 +0,0 @@ -+++ -title = "RSS" -weight = 50 -+++ - -If the site `config.toml` file sets `generate_rss = true`, then Zola will -generate an `rss.xml` page for the site, which will live at `base_url/rss.xml`. To -generate the `rss.xml` page, Zola will look for an `rss.xml` file in the `templates` -directory or, if one does not exist, it will use the use the built-in rss template. - -**Only pages with a date will be available.** - -The RSS template gets three variables in addition to `config`: - -- `feed_url`: the full url to that specific feed -- `last_build_date`: the date of the latest post -- `pages`: see [page variables](@/documentation/templates/pages-sections.md#page-variables) for -a detailed description of what this contains diff --git a/docs/content/documentation/templates/sitemap.md b/docs/content/documentation/templates/sitemap.md index decd397c..3c213516 100644 --- a/docs/content/documentation/templates/sitemap.md +++ b/docs/content/documentation/templates/sitemap.md @@ -25,7 +25,7 @@ A `SitemapEntry` has the following fields: ```ts permalink: String; -date: String?; +updated: String?; extra: Hashmap?; ``` diff --git a/docs/content/documentation/templates/taxonomies.md b/docs/content/documentation/templates/taxonomies.md index cfebf88e..7999957c 100644 --- a/docs/content/documentation/templates/taxonomies.md +++ b/docs/content/documentation/templates/taxonomies.md @@ -21,10 +21,10 @@ and `TaxonomyConfig` has the following fields: ```ts name: String, -slug: String, paginate_by: Number?; paginate_path: String?; -rss: Bool; +feed: Bool; +lang: String; ``` @@ -64,5 +64,5 @@ term: TaxonomyTerm; lang: String; ``` -A paginated taxonomy term will also get a `paginator` variable; see the [pagination page] -(@/documentation/templates/pagination.md) for more details. +A paginated taxonomy term will also get a `paginator` variable; see the +[pagination page](@/documentation/templates/pagination.md) for more details. diff --git a/docs/content/themes/Zulma/index.md b/docs/content/themes/Zulma/index.md index 1ece6301..ffdbe6a5 100644 --- a/docs/content/themes/Zulma/index.md +++ b/docs/content/themes/Zulma/index.md @@ -100,8 +100,8 @@ Zulma has 3 taxonomies already set internally: `tags`, `cateogories` and `author ```toml taxonomies = [ {name = "categories"}, - {name = "tags", paginate_by = 5, rss = true}, - {name = "authors", rss = true}, + {name = "tags", paginate_by = 5, feed = true}, + {name = "authors", feed = true}, ] ``` diff --git a/docs/content/themes/after-dark/index.md b/docs/content/themes/after-dark/index.md index d88236b6..52579550 100644 --- a/docs/content/themes/after-dark/index.md +++ b/docs/content/themes/after-dark/index.md @@ -55,9 +55,9 @@ The theme requires tags and categories taxonomies to be enabled in your `config. ```toml taxonomies = [ - # You can enable/disable RSS - {name = "categories", rss = true}, - {name = "tags", rss = true}, + # You can enable/disable feeds + {name = "categories", feed = true}, + {name = "tags", feed = true}, ] ``` If you want to paginate taxonomies pages, you will need to overwrite the templates diff --git a/docs/content/themes/even/index.md b/docs/content/themes/even/index.md index 50460050..f9beedcb 100644 --- a/docs/content/themes/even/index.md +++ b/docs/content/themes/even/index.md @@ -48,9 +48,9 @@ The theme requires tags and categories taxonomies to be enabled in your `config. ```toml taxonomies = [ - # You can enable/disable RSS - {name = "categories", rss = true}, - {name = "tags", rss = true}, + # You can enable/disable feeds + {name = "categories", feed = true}, + {name = "tags", feed = true}, ] ``` If you want to paginate taxonomies pages, you will need to overwrite the templates diff --git a/sublime_themes/dracula.tmTheme b/sublime_themes/dracula.tmTheme old mode 100755 new mode 100644 diff --git a/test_site/config.toml b/test_site/config.toml index 7d837c8b..9c09c598 100644 --- a/test_site/config.toml +++ b/test_site/config.toml @@ -2,12 +2,12 @@ title = "My site" base_url = "https://replace-this-with-your-url.com" highlight_code = true compile_sass = true -generate_rss = true +generate_feed = true theme = "sample" slugify_paths = true taxonomies = [ - {name = "categories", rss = true}, + {name = "categories", feed = true}, ] extra_syntaxes = ["syntaxes"] diff --git a/test_site_i18n/config.toml b/test_site_i18n/config.toml index a12f5e9a..2d6d34ab 100644 --- a/test_site_i18n/config.toml +++ b/test_site_i18n/config.toml @@ -13,18 +13,18 @@ build_search_index = true default_language = "en" -generate_rss = true +generate_feed = true taxonomies = [ - {name = "authors", rss = true}, + {name = "authors", feed = true}, {name = "auteurs", lang = "fr"}, {name = "tags"}, {name = "tags", lang = "fr"}, ] languages = [ - {code = "fr", rss = true}, - {code = "it", rss = false, search = true }, + {code = "fr", feed = true}, + {code = "it", feed = false, search = true }, ] [extra]