directory listing

This commit is contained in:
Michal Vanko 2024-01-14 22:56:14 +01:00
parent 03fefda519
commit 834f998788
5 changed files with 72 additions and 2 deletions

View File

@ -1,2 +1,3 @@
pub mod index;
pub mod post;
pub mod post_list;

View File

@ -13,7 +13,7 @@ pub struct PostMetadata {
pub published: bool,
#[serde(deserialize_with = "deserialize_date")]
pub date: DateTime<Utc>,
pub thumbnail: String,
pub thumbnail: Option<String>,
pub tags: Vec<String>,
}

View File

@ -0,0 +1,47 @@
use askama::Template;
use axum::http::StatusCode;
use tokio::fs::read_dir;
use tracing::info;
use crate::post_parser::{parse_post, ParseResult};
use super::post::PostMetadata;
#[derive(Template)]
#[template(path = "post_list.html")]
pub struct PostListTemplate {
pub posts: Vec<ParseResult<PostMetadata>>,
// TODO tags and pagination
}
pub async fn render_post_list() -> Result<PostListTemplate, StatusCode> {
let path = "../_posts/blog/";
let dir = read_dir(path).await;
let mut posts: Vec<ParseResult<PostMetadata>> = Vec::new();
let mut files = match dir {
Err(_reason) => {
// TODO find the real reason
return Err(StatusCode::INTERNAL_SERVER_ERROR);
}
Ok(files) => files,
};
while let Some(file) = files
.next_entry()
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
{
let file_path = file.path();
let file_path_str = file_path.to_str().unwrap();
info!(":{}", file_path_str);
let post = parse_post::<PostMetadata>(file_path_str).await?;
posts.push(post);
}
Ok(PostListTemplate { posts })
}
// TODO Do we want pagination or not? Ask designer
// TODO How are we going to implement tags? The path extractor would have to make decision on wether we have a path or a blog post
// TODO Refactor `?` with `.map_err`

View File

@ -1,4 +1,4 @@
use crate::pages::{index::render_index, post::render_post};
use crate::pages::{index::render_index, post::render_post, post_list::render_post_list};
use axum::{extract::MatchedPath, http::Request, routing::get, Router};
use tower_http::trace::TraceLayer;
use tracing::info_span;
@ -6,6 +6,7 @@ use tracing::info_span;
pub fn get_router() -> Router {
Router::new()
.route("/", get(render_index))
.route("/blog", get(render_post_list))
.route("/blog/:post_id", get(render_post))
.layer(
TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {

View File

@ -0,0 +1,21 @@
{% if posts.len() == 0 %}
<p class="no-posts">You've found void in the space.</p>
{% else %}
<h1>{# if filters.tags #} {# <em>{filters.tags}</em> #} Blog posts</h1>
{#if filters.tags#}
<div class="{seeAllClass}">
<a href="/blog">See all posts</a>
</div>
{% endif%}
<ul>
{% for post in posts %}
<li>
{# <ArticlePreviewCard {article} {segment} /> #} {#
<ArticleFooter {article} {segment} /> #} {{post.metadata.title}}
</li>
{% endfor %}
</ul>
{# <ArticlePreviewList {...data} segment="blog" /> #}