simple-learning

Simple learning web program
git clone git://git.laack.co/simple-learning.git
Log | Files | Refs | README | LICENSE

commit 02694bcf37e1e562e092dde3163f7c2e622dfffa
parent 9f00ca8ba772576efc2e81bba261a7a9104f367f
Author: Andrew Laack <andrew@laack.co>
Date:   Thu, 27 Aug 2026 11:28:44 -0500

Refactoring to use jingoo (jinja clone)

Diffstat:
Mlearning/bin/dune | 2+-
Mlearning/bin/main.ml | 98++++++++++++++++++++++---------------------------------------------------------
Mlearning/dune-project | 2+-
Alearning/templates/course.jingoo | 14++++++++++++++
Alearning/templates/course_list.jingoo | 15+++++++++++++++
5 files changed, 58 insertions(+), 73 deletions(-)

diff --git a/learning/bin/dune b/learning/bin/dune @@ -1,4 +1,4 @@ (executable (public_name learning) (name main) - (libraries dream)) + (libraries dream jingoo)) diff --git a/learning/bin/main.ml b/learning/bin/main.ml @@ -1,88 +1,44 @@ -let escape input = - Dream.html_escape input +open Jingoo -let countPrefix char data = - let rec go idx = - if String.length data > idx && data.[idx] = char - then - go (idx + 1) - else idx - in go 0 - - -let handle_normal_line line = - if String.length line > 0 then - let hashCount = countPrefix '#' line in - if hashCount > 0 - then - "<h" ^ string_of_int hashCount ^ ">" ^ escape line ^ "</h" ^ string_of_int hashCount ^ ">" - else - "<content-block>" ^ escape line ^ "</content-block>" - else - (* return nothing if the line is empty *) - "" - - -(* Read in the file with the fileName and apply line_application to each line of the file returning the resulting string. *) -let readFile fileName line_application = +let readFile fileName = let ic = open_in fileName in let rec readAll acc = try - readAll (acc ^ (line_application (input_line ic)) ^ "\n") + readAll (acc ^ ((input_line ic)) ^ "\n") with End_of_file -> close_in_noerr ic; acc in readAll "" - -let id x = x - -let basic_html_prefix = - " - <!DOCTYPE html> - <html> - <head> - <link rel=\"stylesheet\" href=\"/static/styles.css\" type=\"text/css\"> - </head> - <body> - <div class=\"sidenav\"> - <a href=\"/\">Home</a> - <a href=\"#\">Services</a> - <a href=\"#\">Clients</a> - <a href=\"#\">Contact</a> - </div> - <div class=\"main\"> - " -let basic_html_suffix = - "</body> - </div> - </html>" - - -let arr_to_string arr fn = - let rec go acc idx = - if idx < Array.length(arr) then - go (acc ^ (fn arr.(idx))) (idx + 1) - else acc - in go "" 0 - let remove_file_extension file_name = let fin_period_pos = String.rindex file_name '.' in String.sub file_name 0 fin_period_pos -let course_to_html name = - "<div> <a href=\"/course/" ^ escape (remove_file_extension name) ^ "\">" ^ escape (remove_file_extension name) ^ "</div>" +let to_tval value = + Jg_types.Tobj [("name", Jg_types.Tstr value);] + let get_courses = - basic_html_prefix ^ arr_to_string (Sys.readdir "../example/") course_to_html ^ basic_html_suffix + Jg_types.Tlist + (Array.to_list (Array.map to_tval (Array.map remove_file_extension (Sys.readdir "../example/")))) -let () = - Dream.run - @@ Dream.logger - @@ Dream.router [ +let render_course_list = + (Jg_template.from_file "./templates/course_list.jingoo" ~models:[("courses", get_courses)]) - Dream.get "/course/:id" - (fun request -> Dream.html (basic_html_prefix ^ (readFile ("../example/" ^ Dream.param request "id" ^ ".rl") handle_normal_line) ^ basic_html_suffix)); - Dream.get "/static/**" (Dream.static "./static"); - Dream.get "/" (fun _ -> Dream.html get_courses); - ] +let to_course name content = + Jg_types.Tobj [("name", Jg_types.Tstr name); ("content", Jg_types.Tstr content); +] + +let render_course course_name = + (Jg_template.from_file "./templates/course.jingoo" ~models:[( + "course", to_course course_name (readFile ("../example/" ^ course_name ^ ".rl")) + )]) + +let () = + Dream.run + @@ Dream.logger + @@ Dream.router [ + Dream.get "/course/:id" (fun request -> Dream.html (render_course (Dream.param request "id"))); + Dream.get "/static/**" (Dream.static "./static"); + Dream.get "/" (fun _ -> Dream.html render_course_list) + ] diff --git a/learning/dune-project b/learning/dune-project @@ -19,7 +19,7 @@ (name learning) (synopsis "A short synopsis") (description "A longer description") - (depends ocaml dream) + (depends ocaml dream jingoo) (tags ("add topics" "to describe" your project))) diff --git a/learning/templates/course.jingoo b/learning/templates/course.jingoo @@ -0,0 +1,14 @@ +<link rel="stylesheet" href="/static/styles.css" type="text/css"> +<div class="sidenav"> + <a href="/">Home</a> + <a href="">Services</a> + <a href="">Clients</a> + <a href="">Contact</a> +</div> + +<div class="main"> + <div> + <h1>{{ course.name }}</h1> + <div> {{ course.content }}</div> + </div> +</div> diff --git a/learning/templates/course_list.jingoo b/learning/templates/course_list.jingoo @@ -0,0 +1,15 @@ +<link rel="stylesheet" href="/static/styles.css" type="text/css"> +<div class="sidenav"> + <a href="/">Home</a> + <a href="">Services</a> + <a href="">Clients</a> + <a href="">Contact</a> +</div> + +<div class="main"> + <ul> + {% for course in courses %} + <li><a href="/course/{{ course.name }}">{{ course.name }}</a></li> + {% endfor %} + </ul> +</div>