Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 2378 lang level feed config #2400

Open
wants to merge 7 commits into
base: next
Choose a base branch
from
37 changes: 9 additions & 28 deletions components/config/src/config/languages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::config::search;
use crate::config::taxonomies;

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct LanguageOptions {
/// Title of the site. Defaults to None
Expand All @@ -17,8 +17,9 @@ pub struct LanguageOptions {
/// Whether to generate a feed for that language, defaults to `false`
pub generate_feed: bool,
/// 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,
/// Defaults to None, with "atom.xml" and "rss.xml" having templates provided out of the box.
/// If None, site config feed filename is used.
pub feed_filename: Option<String>,
pub taxonomies: Vec<taxonomies::TaxonomyConfig>,
/// Whether to generate search index for that language, defaults to `false`
pub build_search_index: bool,
Expand Down Expand Up @@ -65,12 +66,7 @@ impl LanguageOptions {
}
merge_field!(self.title, other.title, "title");
merge_field!(self.description, other.description, "description");
merge_field!(
self.feed_filename == "atom.xml",
self.feed_filename,
other.feed_filename,
"feed_filename"
);
merge_field!(self.feed_filename, other.feed_filename, "feed_filename");
merge_field!(self.taxonomies.is_empty(), self.taxonomies, other.taxonomies, "taxonomies");
merge_field!(
self.translations.is_empty(),
Expand All @@ -96,21 +92,6 @@ impl LanguageOptions {
}
}

impl Default for LanguageOptions {
fn default() -> LanguageOptions {
LanguageOptions {
title: None,
description: None,
generate_feed: false,
feed_filename: "atom.xml".to_string(),
taxonomies: vec![],
build_search_index: false,
search: search::Search::default(),
translations: HashMap::new(),
}
}
}

/// We want to ensure the language codes are valid ones
pub fn validate_code(code: &str) -> Result<()> {
if LanguageIdentifier::from_bytes(code.as_bytes()).is_err() {
Expand All @@ -130,7 +111,7 @@ mod tests {
title: Some("Site's title".to_string()),
description: None,
generate_feed: true,
feed_filename: "atom.xml".to_string(),
feed_filename: None,
taxonomies: vec![],
build_search_index: true,
search: search::Search::default(),
Expand All @@ -141,7 +122,7 @@ mod tests {
title: None,
description: Some("Site's description".to_string()),
generate_feed: false,
feed_filename: "rss.xml".to_string(),
feed_filename: Some("rss.xml".to_string()),
taxonomies: vec![],
build_search_index: true,
search: search::Search::default(),
Expand All @@ -157,7 +138,7 @@ mod tests {
title: Some("Site's title".to_string()),
description: Some("Duplicate site description".to_string()),
generate_feed: true,
feed_filename: "".to_string(),
feed_filename: Some("".to_string()),
taxonomies: vec![],
build_search_index: true,
search: search::Search::default(),
Expand All @@ -168,7 +149,7 @@ mod tests {
title: None,
description: Some("Site's description".to_string()),
generate_feed: false,
feed_filename: "Some feed_filename".to_string(),
feed_filename: Some("Some feed_filename".to_string()),
taxonomies: vec![],
build_search_index: true,
search: search::Search::default(),
Expand Down
21 changes: 12 additions & 9 deletions components/config/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use utils::slugs::slugify_paths;

// We want a default base url for tests
static DEFAULT_BASE_URL: &str = "http://a-website.com";
pub static DEFAULT_FEED_FILENAME: &str = "atom.xml";

#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
Expand Down Expand Up @@ -65,8 +66,9 @@ pub struct Config {
/// The number of articles to include in the feed. Defaults to including all items.
pub feed_limit: Option<usize>,
/// 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,
/// Defaults to None, with "atom.xml" and "rss.xml" having templates provided out of the box.
/// If None, "atom.xml" is used for feed. Defined by DEFAULT_FEED_FILENAME
pub feed_filename: Option<String>,
/// If set, files from static/ will be hardlinked instead of copied to the output dir.
pub hard_link_static: bool,
pub taxonomies: Vec<taxonomies::TaxonomyConfig>,
Expand Down Expand Up @@ -120,7 +122,7 @@ pub struct SerializedConfig<'a> {
languages: HashMap<&'a String, &'a languages::LanguageOptions>,
default_language: &'a str,
generate_feed: bool,
feed_filename: &'a str,
feed_filename: &'a Option<String>,
taxonomies: &'a [taxonomies::TaxonomyConfig],
author: &'a Option<String>,
build_search_index: bool,
Expand Down Expand Up @@ -202,12 +204,13 @@ 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 is_feed_file = self
.feed_filename
.as_ref()
.map(|ff| path.ends_with(ff))
.unwrap_or_else(|| path.ends_with(DEFAULT_FEED_FILENAME));
let trailing_bit =
if path.ends_with('/') || path.ends_with(&self.feed_filename) || path.is_empty() {
""
} else {
"/"
};
if path.ends_with('/') || is_feed_file || path.is_empty() { "" } else { "/" };

// Index section with a base url that has a trailing slash
if self.base_url.ends_with('/') && path == "/" {
Expand Down Expand Up @@ -390,7 +393,7 @@ impl Default for Config {
languages: HashMap::new(),
generate_feed: false,
feed_limit: None,
feed_filename: "atom.xml".to_string(),
feed_filename: None,
hard_link_static: false,
taxonomies: Vec::new(),
author: None,
Expand Down
2 changes: 1 addition & 1 deletion components/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub use crate::config::{
search::{IndexFormat, Search},
slugify::Slugify,
taxonomies::TaxonomyConfig,
Config,
Config, DEFAULT_FEED_FILENAME,
};
use errors::Result;

Expand Down
2 changes: 1 addition & 1 deletion components/site/src/feed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn render_feed(
context.insert("config", &site.config.serialize(lang));
context.insert("lang", lang);

let feed_filename = &site.config.feed_filename;
let feed_filename = &site.language_feed_filename(lang);
let feed_url = if let Some(base) = base_path {
site.config.make_permalink(&base.join(feed_filename).to_string_lossy().replace('\\', "/"))
} else {
Expand Down
26 changes: 22 additions & 4 deletions components/site/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,15 @@ impl Site {
start = log_time(start, "Rendered sitemap");

let library = self.library.read().unwrap();
if self.config.generate_feed {

let generate_feed_for_default = self
.config
.languages
.get(&self.config.default_language)
.map(|lang_opt| lang_opt.generate_feed)
.or(Some(self.config.generate_feed))
.unwrap_or(false);
if generate_feed_for_default {
let is_multilingual = self.config.is_multilingual();
let pages: Vec<_> = if is_multilingual {
library.pages.values().filter(|p| p.lang == self.config.default_language).collect()
Expand All @@ -768,6 +776,7 @@ impl Site {
self.render_feed(pages, Some(&PathBuf::from(code)), code, |c| c)?;
start = log_time(start, "Generated feed in other language");
}

self.render_themes_css()?;
start = log_time(start, "Rendered themes css");
self.render_404()?;
Expand Down Expand Up @@ -1022,6 +1031,15 @@ impl Site {
Ok(())
}

pub fn language_feed_filename(&self, lang: &str) -> &str {
self.config
.languages
.get(lang)
.and_then(|l| l.feed_filename.as_ref().or(self.config.feed_filename.as_ref()))
.or(self.config.feed_filename.as_ref())
.map_or_else(|| config::DEFAULT_FEED_FILENAME, |ff| ff.as_str())
}

/// 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.
Expand All @@ -1039,7 +1057,7 @@ impl Site {
Some(v) => v,
None => return Ok(()),
};
let feed_filename = &self.config.feed_filename;
let feed_filename = self.language_feed_filename(lang);

if let Some(base) = base_path {
let mut components = Vec::new();
Expand All @@ -1048,12 +1066,12 @@ impl Site {
}
self.write_content(
&components.iter().map(|x| x.as_ref()).collect::<Vec<_>>(),
feed_filename,
&feed_filename,
feed,
false,
)?;
} else {
self.write_content(&[], feed_filename, feed, false)?;
self.write_content(&[], &feed_filename, feed, false)?;
}
Ok(())
}
Expand Down
10 changes: 8 additions & 2 deletions components/templates/src/global_fns/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,10 @@ title = "A title"
let static_fn =
GetUrl::new(dir.path().to_path_buf(), config.clone(), HashMap::new(), PathBuf::new());
let mut args = HashMap::new();
args.insert("path".to_string(), to_value(config.feed_filename).unwrap());
args.insert(
"path".to_string(),
to_value(config.feed_filename.unwrap_or(String::from("atom.xml"))).unwrap(),
);
args.insert("lang".to_string(), to_value("fr").unwrap());
assert_eq!(static_fn.call(&args).unwrap(), "https://remplace-par-ton-url.fr/atom.xml");
}
Expand All @@ -479,7 +482,10 @@ title = "A title"
let static_fn =
GetUrl::new(dir.path().to_path_buf(), config.clone(), HashMap::new(), PathBuf::new());
let mut args = HashMap::new();
args.insert("path".to_string(), to_value(config.feed_filename).unwrap());
args.insert(
"path".to_string(),
to_value(config.feed_filename.unwrap_or(String::from("atom.xml"))).unwrap(),
);
args.insert("lang".to_string(), to_value("en").unwrap());
assert_eq!(static_fn.call(&args).unwrap(), "https://remplace-par-ton-url.fr/en/atom.xml");
}
Expand Down