Commit a1fc79e2 authored by Dario Pinto's avatar Dario Pinto
Browse files

Add blog homepage and article metadata display

parent da5e58cb
type article =
{ date : int * int * int
; title : string
; authors : string list
; tags : string list
; category : string
; content : string
; url : string
}
let string_of_file file =
let chan = open_in ("src/content/" ^ file) in
let rec aux acc chan =
match input_line chan with
| exception End_of_file -> acc
| line -> aux (acc ^ "\n" ^ line) chan
in
let res = aux "" chan in
close_in chan;
res
let get_value field = List.hd (List.rev (String.split_on_char ':' field))
let post_header t a d c tg =
let title = get_value t in
let authors = get_value a in
let date = get_value d in
let category = get_value c in
let tags = get_value tg in
let extract_date date =
match String.split_on_char '-' date with
| [ year; month; day ] ->
(int_of_string year, int_of_string month, int_of_string day)
| _ -> (0, 0, 0)
let article_of_string post url =
match String.split_on_char '\n' post with
| title :: authors :: date :: category :: tags :: r ->
Some
{ date = extract_date (get_value date)
; title = get_value title
; authors =
(let authors = get_value authors in
match String.split_on_char ',' authors with
| [] -> [ "Unspecified authors!" ]
| auth -> auth )
; tags =
(let tags = get_value tags in
match String.split_on_char ',' tags with
| [] -> [ "Unspecified tags!" ]
| tags -> tags )
; category = get_value category
; content = String.concat "\n" r
; url
}
| _ -> None
let post_header title authors (year, month, day) category tags =
Format.asprintf
{|<h1 id="page-title">%s</h1>
<div class="row">
<div class="col-lg-3">
<img src="/blog/assets/img/icon_person.svg" style="max-width:1em"/>
Authors: %s
Authors: %a
</div>
<div class="col-lg-3">
<img src="/blog/assets/img/icon_calendar.svg" style="max-width:1em"/>
Date: %s
Date: %4d-%2d-%2d
</div>
<div class="col-lg-3">
<img src="/blog/assets/img/icon_category.svg" style="max-width:1em"/>
......@@ -23,9 +67,48 @@ let post_header t a d c tg =
</div>
<div class="col-lg-3">
<img src="/blog/assets/img/icon_tags.svg" style="max-width:1em"/>
Tags: %s
Tags: %a
</div>
</div>
<hr class="featurette-divider"/>
|}
title authors date category tags
title
(Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt ", ")
Format.pp_print_string )
authors year month day category
(Format.pp_print_list
~pp_sep:(fun fmt () -> Format.fprintf fmt ", ")
Format.pp_print_string )
tags
let pp_articles fmt articles_data_list =
List.iter
(fun article ->
Format.fprintf fmt {|<a href="%s">%s</a>@.<br />|} article.url
article.title )
articles_data_list
let home_page home =
let articles =
List.find_all
(fun file ->
(String.length file >= 5 && String.equal (String.sub file 0 5) "blog/")
&& Filename.check_suffix file ".md" )
Content.file_list
in
let articles_data =
List.map
(fun article ->
match Content.read article with
| None -> failwith "invalid article data"
| Some data -> (
match article_of_string data (Filename.chop_suffix article ".md") with
| None -> failwith "invalid article data"
| Some data -> data ) )
articles
in
let articles_by_date =
List.sort (fun a1 a2 -> compare a2.date a1.date) articles_data
in
Format.asprintf "%s%a" home pp_articles articles_by_date
<h1 id="page-title">Blog</h1>
This is our blog
title: opam 2.1.0 is released!
authors: rjbou
date: 2021-08-05
category: tooling
tags: opam
title:opam 2.1.0 is released!
authors:rjbou
date:2021-08-05
category:tooling
tags:opam
<div class="row">
<div class="col-lg-12" align="center">
......
......@@ -14,18 +14,24 @@ let blog_asset_loader _root path _request =
let page path =
match Content.read (path ^ ".md") with
| None -> None
| Some page -> Some (Omd.of_string page |> Omd.to_html)
| Some page -> (
match path with
| "blog" -> Some (Omd.of_string (Blog.home_page page) |> Omd.to_html)
| _any_other_page -> Some (Omd.of_string page |> Omd.to_html) )
let article path =
match Content.read ("blog/" ^ path ^ ".md") with
| None -> None
| Some blog_article -> (
match String.split_on_char '\n' blog_article with
| title :: authors :: date :: category :: tags :: article ->
let header = Blog.post_header title authors date category tags in
Some (header ^ (Omd.of_string (String.concat "\n" article) |> Omd.to_html))
| _ -> None )
| Some blog_article -> begin
match Blog.article_of_string blog_article path with
| None -> None
| Some article ->
let header =
Blog.post_header article.title article.authors article.date
article.category article.tags
in
Some (header ^ (Omd.of_string article.content |> Omd.to_html))
end
let () =
Dream.run @@ Dream.logger
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment