From 84932c0d1e88a974ae4e05ac245f881c5ab65520 Mon Sep 17 00:00:00 2001 From: slonkazoid Date: Thu, 13 Jun 2024 21:52:18 +0300 Subject: [PATCH] add custom date formatting and client side date formatting --- README.md | 12 +++++++++--- src/app.rs | 10 +++++++++- src/config.rs | 18 ++++++++++++++---- src/filters.rs | 24 +++++++++++++++++++++--- src/post/cache.rs | 5 ++--- static/main.js | 4 ++++ static/style.css | 29 +++++++++++++++++++++++++++++ templates/index.html | 3 +++ templates/macros.askama | 22 +++++++++++++++++----- templates/post.html | 33 ++++++++++++++++----------------- 10 files changed, 124 insertions(+), 36 deletions(-) create mode 100644 static/main.js diff --git a/README.md b/README.md index afa78ac..dd87090 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ blazingly fast markdown blog software written in rust memory safe - [ ] ^ replace HashMap with HashCache once i implement [this](https://github.com/wvwwvwwv/scalable-concurrent-containers/issues/139) - [x] (de)compress cache with zstd on startup/shutdown - [ ] make date parsing less strict -- [ ] make date formatting better +- [x] make date formatting better - [ ] date formatting respects user timezone - [x] clean up imports and require less features - [ ] improve home page @@ -36,10 +36,16 @@ blazingly fast markdown blog software written in rust memory safe the default configuration with comments looks like this ```toml -title = "bingus-blog" # title of the website -description = "blazingly fast markdown blog software written in rust memory safe" # description of the website +title = "bingus-blog" # title of the blog +# description of the blog +description = "blazingly fast markdown blog software written in rust memory safe" markdown_access = true # allow users to see the raw markdown of a post # endpoint: /posts/.md +date_format = "RFC3339" # format string used to format dates in the backend + # it's highly recommended to leave this as default, + # so the date can be formatted by the browser. + # format: https://docs.rs/chrono/latest/chrono/format/strftime/index.html#specifiers +js_enable = true # enable javascript (required for above) [rss] enable = false # serve an rss field under /feed.xml diff --git a/src/app.rs b/src/app.rs index 72b8322..1a8b0ca 100644 --- a/src/app.rs +++ b/src/app.rs @@ -14,7 +14,7 @@ use tower_http::services::ServeDir; use tower_http::trace::TraceLayer; use tracing::{info, info_span, Span}; -use crate::config::Config; +use crate::config::{Config, DateFormat}; use crate::error::{AppError, AppResult}; use crate::filters; use crate::post::{MarkdownPosts, PostManager, PostMetadata, RenderStats, ReturnedPost}; @@ -31,6 +31,8 @@ struct IndexTemplate { title: String, description: String, posts: Vec, + df: DateFormat, + js: bool, } #[derive(Template)] @@ -40,6 +42,8 @@ struct PostTemplate { rendered: String, rendered_in: RenderStats, markdown_access: bool, + df: DateFormat, + js: bool, } #[derive(Deserialize)] @@ -61,6 +65,8 @@ async fn index( title: config.title.clone(), description: config.description.clone(), posts, + df: config.date_format.clone(), + js: config.js_enable, }) } @@ -145,6 +151,8 @@ async fn post( rendered, rendered_in, markdown_access: config.markdown_access, + df: config.date_format.clone(), + js: config.js_enable, }; Ok(page.into_response()) diff --git a/src/config.rs b/src/config.rs index 23df5bf..f4dca81 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ use std::env; -use std::net::{IpAddr, Ipv4Addr}; +use std::net::{IpAddr, Ipv6Addr}; use std::path::PathBuf; use color_eyre::eyre::{bail, Context, Result}; @@ -59,13 +59,22 @@ pub struct RssConfig { pub link: Url, } +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub enum DateFormat { + #[default] + RFC3339, + #[serde(untagged)] + Strftime(String), +} + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(default)] pub struct Config { pub title: String, pub description: String, pub markdown_access: bool, - pub num_posts: usize, + pub date_format: DateFormat, + pub js_enable: bool, pub rss: RssConfig, pub dirs: DirsConfig, pub http: HttpConfig, @@ -79,7 +88,8 @@ impl Default for Config { title: "bingus-blog".into(), description: "blazingly fast markdown blog software written in rust memory safe".into(), markdown_access: true, - num_posts: 5, + date_format: Default::default(), + js_enable: true, // i have a love-hate relationship with serde // it was engimatic at first, but then i started actually using it // writing my own serialize and deserialize implementations.. spending @@ -111,7 +121,7 @@ impl Default for DirsConfig { impl Default for HttpConfig { fn default() -> Self { Self { - host: IpAddr::V4(Ipv4Addr::UNSPECIFIED), + host: IpAddr::V6(Ipv6Addr::UNSPECIFIED), port: 3000, } } diff --git a/src/filters.rs b/src/filters.rs index 35929dc..24d0a10 100644 --- a/src/filters.rs +++ b/src/filters.rs @@ -1,11 +1,29 @@ -use std::{collections::HashMap, time::Duration}; +use std::collections::HashMap; +use std::fmt::Display; +use std::time::Duration; use chrono::{DateTime, TimeZone}; +use crate::config::DateFormat; use crate::post::PostMetadata; -pub fn date(date: &DateTime) -> Result { - Ok(date.to_rfc3339_opts(chrono::SecondsFormat::Secs, true)) +fn format_date(date: &DateTime, date_format: &DateFormat) -> String +where + T: TimeZone, + T::Offset: Display, +{ + match date_format { + DateFormat::RFC3339 => date.to_rfc3339_opts(chrono::SecondsFormat::Secs, true), + DateFormat::Strftime(ref format_string) => date.format(format_string).to_string(), + } +} + +pub fn date(date: &DateTime, date_format: &DateFormat) -> Result +where + T: TimeZone, + T::Offset: Display, +{ + Ok(format_date(date, date_format)) } pub fn duration(duration: &&Duration) -> Result { diff --git a/src/post/cache.rs b/src/post/cache.rs index 45a74f1..cd3e837 100644 --- a/src/post/cache.rs +++ b/src/post/cache.rs @@ -1,15 +1,14 @@ use std::hash::{DefaultHasher, Hash, Hasher}; use std::io::Read; +use crate::config::{Config, RenderConfig}; +use crate::post::PostMetadata; use color_eyre::eyre::{self, Context}; use scc::HashMap; use serde::{Deserialize, Serialize}; use tokio::io::AsyncReadExt; use tracing::{debug, instrument}; -use crate::config::{Config, RenderConfig}; -use crate::post::PostMetadata; - /// do not persist cache if this version number changed pub const CACHE_VERSION: u16 = 2; diff --git a/static/main.js b/static/main.js new file mode 100644 index 0000000..ad261ed --- /dev/null +++ b/static/main.js @@ -0,0 +1,4 @@ +for (let el of document.querySelectorAll(".date-rfc3339")) { + let date = new Date(Date.parse(el.textContent)); + el.textContent = date.toLocaleString(); +} diff --git a/static/style.css b/static/style.css index 21633a7..ac679b2 100644 --- a/static/style.css +++ b/static/style.css @@ -84,6 +84,35 @@ div.post { margin-bottom: 1em; } +.table { + display: grid; + /*grid-template-columns: auto auto auto; + grid-template-rows: auto auto;*/ + width: max-content; +} + +.table > :not(.value)::after { + content: ":"; +} + +.table > .value { + margin-left: 1em; + text-align: end; + grid-column: 2; +} + +.table > .created { + grid-row: 1; +} + +.table > .modified { + grid-row: 2; +} + +.table > .tags { + grid-row: 3; +} + /* BEGIN cool effect everyone liked */ body { diff --git a/templates/index.html b/templates/index.html index 591c008..bdf4cdc 100644 --- a/templates/index.html +++ b/templates/index.html @@ -9,6 +9,9 @@ {{ title }} + {% if js %} + + {% endif %}
diff --git a/templates/macros.askama b/templates/macros.askama index 17be7a6..bd21a25 100644 --- a/templates/macros.askama +++ b/templates/macros.askama @@ -1,19 +1,31 @@ +{% macro span_date(value) %} +{{ value|date(df) }} +{% endmacro %} {% macro table(post) %} +
{% match post.created_at %} {% when Some(created_at) %} - written:       {{ created_at|date }}
+
written
+
{% call span_date(created_at) %}
{% when None %} {% endmatch %} {% match post.modified_at %} {% when Some(modified_at) %} - last modified: {{ modified_at|date }}
+
last modified
+
{% call span_date(modified_at) %}
{% when None %} {% endmatch %} - {% if !post.tags.is_empty() %} - tags:          +
tags
+
{% for tag in post.tags %} {{ tag }} - {% endfor %}
+ {% endfor %} +
{% endif %} +
{% endmacro %} diff --git a/templates/post.html b/templates/post.html index a4ddf62..ba78574 100644 --- a/templates/post.html +++ b/templates/post.html @@ -2,20 +2,21 @@ - - - - - - - {% match meta.icon %} {% when Some with (url) %} - - - {% when None %} {% endmatch %} - {{ meta.title }} - - - + + + + + + {% match meta.icon %} {% when Some with (url) %} + + + {% when None %} {% endmatch %} + {{ meta.title }} + + + {% if js %} + + {% endif %}
@@ -24,11 +25,9 @@

{{ meta.description }}

-
+
-
{% call macros::table(meta) %} -
link
back to home