Article metadata
This commit is contained in:
parent
3adf6031a4
commit
f0ef67f9a0
@ -120,6 +120,15 @@ header {
|
|||||||
.article-title {
|
.article-title {
|
||||||
// balance the number of words per line
|
// balance the number of words per line
|
||||||
text-wrap: balance;
|
text-wrap: balance;
|
||||||
|
|
||||||
|
&:has(+ .article-meta) {
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-meta {
|
||||||
|
margin-top: 0;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-content {
|
.article-content {
|
||||||
|
@ -38,6 +38,19 @@
|
|||||||
{{ metadata.title }}
|
{{ metadata.title }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h1>
|
</h1>
|
||||||
|
<p class="article-meta">
|
||||||
|
Published on
|
||||||
|
<time itemprop="datePublished" datetime="{{ metadata.date | iso_datetime }}">
|
||||||
|
{{ metadata.date | pretty_date }},
|
||||||
|
</time>
|
||||||
|
in
|
||||||
|
{% for tag in metadata.tags %}
|
||||||
|
<span itemprop="articleSection">
|
||||||
|
<a href="/{{ tag.slug }}/">{{ tag.name }}</a>{% if loop.last %}.{% else %},{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{{ word_count | reading_time }} minute read.
|
||||||
|
</p>
|
||||||
<div class="article-content" itemprop="articleBody">
|
<div class="article-content" itemprop="articleBody">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -284,6 +284,12 @@ impl DynamicRule for MakeWritePosts {
|
|||||||
|post_opt, ctx| {
|
|post_opt, ctx| {
|
||||||
let post = post_opt.as_ref().unwrap();
|
let post = post_opt.as_ref().unwrap();
|
||||||
ctx.insert("metadata", &post.metadata);
|
ctx.insert("metadata", &post.metadata);
|
||||||
|
ctx.insert(
|
||||||
|
"word_count",
|
||||||
|
&post
|
||||||
|
.word_count
|
||||||
|
.expect("post should have word count when rendering"),
|
||||||
|
);
|
||||||
ctx.insert("content", post.content.html());
|
ctx.insert("content", post.content.html());
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
@ -24,8 +24,10 @@ pub fn make_graph(
|
|||||||
watcher: &mut FileWatcher,
|
watcher: &mut FileWatcher,
|
||||||
) -> Input<Templates> {
|
) -> Input<Templates> {
|
||||||
let mut empty_templates = Templates::default();
|
let mut empty_templates = Templates::default();
|
||||||
|
empty_templates.register_filter("iso_datetime", filters::iso_datetime);
|
||||||
empty_templates.register_filter("pretty_date", filters::pretty_date);
|
empty_templates.register_filter("pretty_date", filters::pretty_date);
|
||||||
empty_templates.register_filter("pretty_datetime", filters::pretty_datetime);
|
empty_templates.register_filter("pretty_datetime", filters::pretty_datetime);
|
||||||
|
empty_templates.register_filter("reading_time", filters::reading_time);
|
||||||
let empty_templates = builder.add_value(empty_templates);
|
let empty_templates = builder.add_value(empty_templates);
|
||||||
|
|
||||||
let default_path = content_path("layout/default.html");
|
let default_path = content_path("layout/default.html");
|
||||||
@ -212,7 +214,7 @@ pub mod filters {
|
|||||||
use chrono::{DateTime, Datelike, Local};
|
use chrono::{DateTime, Datelike, Local};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tera::{Result, Value};
|
use tera::{Number, Result, Value};
|
||||||
|
|
||||||
// pub fn iso_date(date: &NaiveDate) -> String {
|
// pub fn iso_date(date: &NaiveDate) -> String {
|
||||||
// Utc::from_utc_datetime(&Utc, &date.and_hms_opt(12, 0, 0).unwrap())
|
// Utc::from_utc_datetime(&Utc, &date.and_hms_opt(12, 0, 0).unwrap())
|
||||||
@ -228,6 +230,11 @@ pub mod filters {
|
|||||||
// datetime.format("%+:0").to_string()
|
// datetime.format("%+:0").to_string()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
pub fn iso_datetime(value: &Value, _args: &HashMap<String, Value>) -> Result<Value> {
|
||||||
|
let date = DateTime::<Local>::deserialize(value)?;
|
||||||
|
Ok(Value::String(date.format("%+:0").to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
const MONTHS: &[&str; 12] = &[
|
const MONTHS: &[&str; 12] = &[
|
||||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
|
||||||
];
|
];
|
||||||
@ -260,8 +267,10 @@ pub mod filters {
|
|||||||
Ok(Value::String(s))
|
Ok(Value::String(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn reading_time(words: &u32) -> u32 {
|
pub fn reading_time(value: &Value, _args: &HashMap<String, Value>) -> Result<Value> {
|
||||||
// let wpm = 225.0;
|
let words = u32::deserialize(value)?;
|
||||||
// (*words as f32 / wpm).max(1.0) as u32
|
let wpm = 225.0;
|
||||||
// }
|
let minutes = (words as f64 / wpm).max(1.0).round();
|
||||||
|
Ok(Value::Number(Number::from_f64(minutes).unwrap()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user