From d571dea8c33ce4fcbe7f1a436212158028066cb6 Mon Sep 17 00:00:00 2001 From: Yaroslav Date: Thu, 27 Aug 2020 21:21:37 +0300 Subject: [PATCH] Per section/subsection feeds (#1128) * Per section/subsection feeds * Added `generate_feed` variable to section front matter. * Generate atom/rss feeds for sections/subsections that have the `generate_feed` variable set to true (false by default); this works independent of the `generate_feed` variable in the root `config.toml` file, however, the name (and template) of the feed file for each section is the same as `feed_filename` in `config.toml`, just located in the root of each section. * Slightly edited `atom.xml` and `rss.xml` so that they include the section title (if any), and the url of a section, if it's a section feed. * Section feeds: tests * Changed a couple of sections' front matter in order to generate feeds for them for the test. * Changed the can_build_feed test in site package to can_build_feeds and included some assertions to make sure that section feeds are generated when requested. * Section feeds: documentation * Added information about the section front matter variable `generate_feed` in the section content page. * Added information about section feeds in the feeds template page. * Section feeds fix: use section.path for feed path --- components/front_matter/src/section.rs | 4 ++++ components/site/src/lib.rs | 18 ++++++++++++++++++ components/site/tests/site.rs | 10 +++++++++- components/templates/src/builtins/atom.xml | 9 ++++++++- components/templates/src/builtins/rss.xml | 13 +++++++++++-- docs/content/documentation/content/section.md | 6 ++++++ .../documentation/templates/feeds/index.md | 7 +++++++ test_site/content/posts/_index.md | 1 + .../posts/tutorials/programming/_index.md | 1 + 9 files changed, 65 insertions(+), 4 deletions(-) diff --git a/components/front_matter/src/section.rs b/components/front_matter/src/section.rs index d0bf5265..a574216a 100644 --- a/components/front_matter/src/section.rs +++ b/components/front_matter/src/section.rs @@ -60,6 +60,9 @@ pub struct SectionFrontMatter { /// redirect to this #[serde(skip_serializing)] pub aliases: Vec, + /// Whether to generate a feed for the current section + #[serde(skip_serializing)] + pub generate_feed: bool, /// Any extra parameter present in the front matter pub extra: Map, } @@ -105,6 +108,7 @@ impl Default for SectionFrontMatter { transparent: false, page_template: None, aliases: Vec::new(), + generate_feed: false, extra: Map::new(), } } diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index dc2befd3..cd8b6bff 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -901,6 +901,24 @@ impl Site { } } + if section.meta.generate_feed { + let library = &self.library.read().unwrap(); + let pages = section + .pages + .iter() + .map(|k| library.get_page_by_key(*k)) + .collect(); + self.render_feed( + pages, + Some(&PathBuf::from(§ion.path[1..])), + §ion.lang, + |mut context: Context| { + context.insert("section", §ion.to_serialized(library)); + context + }, + )?; + } + // Copy any asset we found previously into the same directory as the index.html for asset in §ion.assets { let asset_path = asset.as_path(); diff --git a/components/site/tests/site.rs b/components/site/tests/site.rs index 170db3f5..bf9f3358 100644 --- a/components/site/tests/site.rs +++ b/components/site/tests/site.rs @@ -613,7 +613,7 @@ fn can_build_site_with_pagination_for_taxonomy() { } #[test] -fn can_build_feed() { +fn can_build_feeds() { let (_, _tmp_dir, public) = build_site("test_site"); assert!(&public.exists()); @@ -622,6 +622,14 @@ fn can_build_feed() { assert!(file_contains!(public, "atom.xml", "Extra Syntax")); // Next is posts/simple.md assert!(file_contains!(public, "atom.xml", "Simple article with shortcodes")); + + // Test section feeds + assert!(file_exists!(public, "posts/tutorials/programming/atom.xml")); + // It contains both sections articles + assert!(file_contains!(public, "posts/tutorials/programming/atom.xml", "Python tutorial")); + assert!(file_contains!(public, "posts/tutorials/programming/atom.xml", "Rust")); + // It doesn't contain articles from other sections + assert!(!file_contains!(public, "posts/tutorials/programming/atom.xml", "Extra Syntax")); } #[test] diff --git a/components/templates/src/builtins/atom.xml b/components/templates/src/builtins/atom.xml index b2c89443..3ebacb9b 100644 --- a/components/templates/src/builtins/atom.xml +++ b/components/templates/src/builtins/atom.xml @@ -2,13 +2,20 @@ {{ config.title }} {%- if term %} - {{ term.name }} + {%- elif section.title %} - {{ section.title }} {%- endif -%} {%- if config.description %} {{ config.description }} {%- endif %} - + Zola {{ last_updated | date(format="%+") }} {{ feed_url | safe }} diff --git a/components/templates/src/builtins/rss.xml b/components/templates/src/builtins/rss.xml index a76f6475..4eeffdde 100644 --- a/components/templates/src/builtins/rss.xml +++ b/components/templates/src/builtins/rss.xml @@ -1,8 +1,17 @@ - {{ config.title }} - {{ config.base_url | escape_xml | safe }} + {{ config.title }} + {%- if term %} - {{ term.name }} + {%- elif section.title %} - {{ section.title }} + {%- endif -%} + + {%- if section -%} + {{ section.permalink | escape_xml | safe }} + {%- else -%} + {{ config.base_url | escape_xml | safe }} + {%- endif -%} + {{ config.description }} Zola {{ config.default_language }} diff --git a/docs/content/documentation/content/section.md b/docs/content/documentation/content/section.md index 0c35944d..2d6952b1 100644 --- a/docs/content/documentation/content/section.md +++ b/docs/content/documentation/content/section.md @@ -93,6 +93,12 @@ transparent = false # current one. This takes an array of paths, not URLs. aliases = [] +# If set to "true", a feed file will be generated for this section at the +# section's root path. This is independent of the site-wide variable of the same +# name. The section feed will only include posts from that respective feed, and +# not from any other sections, including sub-sections under that section. +generate_feed = false + # Your own data. [extra] ``` diff --git a/docs/content/documentation/templates/feeds/index.md b/docs/content/documentation/templates/feeds/index.md index 77630f6b..fa95f20b 100644 --- a/docs/content/documentation/templates/feeds/index.md +++ b/docs/content/documentation/templates/feeds/index.md @@ -33,6 +33,13 @@ Feeds for taxonomy terms get two more variables, using types from the - `taxonomy`: of type `TaxonomyConfig` - `term`: of type `TaxonomyTerm`, but without `term.pages` (use `pages` instead) +You can also enable separate feeds for each section by setting the +`generate_feed` variable to true in the respective section's front matter. +Section feeds will use the same template as indicated in the `config.toml` file. +Section feeds, in addition to the five feed template variables, get the +`section` variable from the [section +template](@/documentation/templates/pages-sections.md). + Enable feed autodiscovery allows feed readers and browsers to notify user about a RSS or Atom feed available on your web site. So it is easier for user to subscribe. As an example this is how it looks like using [Firefox](https://en.wikipedia.org/wiki/Mozilla_Firefox) [Livemarks](https://addons.mozilla.org/en-US/firefox/addon/livemarks/?src=search) addon. diff --git a/test_site/content/posts/_index.md b/test_site/content/posts/_index.md index cd81b40e..2be1b38c 100644 --- a/test_site/content/posts/_index.md +++ b/test_site/content/posts/_index.md @@ -5,4 +5,5 @@ template = "section_paginated.html" insert_anchor_links = "left" sort_by = "date" aliases = ["another-old-url/index.html"] +generate_feed = true +++ diff --git a/test_site/content/posts/tutorials/programming/_index.md b/test_site/content/posts/tutorials/programming/_index.md index f16966cf..6ab12564 100644 --- a/test_site/content/posts/tutorials/programming/_index.md +++ b/test_site/content/posts/tutorials/programming/_index.md @@ -2,6 +2,7 @@ title = "Programming" sort_by = "weight" weight = 1 +generate_feed = true [extra] we_have_extra = "variables"