template blog index
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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"))
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user