mirror of
https://github.com/zyllian/webdog.git
synced 2025-01-17 19:22:21 -08:00
make rss feeds optional for resources
This commit is contained in:
parent
95a0765b1e
commit
ddeb079d52
7 changed files with 101 additions and 65 deletions
|
@ -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
|
||||
|
|
|
@ -66,6 +66,9 @@ Arguments:
|
|||
<ID> The resource type's ID
|
||||
<NAME> The name of the resource type to create
|
||||
<PLURAL> The name of the resource type, but plural
|
||||
|
||||
Options:
|
||||
--no-rss Whether to skip enabling RSS for this resource or not
|
||||
```
|
||||
|
||||
## `webdog page new`
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
{% else %}
|
||||
<h1>blog Posts</h1>
|
||||
<p><a href="tags">view blog tags</a></p>
|
||||
{% if data.rss_enabled %}
|
||||
<p><a href="rss.xml">rss feed</a></p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<h1>Page {{data.page}}/{{data.page_max}}</h1>
|
||||
{% if data.previous %}
|
||||
<a href="./{{data.previous}}">previous page</a>
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
{% extends "base.tera" %}
|
||||
{% block content %}
|
||||
{% if tag %}
|
||||
<h1>!!RESOURCE_NAME_PLURAL!! tagged {{ tag }}</h1>
|
||||
{% if data.tag %}
|
||||
<h1>!!RESOURCE_NAME_PLURAL!! tagged {{ data.tag }}</h1>
|
||||
<p><a href="/!!RESOURCE_TYPE!!/">View all !!RESOURCE_NAME_PLURAL_LOWERCASE!!</a></p>
|
||||
{% else %}
|
||||
<h1>!!RESOURCE_NAME_PLURAL!!</h1>
|
||||
<p><a href="tags">view !!RESOURCE_NAME!! tags</a></p>
|
||||
{% if data.rss_enabled %}
|
||||
<p><a href="rss.xml">rss feed</a></p>
|
||||
{% endif %}
|
||||
<h1>Page {{ page }}/{{ page_max }}</h1>
|
||||
{% endif %}
|
||||
<h1>Page {{ data.page }}/{{ data.page_max }}</h1>
|
||||
{% if previous %}
|
||||
<a href="./{{previous}}">previous page</a>
|
||||
<a href="./{{data.previous}}">previous page</a>
|
||||
{% endif %}
|
||||
{% if next %}
|
||||
<a href="./{{next}}">next page</a>
|
||||
<a href="./{{data.next}}">next page</a>
|
||||
{% endif %}
|
||||
<div>
|
||||
{% for resource in resources %}
|
||||
{% for resource in data.resources %}
|
||||
<p><a href="/!!RESOURCE_TYPE!!/{{resource.id}}">{{ resource.title }}</a></p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
22
src/main.rs
22
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,
|
||||
|
|
106
src/resource.rs
106
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<usize>,
|
||||
|
@ -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<ResourceRSSBuilderConfig>,
|
||||
/// 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(())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue