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
This commit is contained in:
Yaroslav 2020-08-27 21:21:37 +03:00 committed by GitHub
parent 6e16dfdc29
commit d571dea8c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 4 deletions

View file

@ -60,6 +60,9 @@ pub struct SectionFrontMatter {
/// redirect to this /// redirect to this
#[serde(skip_serializing)] #[serde(skip_serializing)]
pub aliases: Vec<String>, pub aliases: Vec<String>,
/// Whether to generate a feed for the current section
#[serde(skip_serializing)]
pub generate_feed: bool,
/// Any extra parameter present in the front matter /// Any extra parameter present in the front matter
pub extra: Map<String, Value>, pub extra: Map<String, Value>,
} }
@ -105,6 +108,7 @@ impl Default for SectionFrontMatter {
transparent: false, transparent: false,
page_template: None, page_template: None,
aliases: Vec::new(), aliases: Vec::new(),
generate_feed: false,
extra: Map::new(), extra: Map::new(),
} }
} }

View file

@ -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(&section.path[1..])),
&section.lang,
|mut context: Context| {
context.insert("section", &section.to_serialized(library));
context
},
)?;
}
// Copy any asset we found previously into the same directory as the index.html // Copy any asset we found previously into the same directory as the index.html
for asset in &section.assets { for asset in &section.assets {
let asset_path = asset.as_path(); let asset_path = asset.as_path();

View file

@ -613,7 +613,7 @@ fn can_build_site_with_pagination_for_taxonomy() {
} }
#[test] #[test]
fn can_build_feed() { fn can_build_feeds() {
let (_, _tmp_dir, public) = build_site("test_site"); let (_, _tmp_dir, public) = build_site("test_site");
assert!(&public.exists()); assert!(&public.exists());
@ -622,6 +622,14 @@ fn can_build_feed() {
assert!(file_contains!(public, "atom.xml", "Extra Syntax")); assert!(file_contains!(public, "atom.xml", "Extra Syntax"));
// Next is posts/simple.md // Next is posts/simple.md
assert!(file_contains!(public, "atom.xml", "Simple article with shortcodes")); 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] #[test]

View file

@ -2,13 +2,20 @@
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ lang }}"> <feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ lang }}">
<title>{{ config.title }} <title>{{ config.title }}
{%- if term %} - {{ term.name }} {%- if term %} - {{ term.name }}
{%- elif section.title %} - {{ section.title }}
{%- endif -%} {%- endif -%}
</title> </title>
{%- if config.description %} {%- if config.description %}
<subtitle>{{ config.description }}</subtitle> <subtitle>{{ config.description }}</subtitle>
{%- endif %} {%- endif %}
<link href="{{ feed_url | safe }}" rel="self" type="application/atom+xml"/> <link href="{{ feed_url | safe }}" rel="self" type="application/atom+xml"/>
<link href="{{ config.base_url | safe }}"/> <link href="
{%- if section -%}
{{ section.permalink | escape_xml | safe }}
{%- else -%}
{{ config.base_url | escape_xml | safe }}
{%- endif -%}
"/>
<generator uri="https://www.getzola.org/">Zola</generator> <generator uri="https://www.getzola.org/">Zola</generator>
<updated>{{ last_updated | date(format="%+") }}</updated> <updated>{{ last_updated | date(format="%+") }}</updated>
<id>{{ feed_url | safe }}</id> <id>{{ feed_url | safe }}</id>

View file

@ -1,8 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"> <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel> <channel>
<title>{{ config.title }}</title> <title>{{ config.title }}
<link>{{ config.base_url | escape_xml | safe }}</link> {%- if term %} - {{ term.name }}
{%- elif section.title %} - {{ section.title }}
{%- endif -%}
</title>
<link>{%- if section -%}
{{ section.permalink | escape_xml | safe }}
{%- else -%}
{{ config.base_url | escape_xml | safe }}
{%- endif -%}
</link>
<description>{{ config.description }}</description> <description>{{ config.description }}</description>
<generator>Zola</generator> <generator>Zola</generator>
<language>{{ config.default_language }}</language> <language>{{ config.default_language }}</language>

View file

@ -93,6 +93,12 @@ transparent = false
# current one. This takes an array of paths, not URLs. # current one. This takes an array of paths, not URLs.
aliases = [] 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. # Your own data.
[extra] [extra]
``` ```

View file

@ -33,6 +33,13 @@ Feeds for taxonomy terms get two more variables, using types from the
- `taxonomy`: of type `TaxonomyConfig` - `taxonomy`: of type `TaxonomyConfig`
- `term`: of type `TaxonomyTerm`, but without `term.pages` (use `pages` instead) - `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. 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. 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.

View file

@ -5,4 +5,5 @@ template = "section_paginated.html"
insert_anchor_links = "left" insert_anchor_links = "left"
sort_by = "date" sort_by = "date"
aliases = ["another-old-url/index.html"] aliases = ["another-old-url/index.html"]
generate_feed = true
+++ +++

View file

@ -2,6 +2,7 @@
title = "Programming" title = "Programming"
sort_by = "weight" sort_by = "weight"
weight = 1 weight = 1
generate_feed = true
[extra] [extra]
we_have_extra = "variables" we_have_extra = "variables"