(* COCANWIKI - a wiki written in Objective CAML.
* Written by Richard W.M. Jones <rich@merjis.com>.
* Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_ext_calendar.ml,v 1.1 2004/10/07 16:54:24 rich Exp $
+ * $Id: cocanwiki_ext_calendar.ml,v 1.3 2004/10/09 08:33:02 rich Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
let day_template = _get_template "calendar_day.html"
let month_template = _get_template "calendar_month.html"
let year_template = _get_template "calendar_year.html"
+let year_1m_template = _get_template "calendar_year_1m.html"
let rec range a b =
if a <= b then
| _ -> assert false) in
List.filter_map
(fun (from_url, title, to_url) ->
- try let date = valid_date to_url in Some (date, title, from_url)
+ try let date = valid_date to_url in Some (date, (title, from_url))
with Not_found -> None) results in
let pages = List.sort pages in
"<p>" ^ url ^ " is not an actual date.</p>"
| Some (yyyy, 0, 0) -> (* Year view. *)
let template = year_template in
- failwith "not impl";
-
-
-
-
+ template#set "yyyy" (string_of_int yyyy);
+ template#set "prev_yyyy" (string_of_int (yyyy - 1));
+ template#set "next_yyyy" (string_of_int (yyyy + 1));
+
+ (* Return true if there are any events on a particular day. *)
+ let has_events date = List.exists (fun (d, _) -> date = d) pages in
+
+ (* Generate each month template separately ...
+ * Wow, finally found a place I can use a for loop.
+ *)
+ for mm = 1 to 12 do
+ let str =
+ let template = year_1m_template in
+ template#set "yyyy" (string_of_int yyyy);
+ template#set "mm" (sprintf "%02d" mm);
+ template#set "month_name" (long_month mm);
+ let dow = GregorianDate.day_of_week (yyyy, mm, 1) in
+ let dow = if dow = 7 then 0 else dow in
+ let max_dd = GregorianDate.days_in_month yyyy mm in
+ let dd = ref (1-dow) in
+ let rows = ref [] in
+ for r = 0 to 5 do (* up to 5 rows ... *)
+ let cols = ref [] in
+ for c = 0 to 6 do (* 7 columns, Sunday - Saturday *)
+ let is_day = !dd >= 1 && !dd <= max_dd in
+ let clasz =
+ if is_day then (
+ let date = yyyy, mm, !dd in
+ let is_weekend = GregorianDate.day_of_week date >= 6 in
+ let events = has_events date in
+ (if is_weekend then "cal_year_1m_weekend " else "") ^
+ (if events then "cal_year_1m_events" else "")
+ ) else
+ "cal_year_1m_empty" in
+ let col =
+ [ "is_day", Template.VarConditional is_day;
+ "dd", Template.VarString (sprintf "%02d" !dd);
+ "class", Template.VarString clasz ] in
+ cols := col :: !cols;
+ incr dd
+ done;
+ rows := [ "cols", Template.VarTable (List.rev !cols) ] :: !rows;
+ cols := []
+ done;
+
+ template#table "rows" (List.rev !rows);
+
+ template#to_string in
+ template#set ("month" ^ string_of_int mm) str
+ done;
+
+ (* Annual events. *)
+ let events =
+ List.filter (function ((_, 0, 0), _) -> true | _ -> false) pages in
+ let table =
+ List.map (fun (_, (title, page)) ->
+ [ "title", Template.VarString title;
+ "page", Template.VarString page ]) events in
+ template#table "events" table;
template#to_string
(* Get all monthly events and all daily events. *)
let monthly_events, daily_events =
- List.partition (function ((_, _, 0), _, _) -> true | _ -> false)
+ List.partition (function ((_, _, 0), _) -> true | _ -> false)
pages in
(* Table of monthly events. *)
let table =
- List.map (fun (_, title, page) ->
+ List.map (fun (_, (title, page)) ->
[ "title", Template.VarString title;
"page", Template.VarString page ]) monthly_events in
template#table "monthly_events" table;
let table =
List.map (fun dd ->
let events =
- List.filter (fun ((_, _, d), _, _) -> d = dd)
+ List.filter (fun ((_, _, d), _) -> d = dd)
daily_events in
let table =
- List.map (fun (_, title, page) ->
+ List.map (fun (_, (title, page)) ->
[ "title", Template.VarString title;
"page", Template.VarString page ])
events in
template#to_string
- | Some (yyyy, mm, dd) -> (* Single day view. *)
+ | Some ((yyyy, mm, dd) as date) -> (* Single day view. *)
let template = day_template in
- failwith "not impl";
-
-
-
-
-
-
+ (* XXX This will change once we start doing date and time events.
+ * For now it is very simple indeed.
+ *)
+ template#set "yyyy" (string_of_int yyyy);
+ template#set "mm" (sprintf "%02d" mm);
+ template#set "dd" (sprintf "%02d" dd);
+ template#set "month_name" (long_month mm);
+ let dow = GregorianDate.day_of_week date in
+ template#set "short_weekday" (short_weekday dow);
+ let prev_yyyy, prev_mm, prev_dd =
+ GregorianDate.add_delta_days date (-1) in
+ let next_yyyy, next_mm, next_dd =
+ GregorianDate.add_delta_days date 1 in
+ template#set "prev_yyyy" (string_of_int prev_yyyy);
+ template#set "prev_mm" (sprintf "%02d" prev_mm);
+ template#set "prev_dd" (sprintf "%02d" prev_dd);
+ template#set "next_yyyy" (string_of_int next_yyyy);
+ template#set "next_mm" (sprintf "%02d" next_mm);
+ template#set "next_dd" (sprintf "%02d" next_dd);
+ let table = List.map (fun (_, (title, page)) ->
+ [ "title", Template.VarString title;
+ "page", Template.VarString page ]) pages in
+ template#table "events" table;
template#to_string