From ddeb079d5290b95df61ddee0d5198a0578cb62a3 Mon Sep 17 00:00:00 2001 From: zyl Date: Wed, 13 Nov 2024 13:11:37 -0800 Subject: [PATCH] make rss feeds optional for resources --- site/config.yaml | 7 +- site/pages/docs/commands.md | 3 + site/pages/docs/resources.md | 12 ++- site/templates/blog/list.tera | 2 + src/embedded/resource-template/list.tera | 14 +-- src/main.rs | 22 +++-- src/resource.rs | 106 +++++++++++++---------- 7 files changed, 101 insertions(+), 65 deletions(-) diff --git a/site/config.yaml b/site/config.yaml index ba51e0d..d71e025 100644 --- a/site/config.yaml +++ b/site/config.yaml @@ -14,9 +14,10 @@ resources: resource_template: blog/blog.tera resource_list_template: blog/list.tera tag_list_template: basic-link-list.tera - rss_template: blog/rss.tera - rss_title: webdog blog - rss_description: feed of recent webdog blog posts. + rss: + template: blog/rss.tera + title: webdog blog + description: feed of recent webdog blog posts. list_title: blog tag_list_title: blog tags resource_name_plural: blog posts diff --git a/site/pages/docs/commands.md b/site/pages/docs/commands.md index f0d0d8f..59f7aaf 100644 --- a/site/pages/docs/commands.md +++ b/site/pages/docs/commands.md @@ -66,6 +66,9 @@ Arguments: The resource type's ID The name of the resource type to create The name of the resource type, but plural + +Options: + --no-rss Whether to skip enabling RSS for this resource or not ``` ## `webdog page new` diff --git a/site/pages/docs/resources.md b/site/pages/docs/resources.md index 2db0612..e89d551 100644 --- a/site/pages/docs/resources.md +++ b/site/pages/docs/resources.md @@ -73,17 +73,23 @@ the link to actually use for the link. the link's title. -### `rss_template` +### `rss` + +the resource type's rss info. if not present, no rss feed will be built. + +consists of the following properties: + +#### `template` the template used to render the resource type's rss feed's html content. this template is provided a single resource's properties as its properties. -### `rss_title` +#### `title` the title for the resource type's rss feed. -### `rss_description` +#### `description` the description for the resource type's rss feed. diff --git a/site/templates/blog/list.tera b/site/templates/blog/list.tera index 3a21ef4..a7fabe6 100644 --- a/site/templates/blog/list.tera +++ b/site/templates/blog/list.tera @@ -6,8 +6,10 @@ {% else %}

blog Posts

view blog tags

+{% if data.rss_enabled %}

rss feed

{% endif %} +{% endif %}

Page {{data.page}}/{{data.page_max}}

{% if data.previous %} previous page diff --git a/src/embedded/resource-template/list.tera b/src/embedded/resource-template/list.tera index 422072e..a14c15a 100644 --- a/src/embedded/resource-template/list.tera +++ b/src/embedded/resource-template/list.tera @@ -1,22 +1,24 @@ {% extends "base.tera" %} {% block content %} -{% if tag %} -

!!RESOURCE_NAME_PLURAL!! tagged {{ tag }}

+{% if data.tag %} +

!!RESOURCE_NAME_PLURAL!! tagged {{ data.tag }}

View all !!RESOURCE_NAME_PLURAL_LOWERCASE!!

{% else %}

!!RESOURCE_NAME_PLURAL!!

view !!RESOURCE_NAME!! tags

+{% if data.rss_enabled %}

rss feed

{% endif %} -

Page {{ page }}/{{ page_max }}

+{% endif %} +

Page {{ data.page }}/{{ data.page_max }}

{% if previous %} -previous page +previous page {% endif %} {% if next %} -next page +next page {% endif %}
- {% for resource in resources %} + {% for resource in data.resources %}

{{ resource.title }}

{% endfor %}
diff --git a/src/main.rs b/src/main.rs index 27be24b..b96fad5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use time::{format_description::well_known::Rfc3339, OffsetDateTime}; use url::Url; use webdog::{ frontmatter::FrontMatter, - resource::{ResourceBuilderConfig, ResourceMetadata}, + resource::{ResourceBuilderConfig, ResourceMetadata, ResourceRSSBuilderConfig}, PageMetadata, Site, SiteConfig, }; @@ -93,6 +93,9 @@ enum ResourceCommands { name: String, /// The name of the resource type, but plural. plural: String, + /// Whether to skip enabling RSS for this resource or not. + #[arg(long, default_value = "false")] + no_rss: bool, }, } @@ -163,7 +166,12 @@ fn main() -> eyre::Result<()> { Ok(()) } Commands::Resource { command } => match command { - ResourceCommands::Create { id, name, plural } => { + ResourceCommands::Create { + id, + name, + plural, + no_rss, + } => { let config_path = cli.site.join(SiteConfig::FILENAME); let mut config = SiteConfig::read(&cli.site)?; if config.resources.contains_key(&id) { @@ -196,6 +204,12 @@ fn main() -> eyre::Result<()> { } } + let rss = (!no_rss).then(|| ResourceRSSBuilderConfig { + template: format!("{id}/rss.tera"), + title: id.clone(), + description: Default::default(), + }); + let resource_config = ResourceBuilderConfig { source_path: id.clone(), output_path_resources: id.clone(), @@ -203,9 +217,7 @@ fn main() -> eyre::Result<()> { resource_template: format!("{id}/resource.tera"), resource_list_template: format!("{id}/list.tera"), tag_list_template: "basic-link-list.tera".to_string(), - rss_template: format!("{id}/rss.tera"), - rss_title: id.clone(), - rss_description: Default::default(), + rss, list_title: name.clone(), tag_list_title: format!("{name} tags"), resource_name_plural: plural, diff --git a/src/resource.rs b/src/resource.rs index 19685d7..e72d251 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -113,6 +113,7 @@ impl EmbedMetadata { struct ResourceListTemplateData<'r> { resources: Vec<&'r ResourceTemplateData<'r>>, tag: Option<&'r str>, + rss_enabled: bool, page: usize, page_max: usize, previous: Option, @@ -134,12 +135,8 @@ pub struct ResourceBuilderConfig { pub resource_list_template: String, /// The template used to render the resource's tag pages. pub tag_list_template: String, - /// Template used when rendering the RSS feed. - pub rss_template: String, - /// The RSS feed's title. - pub rss_title: String, - /// The description for the RSS feed. - pub rss_description: String, + /// The resource type's RSS info, if enabled. + pub rss: Option, /// Title for the main list of resources. pub list_title: String, /// Title for the page containing a list of tags. @@ -150,6 +147,16 @@ pub struct ResourceBuilderConfig { pub resources_per_page: usize, } +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct ResourceRSSBuilderConfig { + /// Template used when rendering the RSS feed. + pub template: String, + /// The RSS feed's title. + pub title: String, + /// The description for the RSS feed. + pub description: String, +} + /// Helper to genericize resource building. #[derive(Debug, Default)] pub struct ResourceBuilder { @@ -332,6 +339,7 @@ impl ResourceBuilder { ResourceListTemplateData { resources: iter.copied().collect(), tag, + rss_enabled: config.rss.is_some(), page: page + 1, page_max, previous, @@ -409,49 +417,51 @@ impl ResourceBuilder { } // Build RSS feed - let mut items = Vec::with_capacity(data.len()); - for resource in data { - items.push( - ItemBuilder::default() - .title(Some(resource.resource.data().title.to_owned())) - .link(Some( - builder - .site - .config - .base_url - .join(&format!( - "{}/{}", - self.config.output_path_resources, resource.id - ))? - .to_string(), - )) - .description(resource.resource.data().desc.clone()) - .pub_date(Some(resource.timestamp.format(&Rfc2822)?)) - .content(Some(builder.tera.render( - &self.config.rss_template, - &tera::Context::from_serialize(resource)?, - )?)) - .build(), - ) - } + if let Some(rss) = &self.config.rss { + let mut items = Vec::with_capacity(data.len()); + for resource in data { + items.push( + ItemBuilder::default() + .title(Some(resource.resource.data().title.to_owned())) + .link(Some( + builder + .site + .config + .base_url + .join(&format!( + "{}/{}", + self.config.output_path_resources, resource.id + ))? + .to_string(), + )) + .description(resource.resource.data().desc.clone()) + .pub_date(Some(resource.timestamp.format(&Rfc2822)?)) + .content(Some(builder.tera.render( + &rss.template, + &tera::Context::from_serialize(resource)?, + )?)) + .build(), + ) + } - let channel = ChannelBuilder::default() - .title(self.config.rss_title.clone()) - .link( - builder - .site - .config - .base_url - .join(&format!("{}/", self.config.output_path_lists)) - .expect("Should never fail"), - ) - .description(self.config.rss_description.clone()) - .last_build_date(Some(OffsetDateTime::now_utc().format(&Rfc2822)?)) - .items(items) - .build(); - channel.validate().wrap_err("Failed to validate RSS feed")?; - let out = channel.to_string(); - std::fs::write(out_long.join("rss.xml"), out)?; + let channel = ChannelBuilder::default() + .title(rss.title.clone()) + .link( + builder + .site + .config + .base_url + .join(&format!("{}/", self.config.output_path_lists)) + .expect("Should never fail"), + ) + .description(rss.description.clone()) + .last_build_date(Some(OffsetDateTime::now_utc().format(&Rfc2822)?)) + .items(items) + .build(); + channel.validate().wrap_err("Failed to validate RSS feed")?; + let out = channel.to_string(); + std::fs::write(out_long.join("rss.xml"), out)?; + } Ok(()) }