Per-section div class.
authorrich <rich>
Thu, 17 Aug 2006 09:11:29 +0000 (09:11 +0000)
committerrich <rich>
Thu, 17 Aug 2006 09:11:29 +0000 (09:11 +0000)
16 files changed:
html/_css/editor.css
schema/cocanwiki.sql
scripts/edit.ml
scripts/edit_page_css.ml
scripts/lib/cocanwiki_create_host.ml
scripts/lib/cocanwiki_diff.ml
scripts/lib/cocanwiki_mail.ml
scripts/lib/cocanwiki_pages.ml
scripts/lib/cocanwiki_pages.mli
scripts/mail_import.ml
scripts/page.ml
scripts/restore.ml
scripts/source.ml
templates/edit.html
templates/page.html
tools/copy_page.ml

index 4775958..7cad4b5 100644 (file)
@@ -1,5 +1,5 @@
 /* Stylesheet for COCANWIKI editor, derived from EWM.
- * $Id: editor.css,v 1.7 2006/07/26 13:41:31 rich Exp $
+ * $Id: editor.css,v 1.8 2006/08/17 09:11:29 rich Exp $
  */
 
 body {
@@ -62,6 +62,14 @@ input.css_id {
   font-size: 70%;
 }
 
+abbr.css_class {
+  font-size: 70%;
+}
+
+input.css_class {
+  font-size: 70%;
+}
+
 abbr.js_onclick {
   font-size: 70%;
 }
index 1254c38..afcf10f 100644 (file)
@@ -1115,7 +1115,8 @@ CREATE TABLE contents (
     divname text,
     content_fti tsvector NOT NULL,
     jsgo text,
-    CONSTRAINT "$2" CHECK (((jsgo IS NULL) OR (divname IS NOT NULL)))
+    divclass text,
+    CONSTRAINT "$2" CHECK (((jsgo IS NULL) OR ((divname IS NOT NULL) OR (divclass IS NOT NULL))))
 );
 
 
index 00ebc93..9cdcc93 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: edit.ml,v 1.36 2006/08/14 11:36:50 rich Exp $
+ * $Id: edit.ml,v 1.37 2006/08/17 09:11:31 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
@@ -81,9 +81,12 @@ let run r (q : cgi) dbh hostid {hostname = hostname} user =
       let divname = q#param ("divname_" ^ string_of_int !i) in
       let divname =
        if string_is_whitespace divname then None else Some divname in
+      let divclass = q#param ("divclass_" ^ string_of_int !i) in
+      let divclass =
+       if string_is_whitespace divclass then None else Some divclass in
       let jsgo = q#param ("jsgo_" ^ string_of_int !i) in
       let jsgo = if string_is_whitespace jsgo then None else Some jsgo in
-      contents := (sectionname, divname, jsgo, content) :: !contents;
+      contents := (sectionname, divname, divclass, jsgo, content) :: !contents;
       incr i
     done;
     let contents = List.rev !contents in
@@ -138,22 +141,22 @@ let run r (q : cgi) dbh hostid {hostname = hostname} user =
      *)
     if model.contents_ <> [] then
       List.iter (function
-                | (None, _, _, _) ->
+                | (None, _, _, _, _) ->
                     add_error
                       "Every section except the first must have a title.";
                 | _ -> ())
        (List.tl model.contents_);
 
     (* There are two constraints on any non-null jsgo's:
-     * (1) Must only be present if divname is non-null.
+     * (1) Must only be present if divname or divclass is non-null.
      * (2) Must point to a valid URL on the current host.
      *)
     List.iter (
       function
-      | (_, None, Some _, _) ->
+      | (_, None, None, Some _, _) ->
          add_error
-           "Javascript onclick can only be used with a CSS id."
-      | (_, _, Some jsgo, _) ->
+           "Javascript onclick can only be used with a CSS id/class."
+      | (_, _, _, Some jsgo, _) ->
          let rows =
            PGSQL(dbh) "select 1 from pages
                          where hostid = $hostid
@@ -288,14 +291,16 @@ let run r (q : cgi) dbh hostid {hostname = hostname} user =
     let ordering = ref 0 in
     let table =
       List.map
-       (fun (sectionname, divname, jsgo, content) ->
+       (fun (sectionname, divname, divclass, jsgo, content) ->
           incr ordering; let ordering = Int32.of_int !ordering in
           let sectionname = match sectionname with None -> "" | Some s -> s in
           let divname = match divname with None -> "" | Some s -> s in
+          let divclass = match divclass with None -> "" | Some s -> s in
           let jsgo = match jsgo with None -> "" | Some s -> s in
           [ "ordering", Template.VarString (Int32.to_string ordering);
             "sectionname", Template.VarString sectionname;
             "divname", Template.VarString divname;
+            "divclass", Template.VarString divclass;
             "jsgo", Template.VarString jsgo;
             "content", Template.VarString content ]) model.contents_ in
     template#table "contents" table;
@@ -388,7 +393,7 @@ let run r (q : cgi) dbh hostid {hostname = hostname} user =
       let posn = get_action "insert" in
       let item =
        Some "The title of this section",
-       None, None,
+       None, None, None,
        "Write something here." in
       model := action_insert !model posn item
     ) else if is_action "moveup" then (
index 8b18b9b..ed9f2da 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: edit_page_css.ml,v 1.23 2006/08/14 11:36:50 rich Exp $
+ * $Id: edit_page_css.ml,v 1.24 2006/08/17 09:11:31 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
@@ -79,9 +79,10 @@ let run r (q : cgi) dbh hostid {hostname = hostname} user =
   let pageid = PGOCaml.serial4 dbh "pages_id_seq" in
 
   PGSQL(dbh) "insert into contents (pageid, ordering,
-                                    sectionname, content, divname, jsgo)
+                                    sectionname, content, divname, divclass,
+                                    jsgo)
               select $pageid as pageid, ordering, sectionname,
-                     content, divname, jsgo
+                     content, divname, divclass, jsgo
                 from contents
                where pageid = $oldpageid";
 
index 28a26f7..f83f2ee 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_create_host.ml,v 1.6 2006/08/14 11:36:50 rich Exp $
+ * $Id: cocanwiki_create_host.ml,v 1.7 2006/08/17 09:11:31 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
@@ -83,9 +83,10 @@ let create_host dbh canonical_hostname hostnames template
     (* Copy page contents. *)
     PGSQL(dbh)
       "insert into contents (pageid, ordering, sectionname, content,
-                             divname, jsgo)
+                             divname, divclass, jsgo)
        select (select id from pages where hostid = $hostid and url = p.url),
-              c.ordering, c.sectionname, c.content, c.divname, c.jsgo
+              c.ordering, c.sectionname, c.content, c.divname, c.divclass,
+              c.jsgo
          from contents c, pages p
         where c.pageid = p.id and p.hostid = $template and p.url is not null";
 
index 3f4fdfa..cba7867 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_diff.ml,v 1.8 2006/08/14 11:36:50 rich Exp $
+ * $Id: cocanwiki_diff.ml,v 1.9 2006/08/17 09:11:31 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
@@ -47,7 +47,7 @@ let page_for_diff model css =
    | Some noodp -> string_of_bool noodp) ^ "\n\n" ^
   (String.concat ""
      (List.map (
-       fun (sectionname, divname, jsgo, content) ->
+       fun (sectionname, divname, divclass, jsgo, content) ->
          (match sectionname with
           | None -> ""
           | Some sectionname -> "HEADING: " ^ sectionname ^ "\n\n") ^
@@ -55,6 +55,9 @@ let page_for_diff model css =
          (match divname with
           | None -> ""
           | Some divname -> "CSS Id: " ^ divname ^ "\n") ^
+         (match divclass with
+          | None -> ""
+          | Some divclass -> "CSS Class: " ^ divclass ^ "\n") ^
          (match jsgo with
           | None -> ""
           | Some jsgo -> "Javascript Onclick: " ^ jsgo ^ "\n") ^
@@ -117,7 +120,7 @@ let get_version_for_diff dbh version =
     ) in
 
     let contents_ = PGSQL(dbh)
-      "select sectionname, divname, jsgo, content
+      "select sectionname, divname, divclass, jsgo, content
          from contents where pageid = $version
         order by ordering" in
 
index bef38af..f58b9b1 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_mail.ml,v 1.4 2006/07/27 16:46:55 rich Exp $
+ * $Id: cocanwiki_mail.ml,v 1.5 2006/08/17 09:11:31 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
@@ -402,7 +402,7 @@ let thread_mail r dbh hostid ?user year month =
 
       template#to_string
     in
-    (Some sectionname, None, None, content)
+    (Some sectionname, None, None, None, content)
   in
 
   let contents =
index d616cb7..4d17f62 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_pages.ml,v 1.10 2006/08/14 11:36:50 rich Exp $
+ * $Id: cocanwiki_pages.ml,v 1.11 2006/08/17 09:11:31 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
@@ -27,8 +27,8 @@ open Cocanwiki_strings
 type pt = Page of string | Title of string
 
 type section =
-    string option * string option * string option * string
-    (* (sectionname, divname, jsgo, content) *)
+    string option * string option * string option * string option * string
+    (* (sectionname, divname, divclass, jsgo, content) *)
 
 type model = {
   id : int32;                          (* Original page ID (0 = none). *)
@@ -63,7 +63,7 @@ let new_page pt =
 
 let new_page_with_title title =
   (* Initial page contents. *)
-  let contents = [ None, None, None, "<b>" ^ title ^ "</b> is " ] in
+  let contents = [ None, None, None, None, "<b>" ^ title ^ "</b> is " ] in
   let model = { id = 0l;
                pt = Title title;
                description = title;
@@ -94,7 +94,7 @@ let load_page dbh hostid ~url ?version () =
 
   (* Get the sections. *)
   let contents = PGSQL(dbh)
-    "select sectionname, divname, jsgo, content
+    "select sectionname, divname, divclass, jsgo, content
        from contents
       where pageid = $pageid
       order by ordering" in
@@ -154,13 +154,13 @@ let save_page r dbh hostid ?user model =
       (* Create the page contents. *)
       let ordering = ref 0 in  (* Creating new ordering. *)
       List.iter (
-       fun (sectionname, divname, jsgo, content) ->
+       fun (sectionname, divname, divclass, jsgo, content) ->
          incr ordering; let ordering = Int32.of_int !ordering in
          PGSQL(dbh)
            "insert into contents (pageid, ordering, sectionname, divname,
-                                   jsgo, content)
+                                   divclass, jsgo, content)
              values ($pageid, $ordering,
-                     $?sectionname, $?divname, $?jsgo, $content)"
+                     $?sectionname, $?divname, $?divclass, $?jsgo, $content)"
       ) model.contents_;
 
       url, pageid
@@ -238,12 +238,13 @@ let save_page r dbh hostid ?user model =
       (* Create the page contents. *)
       let ordering = ref 0 in  (* Creating new ordering. *)
       List.iter (
-       fun (sectionname, divname, jsgo, content) ->
+       fun (sectionname, divname, divclass, jsgo, content) ->
          incr ordering; let ordering = Int32.of_int !ordering in
          PGSQL(dbh) "insert into contents (pageid,
-                         ordering, sectionname, divname, jsgo, content)
+                         ordering, sectionname, divname, divclass,
+                         jsgo, content)
                       values ($pageid, $ordering, $?sectionname,
-                              $?divname, $?jsgo, $content)"
+                              $?divname, $?divclass, $?jsgo, $content)"
       ) model.contents_;
 
       url, pageid
index 9770874..6ec8efe 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: cocanwiki_pages.mli,v 1.7 2006/08/14 11:36:50 rich Exp $
+ * $Id: cocanwiki_pages.mli,v 1.8 2006/08/17 09:11:31 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
@@ -25,8 +25,8 @@ open Cocanwiki
 type pt = Page of string | Title of string
 
 type section =
-    string option * string option * string option * string
-    (* (sectionname, divname, jsgo, content) *)
+    string option * string option * string option * string option * string
+    (* (sectionname, divname, divclass, jsgo, content) *)
 
 type model = {
   id : int32;                          (* Original page ID (0 = none). *)
index 582f104..6f1d355 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: mail_import.ml,v 1.15 2006/08/16 15:27:02 rich Exp $
+ * $Id: mail_import.ml,v 1.16 2006/08/17 09:11:31 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
@@ -245,7 +245,7 @@ let run r (q : cgi) dbh hostid _ user =
 
       hdr_template#to_string
     in
-    None, Some "mail_header", None, content in
+    None, Some "mail_header", None, None, content in
 
   (* Create the second section (mail body).
    * XXX Very simple.  Should be extended to understand attachments and
@@ -330,7 +330,7 @@ let run r (q : cgi) dbh hostid _ user =
       with
          Not_found ->
            "No plain text message body found" in
-    Some "Message", Some "mail_body", None, content in
+    Some "Message", Some "mail_body", None, None, content in
 
   (* Overwrite the first two sections of the current page, regardless of
    * what they contain.
index fe2db74..2eaad4a 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: page.ml,v 1.57 2006/08/16 15:27:02 rich Exp $
+ * $Id: page.ml,v 1.58 2006/08/17 09:11:31 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
@@ -325,19 +325,33 @@ let run r (q : cgi) dbh hostid
          None -> []
        | Some pageid ->
            let rows = PGSQL(dbh)
-             "select ordering, sectionname, content, divname, jsgo
+             "select ordering, sectionname, content, divname, divclass, jsgo
                  from contents where pageid = $pageid order by ordering" in
 
            List.map
-             (fun (ordering, sectionname, content, divname, jsgo) ->
+             (fun (ordering, sectionname, content, divname, divclass, jsgo) ->
                 let divname, has_divname =
                   match divname with
                   | None -> "", false
                   | Some divname -> divname, true in
+                let divclass, has_divclass =
+                  match divclass with
+                  | None -> "", false
+                  | Some divclass -> divclass, true in
                 let jsgo, has_jsgo =
                   match jsgo with
                   | None -> "", false
                   | Some jsgo -> jsgo, true in
+
+                let has_divclass, divclass =
+                  if has_jsgo then
+                    (true,
+                     if divclass = "" then "jsgo_div"
+                     else divclass ^ " jsgo_div")
+                  else
+                    has_divclass, divclass in
+                let has_div = has_divname || has_divclass in
+
                 let sectionname, has_sectionname =
                   match sectionname with
                   | None -> "", false
@@ -353,6 +367,9 @@ let run r (q : cgi) dbh hostid
                       (Wikilib.xhtml_of_content r dbh hostid content);
                   "has_divname", Template.VarConditional has_divname;
                   "divname", Template.VarString divname;
+                  "has_divclass", Template.VarConditional has_divclass;
+                  "divclass", Template.VarString divclass;
+                  "has_div", Template.VarConditional has_div;
                   "has_jsgo", Template.VarConditional has_jsgo;
                   "jsgo", Template.VarString jsgo ]) rows in
 
@@ -369,6 +386,9 @@ let run r (q : cgi) dbh hostid
              "content", Template.VarString content;
              "has_divname", Template.VarConditional true;
              "divname", Template.VarString "form_div";
+             "has_divclass", Template.VarConditional false;
+             "divclass", Template.VarString "";
+             "has_div", Template.VarConditional true;
              "has_jsgo", Template.VarConditional false;
              "jsgo", Template.VarString "";
            ] in
index af88891..bb1e243 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: restore.ml,v 1.25 2006/08/14 11:36:50 rich Exp $
+ * $Id: restore.ml,v 1.26 2006/08/17 09:11:31 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
@@ -75,8 +75,10 @@ let run r (q : cgi) dbh hostid {hostname = hostname} user =
     let pageid = PGOCaml.serial4 dbh "pages_id_seq" in
 
     PGSQL(dbh) "insert into contents (pageid, ordering,
-                                      sectionname, content, divname, jsgo)
-                select $pageid, ordering, sectionname, content, divname, jsgo
+                                      sectionname, content, divname, divclass,
+                                      jsgo)
+                select $pageid, ordering, sectionname, content,
+                       divname, divclass, jsgo
                   from contents
                  where pageid = $version";
 
index 9bf5476..88be5da 100644 (file)
@@ -1,7 +1,7 @@
 (* COCANWIKI - a wiki written in Objective CAML.
  * Written by Richard W.M. Jones <rich@merjis.com>.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: source.ml,v 1.6 2006/07/26 13:41:37 rich Exp $
+ * $Id: source.ml,v 1.7 2006/08/17 09:11:31 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
@@ -84,12 +84,14 @@ let run r (q : cgi) dbh hostid _ _ =
   (* Now write out the sections. *)
   if model.redirect = None then
     List.iteri
-      (fun i (sectionname, divname, jsgo, content) ->
+      (fun i (sectionname, divname, divclass, jsgo, content) ->
         write "Section-Id" (string_of_int i);
         (match sectionname with None -> () | Some sectionname ->
            write "Section-Header" sectionname);
         (match divname with None -> () | Some divname ->
            write "Css-Id" divname);
+        (match divclass with None -> () | Some divclass ->
+           write "Css-Class" divclass);
         (match jsgo with None -> () | Some jsgo ->
            write "Javascript-Onclick" jsgo);
         write "Content" content;
index edbda5d..99b3ddc 100644 (file)
@@ -98,7 +98,9 @@ Redirect to:<br/>
 synch_update ('content_::ordering::', 'preview_::ordering::');
 init_edit_buttons ('edit_buttons_::ordering::', 'content_::ordering::', 'preview_::ordering::');
 //--></script>
-<abbr class="css_id" title="Assign a stylesheet ID to this block of text to enable further styling">CSS id</abbr>: <input class="css_id" name="divname_::ordering::" value="::divname_html_tag::" size="8"/> <abbr class="js_onclick" title="Assign a destination URL on the site where clicks in this whole region go to. (Requires Javascript)">Javascript onclick</abbr>: <input class="js_onclick" name="jsgo_::ordering::" value="::jsgo_html_tag::" size="16"/>
+<abbr class="css_id" title="Assign a stylesheet ID to this block of text to enable further styling">CSS id</abbr>: <input class="css_id" name="divname_::ordering::" value="::divname_html_tag::" size="8"/>
+<abbr class="css_id" title="Assign a stylesheet class to this block of text to enable further styling">CSS class</abbr>: <input class="css_class" name="divclass_::ordering::" value="::divclass_html_tag::" size="8"/>
+<abbr class="js_onclick" title="Assign a destination URL on the site where clicks in this whole region go to. (Requires Javascript)">Javascript onclick</abbr>: <input class="js_onclick" name="jsgo_::ordering::" value="::jsgo_html_tag::" size="16"/>
 
 <p class="insert">
 <input class="insert" type="submit" name="action_insert_::ordering::" value="Insert new section here"/>
index 5c3a24e..9304b75 100644 (file)
@@ -8,9 +8,9 @@
 ::end::
 </ul>
 </div>::end::<div id="content_div">
-::table(sections)::::if(has_divname)::<div id="::divname_html_tag::"::if(has_jsgo):: onclick="go('/::jsgo_html_tag::')" class="jsgo_div"::end::>::end::::if(can_edit)::<p class="edit_link">[<a href="/::page_html_tag::/edit#::ordering::" title="Edit this section">edit</a>]</p>::end::::if(has_sectionname)::<a name="::linkname_html_tag::"></a><h2><span>::sectionname_html::</span></h2>::end::
+::table(sections)::::if(has_div)::<div::if(has_divname):: id="::divname_html_tag::"::end::::if(has_divclass):: class="::divclass_html_tag::"::end::::if(has_jsgo):: onclick="go('/::jsgo_html_tag::')"::end::>::end::::if(can_edit)::<p class="edit_link">[<a href="/::page_html_tag::/edit#::ordering::" title="Edit this section">edit</a>]</p>::end::::if(has_sectionname)::<a name="::linkname_html_tag::"></a><h2><span>::sectionname_html::</span></h2>::end::
 ::content::
-::if(has_divname)::</div>::end::::end::
+::if(has_div)::</div>::end::::end::
 </div>
 
 <ul id="topmenu" class="menu">
index f303640..f4ea3e0 100644 (file)
@@ -1,6 +1,6 @@
 (* Copy a page from one host to another.  Note that this only copies
  * the text, not any images which may be present.
- * $Id: copy_page.ml,v 1.4 2006/08/14 11:36:50 rich Exp $
+ * $Id: copy_page.ml,v 1.5 2006/08/17 09:11:31 rich Exp $
  *
  * Usage: copy_page hostid url new_hostid new_url
  *)
@@ -32,8 +32,9 @@ let () =
 
   let sth = dbh#prepare_cached
     "insert into contents (pageid, ordering, sectionname, content,
-                           divname, jsgo)
-     select ? as pageid, ordering, sectionname, content, divname, jsgo
+                           divname, divclass, jsgo)
+     select ? as pageid, ordering, sectionname, content,
+            divname, divclass, jsgo
        from contents
       where pageid = ?" in
   sth#execute [`Int new_pageid; `Int old_pageid];