Code

- Add tests for Interval.pretty().
[roundup.git] / doc / customizing.txt
index 2662f62945040cf7be84d72c932336095b420b27..0136601910ec8a56f34d249378bd9c36dd0a9db6 100644 (file)
@@ -2,7 +2,7 @@
 Customising Roundup
 ===================
 
-:Version: $Revision: 1.100 $
+:Version: $Revision: 1.105 $
 
 .. This document borrows from the ZopeBook section on ZPT. The original is at:
    http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
@@ -16,7 +16,7 @@ What You Can Do
 Before you get too far, it's probably worth having a quick read of the Roundup
 `design documentation`_.
 
-Customisation of Roundup can take one of five forms:
+Customisation of Roundup can take one of six forms:
 
 1. `tracker configuration`_ file changes
 2. database, or `tracker schema`_ changes
@@ -301,6 +301,41 @@ of ``'setkey'``)::
         priority=Link("priority"))
     issue.setkey('title')
 
+
+What you can't do to the schema
+-------------------------------
+
+You must never:
+
+**Remove the users class**
+  This class is the only *required* class in Roundup. Similarly, its
+  username, password and address properties must never be removed.
+
+**Change the type of a property**
+  Property types must *never* be changed - the database simply doesn't take
+  this kind of action into account. Note that you can't just remove a
+  property and re-add it as a new type either. If you wanted to make the
+  assignedto property a Multilink, you'd need to create a new property
+  assignedto_list and remove the old assignedto property.
+
+
+What you can do to the schema
+-----------------------------
+
+Your schema may be changed at any time before or after the tracker has been
+initialised (or used). You may:
+
+**Add new properties to classes, or add whole new classes**
+  This is painless and easy to do - there are generally no repurcussions
+  from adding new information to a tracker's schema.
+
+**Remove properties**
+  Removing properties is a little more tricky - you need to make sure that
+  the property is no longer used in the `web interface`_ *or* by the
+  detectors_.
+
+
+
 Classes and Properties - creating a new information store
 ---------------------------------------------------------
 
@@ -988,7 +1023,7 @@ Two special form values are supported for backwards compatibility:
     This is equivalent to::
 
         @link@messages=msg-1
-        @msg-1@content=value
+        msg-1@content=value
 
     except that in addition, the "author" and "date" properties of
     "msg-1" are set to the userid of the submitter, and the current
@@ -998,7 +1033,7 @@ Two special form values are supported for backwards compatibility:
     This is equivalent to::
 
         @link@files=file-1
-        @file-1@content=value
+        file-1@content=value
 
     The String content value is handled as described above for file
     uploads.
@@ -1866,19 +1901,19 @@ template)::
 
  <table class="form">
  <tr>
-  <th nowrap>Title</th>
+  <th>Title</th>
   <td colspan="3" tal:content="structure python:context.title.field(size=60)">title</td>
  </tr>
  
  <tr>
-  <th nowrap>Priority</th>
+  <th>Priority</th>
   <td tal:content="structure context/priority/menu">priority</td>
-  <th nowrap>Status</th>
+  <th>Status</th>
   <td tal:content="structure context/status/menu">status</td>
  </tr>
  
  <tr>
-  <th nowrap>Superseder</th>
+  <th>Superseder</th>
   <td>
    <span tal:replace="structure python:context.superseder.field(showid=1, size=20)" />
    <span tal:replace="structure python:db.issue.classhelp('id,title')" />
@@ -1886,7 +1921,7 @@ template)::
     <br>View: <span tal:replace="structure python:context.superseder.link(showid=1)" />
    </span>
   </td>
-  <th nowrap>Nosy List</th>
+  <th>Nosy List</th>
   <td>
    <span tal:replace="structure context/nosy/field" />
    <span tal:replace="structure python:db.user.classhelp('username,realname,address,phone')" />
@@ -1894,7 +1929,7 @@ template)::
  </tr>
  
  <tr>
-  <th nowrap>Assigned To</th>
+  <th>Assigned To</th>
   <td tal:content="structure context/assignedto/menu">
    assignedto menu
   </td>
@@ -1903,14 +1938,14 @@ template)::
  </tr>
  
  <tr>
-  <th nowrap>Change Note</th>
+  <th>Change Note</th>
   <td colspan="3">
    <textarea name=":note" wrap="hard" rows="5" cols="60"></textarea>
   </td>
  </tr>
  
  <tr>
-  <th nowrap>File</th>
+  <th>File</th>
   <td colspan="3"><input type="file" name=":file" size="40"></td>
  </tr>
  
@@ -2341,7 +2376,7 @@ will be the "name" variable of the current context (which is
 to the form, a new category will be created with that name::
 
     <tr>
-     <th nowrap>Name</th>
+     <th>Name</th>
      <td tal:content="structure python:context.name.field(size=60)">
      name</td>
     </tr>
@@ -2373,19 +2408,20 @@ So putting it all together, and closing the table and form we get::
    <form method="POST" onSubmit="return submit_once()"
          enctype="multipart/form-data">
 
-    <input type="hidden" name="@required" value="name">
-
     <table class="form">
      <tr><th class="header" colspan="2">Category</th></tr>
 
      <tr>
-      <th nowrap>Name</th>
+      <th>Name</th>
       <td tal:content="structure python:context.name.field(size=60)">
       name</td>
      </tr>
 
      <tr>
-      <td>&nbsp;</td>
+      <td>
+        &nbsp;
+        <input type="hidden" name="@required" value="name"> 
+      </td>
       <td colspan="3" tal:content="structure context/submit">
        submit button will go here
       </td>
@@ -2414,7 +2450,7 @@ Just like ``category.issue.html`` this file defines a form which has a
 table to lay things out. It doesn't matter where in the table we add new
 stuff, it is entirely up to your sense of aesthetics::
 
-   <th nowrap>Category</th>
+   <th>Category</th>
    <td><span tal:replace="structure context/category/field" />
        <span tal:replace="structure db/category/classhelp" />
    </td>
@@ -2578,12 +2614,12 @@ issues to. You can do this by following these steps:
 4. in the ``issue.item.html`` template, change the status editing bit
    from::
 
-    <th nowrap>Status</th>
+    <th>Status</th>
     <td tal:content="structure context/status/menu">status</td>
 
    to::
 
-    <th nowrap>Status</th>
+    <th>Status</th>
     <td>
      <select tal:condition="context/id" name="status">
       <tal:block tal:define="ok context/status/transitions"
@@ -2613,7 +2649,7 @@ Alter the issue.item template section for messages to::
    <td><a tal:attributes="href string:msg${msg/id}"
           tal:content="string:msg${msg/id}"></a></td>
    <td tal:content="msg/author">author</td>
-   <td nowrap tal:content="msg/date/pretty">date</td>
+   <td class="date" tal:content="msg/date/pretty">date</td>
    <td tal:content="msg/summary">summary</td>
    <td>
     <a tal:attributes="href string:?@remove@messages=${msg/id}&@action=edit">
@@ -2720,11 +2756,11 @@ Setting up a "wizard" (or "druid") for controlled adding of issues
 
     <tal:block tal:condition="python:cat in '6 10 13 14 15 16 17'.split()">
      <tr>
-      <th nowrap>Operating System</th>
+      <th>Operating System</th>
       <td tal:content="structure context/os/field"></td>
      </tr>
      <tr>
-      <th nowrap>Web Browser</th>
+      <th>Web Browser</th>
       <td tal:content="structure context/browser/field"></td>
      </tr>
     </tal:block>
@@ -2931,7 +2967,7 @@ be able to give a summary of the total time spent on a particular issue.
    field to capture a new timelog item's perdiod::
 
     <tr> 
-     <th nowrap>Time Log</th> 
+     <th>Time Log</th> 
      <td colspan=3><input type="text" name="timelog-1@period" /> 
       <br />(enter as '3y 1m 4d 2:40:02' or parts thereof) 
      </td> 
@@ -3189,7 +3225,7 @@ that shows either one or the other. We'll use a new form variable,
     <td><a tal:attributes="href string:msg${msg/id}"
            tal:content="string:msg${msg/id}"></a></td>
     <td tal:content="msg/author">author</td>
-    <td nowrap tal:content="msg/date/pretty">date</td>
+    <td class="date" tal:content="msg/date/pretty">date</td>
     <td tal:content="msg/summary">summary</td>
     <td>
      <a tal:attributes="href string:?@remove@messages=${msg/id}&@action=edit">remove</a>
@@ -3206,7 +3242,7 @@ that shows either one or the other. We'll use a new form variable,
    <tal:block tal:repeat="msg context/messages">
     <tr>
      <th tal:content="msg/author">author</th>
-     <th nowrap tal:content="msg/date/pretty">date</th>
+     <th class="date" tal:content="msg/date/pretty">date</th>
      <th style="text-align: right">
       (<a tal:attributes="href string:?@remove@messages=${msg/id}&@action=edit">remove</a>)
      </th>
@@ -3242,7 +3278,7 @@ resolved. To achieve this:
 2. Add the new "blockers" property to the issue.item edit page, using
    something like::
 
-    <th nowrap>Waiting On</th>
+    <th>Waiting On</th>
     <td>
      <span tal:replace="structure python:context.blockers.field(showid=1,
                                   size=20)" />