Commits

Pierre Surply committed fe52c9a

First commit

  • Participants

Comments (0)

Files changed (14)

+*~
+*.cgi
+*_build/
+AddHandler cgi-script .cgi
+Options +ExecCGI
+DirectoryIndex cgi-bin/ocaml-wenframework.cgi
+##
+## Makefile for OCaml-OCR in /website
+## 
+## Made by Pierre Surply
+## <pierre.surply@gmail.com>
+## 
+## Started on  Fri Sep 14 20:30:24 2012 Pierre Surply
+## Last update Thu Oct 11 15:24:34 2012 pierre surply
+##
+
+EXEC = ocaml-webframework.cgi
+export EXEC
+
+all: cgi-bin
+
+clean: COMMAND=clean
+clean: cgi-bin
+
+test: COMMAND=test
+test: cgi-bin
+
+cgi-bin: FORCE
+	@$(MAKE) -C $@ $(COMMAND)
+
+FORCE:
+# OCaml-WebFramework
+
+## Template engine
+
+The template engine, programmed with OCaml, is designed to process web templates (situated in `/website/templates/`) and dynamic content (situated in `/website/cgi-bin`) to produce output web documents.
+
+The template language uses the following syntax :
+
+  - `[begin *part*]*html code*[end]` : defines a part of html code
+  - `{ *part* }` : includes the content of the part *part* previously defined
+  - `{% *function* %}` : includes the result of the OCaml function *function*. The function must be declared in the file `/website/cgi-bin/cgi_functions.ml`.
+  - `{@ *template* @}` : Tells the template engine that the current template "extends" another template.
+
+Once template processing is complete, the content of the part `base` is printed by the CGI.
+
+## URL dispatcher
+
+The URL is divided as follows :
+
+    http://domain?arg0/arg1/arg2/...
+
+The arg0 represents the name of the page asked by the user.
+You can link the arg0 to a template in the file `/website/cgi-bin/url.ml`.
+The others arguments can be gotten with the function `Env.get_url_arg n`.
+
+## Example
+
+### templates/base.html
+
+    :::html
+    [begin base]
+    <!DOCTYPE html>
+    <html>
+      <head>
+        <title>OCaml-OCR -{ title }</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+      </head>
+      <body>
+        <nav>
+          <ul>
+            <li><a href="?index/">Home</a></li>
+            <li><a href="?about/">About</a></li>
+          </ul>
+        </nav>
+        { body }
+      </body>
+    </html>
+    [end]
+
+
+### templates/index.html
+
+    :::html
+    {@ base.html @}
+    
+    [begin title] Index [end]
+    
+    [begin body]
+    <h1>Hello World ! </h1>
+    <p>{% get_time %}</p>
+    [end]
+
+### templates/about.html
+
+    :::html
+    {@ base.html @}
+    
+    [begin title] About [end]
+    
+    [begin body]
+    <h1>About</h1>
+    [end]
+
+### cgi-bin/url.ml
+
+    :::ocaml
+    ...
+    let get_page_from_url () =
+      match Env.get_url_arg 0 with
+        | "about" -> "about.html"
+        | _ -> "index.html"
+    ...
+
+### cgi-bin/cgi_functions.ml
+
+    :::ocaml
+    ...
+    let get_function = function
+      | "get_time" -> Date.get_date ()
+      | f -> "Cannot find function : " ^ f
+    ...
+
+##
+## Makefile for OCaml-OCR in /website/cgi-bin
+## 
+## Made by Pierre Surply
+## <pierre.surply@gmail.com>
+## 
+## Started on  Sat Sep 15 11:14:39 2012 Pierre Surply
+## Last update Sun Sep 16 15:07:16 2012 Pierre Surply
+##
+
+OCAMLBUILD = ocamlbuild
+BUILDFLAGS = -lflags unix.cmxa,str.cmxa -verbose 1
+BUILDTYPE  = native
+
+MAIN	   = main.$(BUILDTYPE)
+URL_TEST   = index/
+
+all: $(MAIN)
+
+$(MAIN):
+	@$(OCAMLBUILD) $(BUILDFLAGS) $@
+	@mv $(MAIN) $(EXEC)
+
+test: REQUEST_METHOD=GET
+test: QUERY_STRING=$(URL_TEST)
+test: $(MAIN)
+	./$(EXEC)
+
+clean:
+	@$(OCAMLBUILD) -clean

cgi-bin/cgi_functions.ml

+(*
+** cgi_functions.ml for OCaml-WebFramework
+** 
+** Made by Pierre Surply
+** <pierre.surply@gmail.com>
+** 
+** Started on  Sat Sep 15 21:11:04 2012 Pierre Surply
+Last update Thu Oct 11 15:23:48 2012 pierre surply
+*)
+
+let get_function = function
+  | "get_time" -> Date.get_date ()
+  | f -> "Cannot find function : " ^ f
+(*
+** date.ml for OCaml-WebFramework
+** 
+** Made by Pierre Surply
+** <pierre.surply@gmail.com>
+** 
+** Started on  Sat Sep 15 21:11:47 2012 Pierre Surply
+Last update Thu Oct 11 15:24:01 2012 pierre surply
+*)
+
+let get_date () =
+  let time = Unix.localtime (Unix.time ()) in
+  string_of_int (time.Unix.tm_hour) ^ ":" ^
+    string_of_int (time.Unix.tm_min) ^ ":" ^
+    string_of_int (time.Unix.tm_sec)
+(*
+** env.ml for OCaml-WebFramework
+** 
+** Made by Pierre Surply
+** <pierre.surply@gmail.com>
+** 
+** Started on  Sun Sep 16 13:57:47 2012 Pierre Surply
+Last update Thu Oct 11 15:24:05 2012 pierre surply
+*)
+
+let get_env str =
+  try
+    Sys.getenv str
+  with Not_found -> ""
+
+let url =
+  let req_method = get_env "REQUEST_METHOD" in
+  match req_method with
+    | "GET" | "HEAD" -> get_env "QUERY_STRING"
+    | _ -> ""
+
+let url_arg =
+  let regex = Str.regexp "\\([^/]*\\)/" in
+  let rec build_url_arg s start =
+    if (try Str.search_forward regex s start
+      with Not_found -> -1) > -1 then
+      begin
+	let start = Str.match_end () in
+	let arg = Str.matched_group 1 s in
+	arg::build_url_arg s start
+      end
+    else []
+  in
+  build_url_arg url 0
+
+let get_url_arg n =
+  let rec r_get n = function
+    | [] -> ""
+    | h::t ->
+      if n = 0 then h
+      else r_get (n-1) t
+  in
+  r_get n url_arg
+(*
+** main.ml for OCaml-WebFramework
+** 
+** Made by Pierre Surply
+** <pierre.surply@gmail.com>
+** 
+** Started on  Sat Sep 15 11:14:18 2012 Pierre Surply
+Last update Thu Oct 11 15:24:09 2012 pierre surply
+*)
+
+let content_type = "Content-Type: text/html;\n\n"
+
+let main () =
+  print_string (content_type ^ 
+		  Url.make_page_from_url ());
+  exit 0
+
+let _ = main ()

cgi-bin/template.ml

+(*
+** template.ml for OCaml-WebFramework
+**
+** Made by Pierre Surply
+** <pierre.surply@gmail.com>
+**
+** Started on  Sat Sep 15 13:45:19 2012 Pierre Surply
+Last update Thu Oct 11 15:24:12 2012 pierre surply
+*)
+
+let template_dir = "../templates/"
+let base = "base"
+
+let regex_link = Str.regexp "{@ \\(.*\\) @}"
+let regex_fun = Str.regexp "{% \\(.*\\) %}"
+let regex_include = Str.regexp "{ \\([^{}]*\\) }"
+let regex_part = Str.regexp
+  "\\[begin \\(.*\\)\\]\\(\\([^][]\\|\n\\)*\\)\\[end\\]"
+
+let apply_function s =
+  Cgi_functions.get_function (Str.matched_group 1 s)
+
+let rec extract_part s start org_list=
+  if (try Str.search_forward regex_part s start
+    with Not_found -> -1) > -1 then
+    begin
+      let start = Str.match_end () in
+      let label = Str.matched_group 1 s in
+      let content = Str.matched_group 2 s in
+      (label, content)::extract_part s start org_list
+    end
+  else org_list
+
+let rec get_part label = function
+  | [] -> "<!-- " ^ label ^ " -->"
+  | (l, c)::t ->
+    if l = label then c
+    else get_part label t
+
+let fill_part part s =
+  get_part (Str.matched_group 1 s) part
+
+let make_page file =
+  let rec r_load_template f =
+    try
+      let line = input_line f in
+      line ^ "\n" ^ r_load_template f
+    with End_of_file -> close_in f; ""
+  in
+  let rec r_load file part=
+    let s = r_load_template (open_in (template_dir ^ file)) in
+    let s_applied_fun = Str.global_substitute regex_fun
+      apply_function s in
+    let s_filled = Str.global_substitute regex_include
+      (fill_part part) s_applied_fun in
+    let part = extract_part s_filled 0 part in
+    if (try Str.search_forward regex_link s_filled 0
+      with Not_found -> -1) > -1 then
+      r_load (Str.matched_group 1 s_filled) part
+    else
+      get_part base part
+  in
+  r_load file []
+(*
+** url.ml for OCaml-WebFramework
+**
+** Made by Pierre Surply
+** <pierre.surply@gmail.com>
+**
+** Started on  Sun Sep 16 11:31:15 2012 Pierre Surply
+Last update Thu Oct 11 15:24:18 2012 pierre surply
+*)
+
+let get_page_from_url () =
+  match Env.get_url_arg 0 with
+    | "about" -> "about.html"
+    | _ -> "index.html"
+
+let make_page_from_url () =
+  Template.make_page (get_page_from_url ())

templates/about.html

+{@ base.html @}
+
+[begin title] About [end]
+
+[begin body]
+<h1>About</h1>
+[end]

templates/base.html

+[begin base]
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>OCaml-OCR -{ title }</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  </head>
+  <body>
+    <nav>
+      <ul>
+        <li><a href="?index/">Home</a></li>
+        <li><a href="?about/">About</a></li>
+      </ul>
+    </nav>
+    { body }
+  </body>
+</html>
+[end]

templates/index.html

+{@ base.html @}
+
+[begin title] Index [end]
+
+[begin body]
+<h1>Hello World ! </h1>
+<p>{% get_time %}</p>
+[end]