template blog index

This commit is contained in:
2022-10-12 16:58:44 -06:00
parent 610da9079e
commit 07dd08698c
6 changed files with 32 additions and 48 deletions

View File

@@ -1,6 +1,6 @@
open Lwt open Lwt
module BlogPost = struct module Blog_post = struct
type t = { type t = {
slug : string; slug : string;
title : string; title : string;
@@ -14,7 +14,7 @@ module Q = struct
open Caqti_type.Std open Caqti_type.Std
let blog_post = let blog_post =
let open BlogPost in let open Blog_post in
let encode {slug; title; content; date} = Ok (slug, title, content, date) in let encode {slug; title; content; date} = Ok (slug, title, content, date) in
let decode (slug, title, content, date) = Ok {slug; title; content; date} in let decode (slug, title, content, date) = Ok {slug; title; content; date} in
let b_rep = Caqti_type.(tup4 string string string string) in let b_rep = Caqti_type.(tup4 string string string string) in

View File

@@ -1,4 +1,4 @@
module BlogPost : module Blog_post :
sig sig
type t = { type t = {
slug : string; slug : string;
@@ -8,33 +8,6 @@ module BlogPost :
} }
end end
module Q :
sig
val blog_post : BlogPost.t Caqti_type.t
val create_blog_post_table : (unit, unit, [ `Zero ]) Caqti_request.t
val create_blog_post :
(string * string * string * string, unit, [ `Zero ]) Caqti_request.t
val get_all_blog_posts :
(unit, BlogPost.t, [ `Many | `One | `Zero ]) Caqti_request.t
val get_all_blog_posts_for_display :
(unit, string * string, [ `Many | `One | `Zero ]) Caqti_request.t
val get_blog_post_by_slug :
(string, BlogPost.t, [ `One | `Zero ]) Caqti_request.t
val update_blog_post_content :
(string * string, unit, [ `Zero ]) Caqti_request.t
val update_blog_post_title :
(string * string, unit, [ `Zero ]) Caqti_request.t
val delete_blog_post : (string, unit, [ `Zero ]) Caqti_request.t
end
module Db : Caqti_lwt.CONNECTION module Db : Caqti_lwt.CONNECTION
val create_blog_post_table : val create_blog_post_table :
@@ -56,14 +29,14 @@ val update_blog_post_title :
val get_blog_post_by_slug : val get_blog_post_by_slug :
string -> string ->
(BlogPost.t option, [> Caqti_error.call_or_retrieve ]) Stdlib.result Lwt.t (Blog_post.t option, [> Caqti_error.call_or_retrieve ]) Stdlib.result Lwt.t
val get_all_blog_posts : val get_all_blog_posts :
unit -> unit ->
(BlogPost.t list, [> Caqti_error.call_or_retrieve ]) Stdlib.result Lwt.t (Blog_post.t list, [> Caqti_error.call_or_retrieve ]) Stdlib.result Lwt.t
val iter_blog_posts : val iter_blog_posts :
(BlogPost.t -> (Blog_post.t ->
(unit, [> Caqti_error.call_or_retrieve ] as 'a) Stdlib.result Lwt.t) -> (unit, [> Caqti_error.call_or_retrieve ] as 'a) Stdlib.result Lwt.t) ->
(unit, 'a) Stdlib.result Lwt.t (unit, 'a) Stdlib.result Lwt.t

View File

@@ -18,7 +18,7 @@ let () =
Dream.get "/resume" @@ Dream.from_filesystem "html" "resume.html"; Dream.get "/resume" @@ Dream.from_filesystem "html" "resume.html";
Dream.get "/philosophy" @@ Dream.from_filesystem "html" "philosophy.html"; Dream.get "/philosophy" @@ Dream.from_filesystem "html" "philosophy.html";
Dream.get "/web-ring" @@ Dream.from_filesystem "html" "web-ring.html"; Dream.get "/web-ring" @@ Dream.from_filesystem "html" "web-ring.html";
Dream.get "/blog" Render.render_blog_index; Dream.get "/blog" (fun _ -> Render.render_blog_index ());
Dream.scope "/blog" [] [ Dream.scope "/blog" [] [
Dream.get "/rss.xml" Render.render_rss_feed; Dream.get "/rss.xml" Render.render_rss_feed;
Dream.get "/:post" (fun request -> Render.render_blog_post ~slug:(Dream.param request "post")) Dream.get "/:post" (fun request -> Render.render_blog_post ~slug:(Dream.param request "post"))

View File

@@ -0,0 +1,17 @@
let render ~posts =
let open Database in
<div>
<h3>Blog</h3>
I have an <a href="/blog/rss.xml">RSS feed</a> too.
<br>
</div>
% posts |> List.iter begin fun (post : Blog_post.t) ->
<div class="link-wrapper">
<a href="/blog/<%s post.slug %>">
<%s post.title %>
</a>
<i>
<%s post.date %>
</i>
</div>
% end;

View File

@@ -1,6 +1,6 @@
open Lwt open Lwt
module BlogPost = Database.BlogPost module Blog_post = Database.Blog_post
module type SimpleRender = (sig val render : unit -> string end) module type SimpleRender = (sig val render : unit -> string end)
@@ -81,7 +81,7 @@ let render_page content =
content content
footer_template footer_template
let generate_link (p : BlogPost.t) = let generate_link (p : Blog_post.t) =
Printf.sprintf Printf.sprintf
{eos|<div class="link-wrapper"> {eos|<div class="link-wrapper">
<a href="/blog/%s">%s</a> <a href="/blog/%s">%s</a>
@@ -89,7 +89,7 @@ let generate_link (p : BlogPost.t) =
</div>|eos} </div>|eos}
p.slug p.title p.date p.slug p.title p.date
let generate_rss_item (p : BlogPost.t) = let generate_rss_item (p : Blog_post.t) =
Printf.sprintf Printf.sprintf
{eos|<item> {eos|<item>
<title>%s</title> <title>%s</title>
@@ -105,18 +105,11 @@ let handle_error e =
let handle_not_found () = let handle_not_found () =
Dream.html ?code:(Some 404) not_found_template Dream.html ?code:(Some 404) not_found_template
let render_blog_index (_ : Dream.request) = let render_blog_index () =
let buff = Buffer.create 512 in let%lwt posts = Database.get_all_blog_posts () in
let () = Buffer.add_string buff "<h3>Blog</h3> I have an <a href=\"/blog/rss.xml\">rss feed</a> too." in match posts with
let posts_t = Database.get_all_blog_posts () in
posts_t >>= function
| Error e -> handle_error e | Error e -> handle_error e
| Ok posts -> | Ok posts -> Blog_index.render ~posts |> Layout.render |> Dream.html
List.iter (fun p -> Buffer.add_string buff (generate_link p)) posts;
let c = if List.length posts <> 0 then
render_page @@ Buffer.contents buff
else render_page "<br>No blog posts..." in
Dream.html c
let render_rss_feed (_ : Dream.request) = let render_rss_feed (_ : Dream.request) =
let buff = Buffer.create 512 in let buff = Buffer.create 512 in

View File

@@ -24,6 +24,7 @@ nav > * {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
margin-bottom: 3px;
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {