diff --git a/CHANGELOG.md b/CHANGELOG.md index 163f13c3..20885a05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # 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. + ## 0.10.2 (unreleased) - Fix link checker not looking for anchor with capital id/name @@ -17,8 +28,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/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/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..3123cd86 100644 --- a/components/rebuild/src/lib.rs +++ b/components/rebuild/src/lib.rs @@ -395,7 +395,9 @@ 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 => { + site.render_feed(site.library.read().unwrap().pages_values(), 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..4cd08058 100644 --- a/components/site/benches/site.rs +++ b/components/site/benches/site.rs @@ -35,12 +35,12 @@ 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).unwrap()); } #[bench] diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index 07a951b6..0ef6615b 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -745,7 +745,7 @@ impl Site { self.render_sitemap()?; let library = self.library.read().unwrap(); - if self.config.generate_rss { + if self.config.generate_feed { let pages = if self.config.is_multilingual() { library .pages_values() @@ -756,16 +756,16 @@ impl Site { } else { library.pages_values() }; - self.render_rss_feed(pages, None)?; + self.render_feed(pages, 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())))?; } self.render_404()?; @@ -983,8 +983,8 @@ 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))), ) @@ -1045,10 +1045,10 @@ 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>, @@ -1058,7 +1058,7 @@ impl Site { 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(()); } @@ -1068,7 +1068,7 @@ impl Site { context.insert("last_build_date", &pages[0].meta.date.clone()); 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) @@ -1078,15 +1078,21 @@ impl Site { context.insert("pages", &p); context.insert("config", &self.config); - 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)?; + 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(); @@ -1096,9 +1102,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/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..acd4b97d 100644 --- a/components/site/tests/site_i18n.rs +++ b/components/site/tests/site_i18n.rs @@ -115,15 +115,15 @@ 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_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/")); + // Italian doesn't have feed enabled + assert!(!file_exists!(public, "it/atom.xml")); // Taxonomies are per-language // English @@ -131,7 +131,7 @@ 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_exists!(public, "tags/index.html")); assert!(file_contains!(public, "tags/index.html", "hello")); @@ -142,7 +142,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/atom.xml b/components/templates/src/builtins/atom.xml new file mode 100644 index 00000000..17f5fe41 --- /dev/null +++ b/components/templates/src/builtins/atom.xml @@ -0,0 +1,21 @@ + + + {{ config.title }} + {{ config.description }} + + + Zola + {{ last_build_date | date(format="%+") }} + {{ feed_url | safe }} + {%- for page in pages %} + + {{ page.title }} + {{ page.date | date(format="%+") }} + + {{ page.permalink | safe }} + {{ page.content }} + + {%- 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/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/taxonomies.md b/docs/content/documentation/content/taxonomies.md index 5a6098e2..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) 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..b013b514 --- /dev/null +++ b/docs/content/documentation/templates/feeds.md @@ -0,0 +1,25 @@ ++++ +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 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/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/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/taxonomies.md b/docs/content/documentation/templates/taxonomies.md index 24f2261b..7999957c 100644 --- a/docs/content/documentation/templates/taxonomies.md +++ b/docs/content/documentation/templates/taxonomies.md @@ -23,7 +23,7 @@ and `TaxonomyConfig` has the following fields: name: String, paginate_by: Number?; paginate_path: String?; -rss: Bool; +feed: Bool; lang: String; ``` 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/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]