Add lang, taxonomy and term to feed template
Also a FIXME on the rebuilding part, because it’s presently very wrong.
This commit is contained in:
parent
eb7751955a
commit
4653e68715
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
### Other
|
### 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 `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)
|
## 0.10.2 (unreleased)
|
||||||
|
|
||||||
|
|
|
@ -396,7 +396,15 @@ pub fn after_template_change(site: &mut Site, path: &Path) -> Result<()> {
|
||||||
match filename {
|
match filename {
|
||||||
"sitemap.xml" => site.render_sitemap(),
|
"sitemap.xml" => site.render_sitemap(),
|
||||||
filename if filename == site.config.feed_filename => {
|
filename if filename == site.config.feed_filename => {
|
||||||
site.render_feed(site.library.read().unwrap().pages_values(), None)
|
// 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(),
|
"split_sitemap_index.xml" => site.render_sitemap(),
|
||||||
"robots.txt" => site.render_robots(),
|
"robots.txt" => site.render_robots(),
|
||||||
|
|
|
@ -40,7 +40,14 @@ fn bench_render_feed(b: &mut test::Bencher) {
|
||||||
let tmp_dir = tempdir().expect("create temp dir");
|
let tmp_dir = tempdir().expect("create temp dir");
|
||||||
let public = &tmp_dir.path().join("public");
|
let public = &tmp_dir.path().join("public");
|
||||||
site.set_output_path(&public);
|
site.set_output_path(&public);
|
||||||
b.iter(|| site.render_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]
|
#[bench]
|
||||||
|
|
|
@ -8,13 +8,15 @@ use std::sync::{Arc, Mutex, RwLock};
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use sass_rs::{compile_file, Options as SassOptions, OutputStyle};
|
use sass_rs::{compile_file, Options as SassOptions, OutputStyle};
|
||||||
|
use serde_derive::Serialize;
|
||||||
use tera::{Context, Tera};
|
use tera::{Context, Tera};
|
||||||
|
|
||||||
use config::{get_config, Config};
|
use config::{get_config, Config, Taxonomy as TaxonomyConfig};
|
||||||
use errors::{bail, Error, ErrorKind, Result};
|
use errors::{bail, Error, ErrorKind, Result};
|
||||||
use front_matter::InsertAnchor;
|
use front_matter::InsertAnchor;
|
||||||
use library::{
|
use library::{
|
||||||
find_taxonomies, sort_actual_pages_by_date, Library, Page, Paginator, Section, Taxonomy,
|
find_taxonomies, sort_actual_pages_by_date, Library, Page, Paginator, Section, Taxonomy,
|
||||||
|
TaxonomyItem,
|
||||||
};
|
};
|
||||||
use link_checker::check_url;
|
use link_checker::check_url;
|
||||||
use templates::{global_fns, render_redirect_template, ZOLA_TERA};
|
use templates::{global_fns, render_redirect_template, ZOLA_TERA};
|
||||||
|
@ -45,6 +47,23 @@ pub struct Site {
|
||||||
include_drafts: bool,
|
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 {
|
impl Site {
|
||||||
/// Parse a site at the given path. Defaults to the current dir
|
/// 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
|
/// Passing in a path is used in tests and when --root argument is passed
|
||||||
|
@ -746,7 +765,8 @@ impl Site {
|
||||||
|
|
||||||
let library = self.library.read().unwrap();
|
let library = self.library.read().unwrap();
|
||||||
if self.config.generate_feed {
|
if self.config.generate_feed {
|
||||||
let pages = if self.config.is_multilingual() {
|
let is_multilingual = self.config.is_multilingual();
|
||||||
|
let pages = if is_multilingual {
|
||||||
library
|
library
|
||||||
.pages_values()
|
.pages_values()
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -756,7 +776,12 @@ impl Site {
|
||||||
} else {
|
} else {
|
||||||
library.pages_values()
|
library.pages_values()
|
||||||
};
|
};
|
||||||
self.render_feed(pages, None)?;
|
self.render_feed(
|
||||||
|
pages,
|
||||||
|
None,
|
||||||
|
&self.config.default_language,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for lang in &self.config.languages {
|
for lang in &self.config.languages {
|
||||||
|
@ -765,7 +790,12 @@ impl Site {
|
||||||
}
|
}
|
||||||
let pages =
|
let pages =
|
||||||
library.pages_values().iter().filter(|p| p.lang == lang.code).cloned().collect();
|
library.pages_values().iter().filter(|p| p.lang == lang.code).cloned().collect();
|
||||||
self.render_feed(pages, Some(&PathBuf::from(lang.code.clone())))?;
|
self.render_feed(
|
||||||
|
pages,
|
||||||
|
Some(&PathBuf::from(lang.code.clone())),
|
||||||
|
&lang.code,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_404()?;
|
self.render_404()?;
|
||||||
|
@ -987,6 +1017,12 @@ impl Site {
|
||||||
self.render_feed(
|
self.render_feed(
|
||||||
item.pages.iter().map(|p| library.get_page_by_key(*p)).collect(),
|
item.pages.iter().map(|p| library.get_page_by_key(*p)).collect(),
|
||||||
Some(&PathBuf::from(format!("{}/{}", taxonomy.kind.name, item.slug))),
|
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 {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1052,6 +1088,8 @@ impl Site {
|
||||||
&self,
|
&self,
|
||||||
all_pages: Vec<&Page>,
|
all_pages: Vec<&Page>,
|
||||||
base_path: Option<&PathBuf>,
|
base_path: Option<&PathBuf>,
|
||||||
|
lang: &str,
|
||||||
|
taxonomy_and_item: Option<(&TaxonomyConfig, &TaxonomyItem)>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
ensure_directory_exists(&self.output_path)?;
|
ensure_directory_exists(&self.output_path)?;
|
||||||
|
|
||||||
|
@ -1084,6 +1122,7 @@ impl Site {
|
||||||
|
|
||||||
context.insert("pages", &p);
|
context.insert("pages", &p);
|
||||||
context.insert("config", &self.config);
|
context.insert("config", &self.config);
|
||||||
|
context.insert("lang", lang);
|
||||||
|
|
||||||
let feed_filename = &self.config.feed_filename;
|
let feed_filename = &self.config.feed_filename;
|
||||||
let feed_url = if let Some(ref base) = base_path {
|
let feed_url = if let Some(ref base) = base_path {
|
||||||
|
@ -1099,6 +1138,11 @@ impl Site {
|
||||||
|
|
||||||
context.insert("feed_url", &feed_url);
|
context.insert("feed_url", &feed_url);
|
||||||
|
|
||||||
|
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)?;
|
let feed = &render_template(feed_filename, &self.tera, context, &self.config.theme)?;
|
||||||
|
|
||||||
if let Some(ref base) = base_path {
|
if let Some(ref base) = base_path {
|
||||||
|
|
|
@ -119,9 +119,11 @@ fn can_build_multilingual_site() {
|
||||||
assert!(file_exists!(public, "atom.xml"));
|
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/blog/something-else/"));
|
||||||
assert!(!file_contains!(public, "atom.xml", "https://example.com/fr/blog/something-else/"));
|
assert!(!file_contains!(public, "atom.xml", "https://example.com/fr/blog/something-else/"));
|
||||||
|
assert!(file_contains!(public, "atom.xml", r#"<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">"#));
|
||||||
assert!(file_exists!(public, "fr/atom.xml"));
|
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/blog/something-else/"));
|
||||||
assert!(file_contains!(public, "fr/atom.xml", "https://example.com/fr/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#"<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">"#));
|
||||||
// Italian doesn't have feed enabled
|
// Italian doesn't have feed enabled
|
||||||
assert!(!file_exists!(public, "it/atom.xml"));
|
assert!(!file_exists!(public, "it/atom.xml"));
|
||||||
|
|
||||||
|
@ -132,6 +134,8 @@ fn can_build_multilingual_site() {
|
||||||
assert!(!file_contains!(public, "authors/index.html", "Vincent"));
|
assert!(!file_contains!(public, "authors/index.html", "Vincent"));
|
||||||
assert!(!file_exists!(public, "auteurs/index.html"));
|
assert!(!file_exists!(public, "auteurs/index.html"));
|
||||||
assert!(file_exists!(public, "authors/queen-elizabeth/atom.xml"));
|
assert!(file_exists!(public, "authors/queen-elizabeth/atom.xml"));
|
||||||
|
assert!(file_contains!(public, "authors/queen-elizabeth/atom.xml", r#"<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">"#));
|
||||||
|
assert!(file_contains!(public, "authors/queen-elizabeth/atom.xml", r#"<title> - Queen Elizabeth</title>"#));
|
||||||
|
|
||||||
assert!(file_exists!(public, "tags/index.html"));
|
assert!(file_exists!(public, "tags/index.html"));
|
||||||
assert!(file_contains!(public, "tags/index.html", "hello"));
|
assert!(file_contains!(public, "tags/index.html", "hello"));
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ config.default_language }}">
|
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ lang }}">
|
||||||
<title>{{ config.title }}</title>
|
<title>{{ config.title }}
|
||||||
|
{%- if term %} - {{ term.name }}
|
||||||
|
{%- endif -%}
|
||||||
|
</title>
|
||||||
{%- if config.description %}
|
{%- if config.description %}
|
||||||
<subtitle>{{ config.description }}</subtitle>
|
<subtitle>{{ config.description }}</subtitle>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
@ -11,7 +14,7 @@
|
||||||
<id>{{ feed_url | safe }}</id>
|
<id>{{ feed_url | safe }}</id>
|
||||||
{%- for page in pages %}
|
{%- for page in pages %}
|
||||||
<entry
|
<entry
|
||||||
{%- if page.lang != config.default_language %} xml:lang="{{ page.lang }}"{% endif -%}
|
{%- if page.lang != lang %} xml:lang="{{ page.lang }}"{% endif -%}
|
||||||
>
|
>
|
||||||
<title>{{ page.title }}</title>
|
<title>{{ page.title }}</title>
|
||||||
<published>{{ page.date | date(format="%+") }}</published>
|
<published>{{ page.date | date(format="%+") }}</published>
|
||||||
|
|
|
@ -17,9 +17,18 @@ need to provide a template yourself.
|
||||||
|
|
||||||
**Only pages with a date will be available.**
|
**Only pages with a date will be available.**
|
||||||
|
|
||||||
The feed template gets three variables in addition to `config`:
|
The feed template gets five variables:
|
||||||
|
|
||||||
|
- `config`: the site config
|
||||||
- `feed_url`: the full url to that specific feed
|
- `feed_url`: the full url to that specific feed
|
||||||
- `last_updated`: the most recent `updated` or `date` field of any post
|
- `last_updated`: the most recent `updated` or `date` field of any post
|
||||||
- `pages`: see [page variables](@/documentation/templates/pages-sections.md#page-variables) for
|
- `pages`: see [page variables](@/documentation/templates/pages-sections.md#page-variables)
|
||||||
a detailed description of what this contains
|
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)
|
||||||
|
|
Loading…
Reference in a new issue