Misc stuff
This commit is contained in:
parent
1e772a97e2
commit
9a13efbd35
@ -26,6 +26,7 @@
|
||||
{% endblock %}
|
||||
<meta property="og:url" content="https://{{ _domain }}{{ _permalink }}">
|
||||
<meta property="og:site_name" content="Shadowfacts">
|
||||
<meta name="fediverse:creator" content="@shadowfacts@social.shadowfacts.net">
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
|
||||
|
@ -6,16 +6,19 @@
|
||||
|
||||
{% block content -%}
|
||||
|
||||
<h1>{{ tag_name }} posts</h1>
|
||||
<h1>Posts tagged ‘{{ tag_name }}’</h1>
|
||||
|
||||
<ul>
|
||||
{% for entry in posts %}
|
||||
<li>
|
||||
<a href="{{ entry.permalink }}">
|
||||
{{ entry.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% for year in years %}
|
||||
<h2>{{ year }}</h2>
|
||||
<ul>
|
||||
{% for entry in posts_by_year[year] %}
|
||||
<li>
|
||||
<a href="{{ entry.permalink }}">
|
||||
{{ entry.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
|
||||
{%- endblock %}
|
||||
|
@ -69,7 +69,7 @@ impl Rule for Entries {
|
||||
}
|
||||
|
||||
#[derive(InputVisitable)]
|
||||
struct PostsByYear(Input<Vec<Entry>>);
|
||||
pub struct PostsByYear(pub Input<Vec<Entry>>);
|
||||
impl Rule for PostsByYear {
|
||||
type Output = PostsYearMap;
|
||||
fn evaluate(&mut self) -> Self::Output {
|
||||
@ -81,11 +81,11 @@ impl Rule for PostsByYear {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
struct PostsYearMap(HashMap<i32, Vec<Entry>>);
|
||||
#[derive(PartialEq, Clone)]
|
||||
pub struct PostsYearMap(pub HashMap<i32, Vec<Entry>>);
|
||||
|
||||
impl PostsYearMap {
|
||||
fn years(&self) -> Vec<i32> {
|
||||
pub fn years(&self) -> Vec<i32> {
|
||||
let mut years = self.0.keys().cloned().collect::<Vec<_>>();
|
||||
years.sort();
|
||||
years.reverse();
|
||||
@ -94,8 +94,8 @@ impl PostsYearMap {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Serialize)]
|
||||
struct Entry {
|
||||
permalink: String,
|
||||
title: String,
|
||||
year: i32,
|
||||
pub struct Entry {
|
||||
pub permalink: String,
|
||||
pub title: String,
|
||||
pub year: i32,
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ impl<'a> Fs for TrackingFs<'a> {
|
||||
struct ReadFile(#[skip_visit] PathBuf);
|
||||
impl Rule for ReadFile {
|
||||
type Output = String;
|
||||
|
||||
fn evaluate(&mut self) -> Self::Output {
|
||||
match std::fs::read(&self.0) {
|
||||
Ok(data) => BASE64_STANDARD.encode(data),
|
||||
@ -170,4 +171,8 @@ impl Rule for ReadFile {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn node_label(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0.display())
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ use compute_graph::{
|
||||
NodeId,
|
||||
builder::GraphBuilder,
|
||||
input::{DynamicInput, Input, InputVisitable},
|
||||
node::NodeValue,
|
||||
rule::{DynamicNodeFactory, DynamicRule, DynamicRuleContext, Rule},
|
||||
synchronicity::Asynchronous,
|
||||
};
|
||||
@ -23,25 +22,22 @@ pub fn make_graph(
|
||||
) -> Input<()> {
|
||||
let recents = builder.add_dynamic_rule(RecentPosts::new(posts));
|
||||
let with_rss_html = builder.add_dynamic_rule(ConvertRecentsToRSSContent::new(recents));
|
||||
|
||||
builder.add_rule(RenderRSSFeed(with_rss_html))
|
||||
}
|
||||
|
||||
#[derive(InputVisitable)]
|
||||
struct RecentPosts {
|
||||
posts: DynamicInput<ReadPostOutput>,
|
||||
factory: DynamicNodeFactory<NodeId, ReadPostOutput>,
|
||||
}
|
||||
impl RecentPosts {
|
||||
fn new(posts: DynamicInput<ReadPostOutput>) -> Self {
|
||||
Self {
|
||||
posts,
|
||||
factory: DynamicNodeFactory::new(),
|
||||
}
|
||||
Self { posts }
|
||||
}
|
||||
}
|
||||
impl DynamicRule for RecentPosts {
|
||||
type ChildOutput = ReadPostOutput;
|
||||
fn evaluate(&mut self, ctx: &mut impl DynamicRuleContext) -> Vec<Input<Self::ChildOutput>> {
|
||||
fn evaluate(&mut self, _ctx: &mut impl DynamicRuleContext) -> Vec<Input<Self::ChildOutput>> {
|
||||
let mut posts = vec![];
|
||||
for post_input in self.posts().inputs.iter() {
|
||||
if let Some(post) = post_input.value().as_ref() {
|
||||
@ -50,21 +46,11 @@ impl DynamicRule for RecentPosts {
|
||||
}
|
||||
posts.sort_by_key(|post_and_date| post_and_date.1);
|
||||
posts.reverse();
|
||||
for (post_input, _) in posts.into_iter().take(10) {
|
||||
self.factory.add_node(ctx, post_input.node_id(), |ctx| {
|
||||
ctx.add_rule(Identity(post_input))
|
||||
});
|
||||
}
|
||||
self.factory.all_nodes(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(InputVisitable)]
|
||||
struct Identity<T>(Input<T>);
|
||||
impl<T: Clone + NodeValue + 'static> Rule for Identity<T> {
|
||||
type Output = T;
|
||||
fn evaluate(&mut self) -> Self::Output {
|
||||
self.input_0().clone()
|
||||
posts
|
||||
.into_iter()
|
||||
.map(|(post_input, _)| post_input)
|
||||
.take(10)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,19 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use chrono::Datelike;
|
||||
use compute_graph::{
|
||||
builder::GraphBuilder,
|
||||
input::{DynamicInput, Input, InputVisitable},
|
||||
rule::{DynamicNodeFactory, DynamicRule, Rule},
|
||||
synchronicity::Asynchronous,
|
||||
};
|
||||
use serde::Serialize;
|
||||
use tera::Context;
|
||||
|
||||
use crate::generator::archive::PostsByYear;
|
||||
|
||||
use super::{
|
||||
FileWatcher,
|
||||
archive::{Entry, PostsYearMap},
|
||||
posts::{ReadPostOutput, metadata::Tag},
|
||||
templates::{AddTemplate, BuildTemplateContext, RenderTemplate, Templates},
|
||||
util::{MapDynamicToVoid, content_path},
|
||||
@ -39,13 +42,17 @@ pub fn make_graph(
|
||||
#[derive(InputVisitable)]
|
||||
struct MakePostsByTags {
|
||||
posts: DynamicInput<ReadPostOutput>,
|
||||
node_factory: DynamicNodeFactory<String, TagAndPosts>,
|
||||
posts_by_tag_factory: DynamicNodeFactory<String, Vec<Entry>>,
|
||||
posts_by_year_factory: DynamicNodeFactory<String, PostsYearMap>,
|
||||
tag_and_posts_factory: DynamicNodeFactory<String, TagAndPosts>,
|
||||
}
|
||||
impl MakePostsByTags {
|
||||
fn new(posts: DynamicInput<ReadPostOutput>) -> Self {
|
||||
Self {
|
||||
posts,
|
||||
node_factory: DynamicNodeFactory::new(),
|
||||
posts_by_tag_factory: DynamicNodeFactory::new(),
|
||||
posts_by_year_factory: DynamicNodeFactory::new(),
|
||||
tag_and_posts_factory: DynamicNodeFactory::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,14 +71,35 @@ impl DynamicRule for MakePostsByTags {
|
||||
}
|
||||
}
|
||||
for (slug, name) in all_tags {
|
||||
self.node_factory.add_node(ctx, slug.clone(), |ctx| {
|
||||
ctx.add_rule(PostsByTag {
|
||||
posts: self.posts.clone(),
|
||||
tag: Tag { slug, name },
|
||||
})
|
||||
});
|
||||
let tag = Tag {
|
||||
slug: slug.clone(),
|
||||
name,
|
||||
};
|
||||
|
||||
let posts_for_tag = self
|
||||
.posts_by_tag_factory
|
||||
.add_node(ctx, slug.clone(), |ctx| {
|
||||
ctx.add_rule(PostsByTag {
|
||||
posts: self.posts.clone(),
|
||||
tag: tag.clone(),
|
||||
})
|
||||
});
|
||||
let posts_by_year = self
|
||||
.posts_by_year_factory
|
||||
.add_node(ctx, slug.clone(), |ctx| {
|
||||
ctx.add_rule(PostsByYear(posts_for_tag))
|
||||
});
|
||||
self.tag_and_posts_factory
|
||||
.add_node(ctx, slug.clone(), |ctx| {
|
||||
ctx.add_rule(CreateTagAndPosts {
|
||||
posts: posts_by_year,
|
||||
tag,
|
||||
})
|
||||
});
|
||||
}
|
||||
self.node_factory.all_nodes(ctx)
|
||||
self.posts_by_tag_factory.finalize_nodes(ctx);
|
||||
self.posts_by_year_factory.finalize_nodes(ctx);
|
||||
self.tag_and_posts_factory.all_nodes(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,11 +110,10 @@ struct PostsByTag {
|
||||
tag: Tag,
|
||||
}
|
||||
impl Rule for PostsByTag {
|
||||
type Output = TagAndPosts;
|
||||
type Output = Vec<Entry>;
|
||||
|
||||
fn evaluate(&mut self) -> Self::Output {
|
||||
let entries = self
|
||||
.posts()
|
||||
self.posts()
|
||||
.inputs
|
||||
.iter()
|
||||
.flat_map(|post_input| {
|
||||
@ -101,16 +128,13 @@ impl Rule for PostsByTag {
|
||||
Some(Entry {
|
||||
permalink: post.permalink(),
|
||||
title: post.metadata.title.clone(),
|
||||
year: post.metadata.date.year(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
TagAndPosts {
|
||||
tag: self.tag.clone(),
|
||||
entries,
|
||||
}
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn node_label(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
@ -118,16 +142,26 @@ impl Rule for PostsByTag {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(InputVisitable)]
|
||||
struct CreateTagAndPosts {
|
||||
posts: Input<PostsYearMap>,
|
||||
#[skip_visit]
|
||||
tag: Tag,
|
||||
}
|
||||
impl Rule for CreateTagAndPosts {
|
||||
type Output = TagAndPosts;
|
||||
fn evaluate(&mut self) -> Self::Output {
|
||||
TagAndPosts {
|
||||
tag: self.tag.clone(),
|
||||
posts: self.posts().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
struct TagAndPosts {
|
||||
tag: Tag,
|
||||
entries: Vec<Entry>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Serialize)]
|
||||
struct Entry {
|
||||
permalink: String,
|
||||
title: String,
|
||||
posts: PostsYearMap,
|
||||
}
|
||||
|
||||
#[derive(InputVisitable)]
|
||||
@ -165,7 +199,8 @@ impl DynamicRule for MakeWriteTagPages {
|
||||
tag_input.clone(),
|
||||
|tag_and_posts, ctx| {
|
||||
ctx.insert("tag_name", &tag_and_posts.tag.name);
|
||||
ctx.insert("posts", &tag_and_posts.entries);
|
||||
ctx.insert("years", &tag_and_posts.posts.years());
|
||||
ctx.insert("posts_by_year", &tag_and_posts.posts.0);
|
||||
},
|
||||
))
|
||||
});
|
||||
|
@ -112,6 +112,7 @@ impl<T, F: Fn(&T, &mut Context) -> ()> BuildTemplateContext<T, F> {
|
||||
}
|
||||
impl<T: 'static, F: Fn(&T, &mut Context) -> () + 'static> Rule for BuildTemplateContext<T, F> {
|
||||
type Output = Context;
|
||||
|
||||
fn evaluate(&mut self) -> Self::Output {
|
||||
let mut context = Context::new();
|
||||
(self.func)(&*self.input.value(), &mut context);
|
||||
@ -126,6 +127,14 @@ impl<T: 'static, F: Fn(&T, &mut Context) -> () + 'static> Rule for BuildTemplate
|
||||
context.insert("_generated_at", &Local::now());
|
||||
context
|
||||
}
|
||||
|
||||
fn node_label(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self.permalink {
|
||||
TemplatePermalink::Constant(s) => write!(f, "{s}"),
|
||||
TemplatePermalink::ConstantOwned(ref s) => write!(f, "{s}"),
|
||||
TemplatePermalink::Dynamic(ref inp) => write!(f, "{}", *inp.value()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(InputVisitable)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user