From 00b721caab4b692c682cc9161e9fa290163a1270 Mon Sep 17 00:00:00 2001 From: slonkazoid Date: Thu, 1 Aug 2024 00:25:42 +0300 Subject: [PATCH] implement sorting --- README.md | 25 +++++++++++++------------ src/app.rs | 4 +++- src/config.rs | 15 +++++++++++++-- src/filters.rs | 4 ++++ static/date.js | 4 ++++ static/main.js | 42 +++++++++++++++++++++++++++++++++++++++--- static/style.css | 5 +++++ templates/index.html | 34 +++++++++++++++++++++++----------- templates/post.html | 2 +- 9 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 static/date.js diff --git a/README.md b/README.md index 4135ad4..b8dfb5b 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,12 @@ title = "bingus-blog" # title 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 +js_enable = true # enable javascript (required for below 2 options) 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) +default_sort = "date" # default sorting method ("date" or "name") default_color = "#f5c2e7" # default embed color, optional [rss] @@ -144,7 +145,7 @@ created_at: 2024-04-18T04:15:26+03:00 # date of writing, this is highly # because this is fetched from file stats by default #modified_at: ... # see above. this is also fetched from the filesystem tags: # tags, or keywords, used in meta and also in the ui - - lifestyle + - lifestyle --- ``` @@ -165,11 +166,11 @@ standard. examples of valid and invalid dates: ## Routes -- `GET /`: index page, lists posts -- `GET /posts`: returns a list of all posts with metadata in JSON format -- `GET /posts/`: view a post -- `GET /posts/.md`: view the raw markdown of a post -- `GET /post/*`: redirects to `/posts/*` +- `GET /`: index page, lists posts +- `GET /posts`: returns a list of all posts with metadata in JSON format +- `GET /posts/`: view a post +- `GET /posts/.md`: view the raw markdown of a post +- `GET /post/*`: redirects to `/posts/*` ## Cache @@ -190,8 +191,8 @@ there is basically no good reason to not have compression on. make sure your changes don't cause problems on at least the following browsers: -- links2 -- lynx -- w3m -- Firefox -- Chromium +- links2 +- lynx +- w3m +- Firefox +- Chromium diff --git a/src/app.rs b/src/app.rs index 913687a..b3e7337 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, DateFormat}; +use crate::config::{Config, DateFormat, Sort}; use crate::error::{AppError, AppResult}; use crate::filters; use crate::post::{MarkdownPosts, PostManager, PostMetadata, RenderStats, ReturnedPost}; @@ -35,6 +35,7 @@ struct IndexTemplate<'a> { df: &'a DateFormat, js: bool, color: Option<&'a str>, + sort: Sort, } #[derive(Template)] @@ -72,6 +73,7 @@ async fn index<'a>( df: &config.date_format, js: config.js_enable, color: config.default_color.as_deref(), + sort: config.default_sort, } .into_response()) } diff --git a/src/config.rs b/src/config.rs index 50bbd8a..24c2b72 100644 --- a/src/config.rs +++ b/src/config.rs @@ -67,14 +67,24 @@ pub enum DateFormat { Strftime(String), } +#[derive(Serialize, Deserialize, Debug, Clone, Default, Copy, PartialEq, Eq)] +#[serde(rename_all = "lowercase")] +#[repr(u8)] +pub enum Sort { + #[default] + Date, + Name, +} + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(default)] pub struct Config { pub title: String, pub description: String, pub markdown_access: bool, - pub date_format: DateFormat, pub js_enable: bool, + pub date_format: DateFormat, + pub default_sort: Sort, pub default_color: Option, pub rss: RssConfig, pub dirs: DirsConfig, @@ -89,8 +99,9 @@ impl Default for Config { title: "bingus-blog".into(), description: "blazingly fast markdown blog software written in rust memory safe".into(), markdown_access: true, - date_format: Default::default(), js_enable: true, + date_format: Default::default(), + default_sort: Default::default(), default_color: Some("#f5c2e7".into()), // i have a love-hate relationship with serde // it was engimatic at first, but then i started actually using it diff --git a/src/filters.rs b/src/filters.rs index 24d0a10..4e40ac9 100644 --- a/src/filters.rs +++ b/src/filters.rs @@ -50,3 +50,7 @@ pub fn collect_tags(posts: &Vec) -> Result, ask Ok(tags) } + +pub fn join_tags_for_meta(tags: &Vec) -> Result { + Ok(tags.join(", ")) +} diff --git a/static/date.js b/static/date.js new file mode 100644 index 0000000..ad261ed --- /dev/null +++ b/static/date.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/main.js b/static/main.js index ad261ed..f99ea13 100644 --- a/static/main.js +++ b/static/main.js @@ -1,4 +1,40 @@ -for (let el of document.querySelectorAll(".date-rfc3339")) { - let date = new Date(Date.parse(el.textContent)); - el.textContent = date.toLocaleString(); +let form = document.getElementById("sort"); +let posts = document.getElementById("posts"); + +let postsName = document.createElement("div"); + +function initialSort(source, target) { + let posts = []; + for (let post of source.children) { + let title = post.firstElementChild.innerText; + posts.push([title, post.cloneNode(true)]); + } + posts.sort(([a, _1], [b, _2]) => a.toLocaleLowerCase() > b.toLocaleLowerCase()); + for (let [_, post] of posts) { + target.appendChild(post); + } } + +function sort(by) { + console.log("sorting by", by); + switch (by) { + case "date": + posts.style.display = "block"; + postsName.style.display = "none"; + break; + case "name": + postsName.style.display = "block"; + posts.style.display = "none"; + break; + } +} + +function handleSort() { + if (!form) return; + for (let el of form.sort) el.addEventListener("change", () => sort(form.sort.value)); +} + +initialSort(posts, postsName); +posts.parentNode.appendChild(postsName); +handleSort(); +sort(form.sort.value); diff --git a/static/style.css b/static/style.css index 2faa0f2..13922fc 100644 --- a/static/style.css +++ b/static/style.css @@ -112,6 +112,11 @@ div.post { grid-row: 3; } +#sort { + display: inline-block; + margin-bottom: 1rem; +} + /* BEGIN cool effect everyone liked */ body { diff --git a/templates/index.html b/templates/index.html index 85d6b21..9112bf5 100644 --- a/templates/index.html +++ b/templates/index.html @@ -17,6 +17,7 @@ {% endif %} {% if js %} + {% endif %} @@ -25,20 +26,31 @@

{{ title }}

{{ description }}

posts

-
- {% if posts.is_empty() %} - there are no posts right now. check back later! + {% if posts.is_empty() %} + there are no posts right now. check back later! + {% else %} + {% if js %} + sort by: +
+ + + + +
{% endif %} - {% for post in posts %} -
- {{ post.title }} - -
- {{ post.description }}
- {% call macros::table(post) %} +
+ {% for post in posts %} +
+ {{ post.title }} + +
+ {{ post.description }}
+ {% call macros::table(post) %} +
+ {% endfor %}
- {% endfor %} + {% endif %}
{% let tags = posts|collect_tags %} {% if !tags.is_empty() %} diff --git a/templates/post.html b/templates/post.html index 8abfe66..5c4daf1 100644 --- a/templates/post.html +++ b/templates/post.html @@ -5,7 +5,7 @@ - +