comparison doc/index.html @ 653:1dcbee29faa7

More work on the documentation - rolled in the work done by Jeff Blaine. Use build_html.py *.stx to build the HTML. We'll move that into the setup script when someone figures how to :)
author Richard Jones <richard@users.sourceforge.net>
date Fri, 08 Mar 2002 23:41:46 +0000
parents f98f37697f4c
children
comparison
equal deleted inserted replaced
652:66b324f895d1 653:1dcbee29faa7
1 <html><head> 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 <title>Roundup: an Issue-Tracking System for Knowledge Workers</title> 2 "http://www.w3.org/TR/html4/loose.dtd">
3 </head><body> 3 <HTML LANG="en">
4 4 <HEAD>
5 <h1 align=center>Roundup (0.3.1)</h1> 5 <LINK REL="StyleSheet" HREF="default.css" TYPE="text/css"></HEAD>
6 <h3 align=center>An Issue-Tracking System for Knowledge Workers</h2> 6 <BODY>
7 7 <DIV CLASS="document">
8 <h1>Contents</h1> 8 <P><EM>Roundup: an Issue-Tracking System for Knowledge Workers</EM></P>
9 9 <DIV CLASS="section" ID="id1">
10 <ul> 10 <H1>Contents</H1>
11 <li><a href="overview.html">Overview</a> (Initial submission to SC Track) 11 <UL>
12 <li><a href="#installation">Installation</a> 12 <LI>
13 <ul> 13 <P><A CLASS="reference" HREF="overview.html">Overview</A></P>
14 <li><a href="#requires">Prerequisites</a> 14 </LI>
15 <li><a href="#getting">Getting Roundup</a> 15 <LI>
16 <li><a href="#installing">Installing Roundup</a> 16 <P><A CLASS="reference" HREF="installation.html">Installation</A></P>
17 </ul> 17 </LI>
18 <li><a href="#starting">Getting Started</a> 18 <LI>
19 <ul> 19 <P><A CLASS="reference" HREF="getting_started.html">Getting Started</A></P>
20 <li><a href="#instance">The Instance</a> 20 </LI>
21 <li><a href="#startcmd">Command Line Tool</a> 21 <LI>
22 <li><a href="#startmail">E-Mail Interface</a> 22 <P><A CLASS="reference" HREF="user_guide.html">User Guide</A></P>
23 <li><a href="#startweb">Web Interface</a> 23 </LI>
24 <li><a href="#users">Users and Access Control</a> (Users and permissions, Adding users) 24 <LI>
25 <li><a href="#issues">Issues</a> 25 <P><A CLASS="reference" HREF="customizing.html">Customising Roundup</A></P>
26 </ul> 26 </LI>
27 <li><a href="#guide">User Guide</a> 27 <LI>
28 <ul> 28 <P><A CLASS="reference" HREF="spec.html">Roundup's Design Document</A></P>
29 <li><a href="#cmd">Command Line Tool</a> 29 </LI>
30 <li><a href="#web">Web Interface</a> 30 </UL>
31 <li><a href="#mail">E-Mail Gateway</a> (Message content summary, Address handling, Performing Actions) 31 </A></A></A></A></A></A></DIV>
32 </ul> 32 <DIV CLASS="section" ID="id8">
33 <li><a href="#custom">Customising Roundup</a> 33 <H1>Acknowledgements</H1>
34 <ul> 34 <P>Go Ping, you rock! Also, go Bizar Software and ekit.com for letting me
35 <li><a href="#config">Instance Configuration</a> 35 implement this system on their time.</P>
36 <li><a href="#custinst">Instance Schema</a> (Creating a new information store) 36 <P>Thanks also to the many people on the mailing list and in the sourceforge
37 <li><a href="#custweb">Web Interface</a> (Displaying properties, Index views, Item views) 37 project: Anthony Baxter, Juergen Hermann, Roch'e Compaan, Engelbert Gruber,
38 </ul> 38 Titus Brown, Jeff Blaine and Patrick Ohly.</P>
39 <li><a href="spec.html">Roundup's Design Document</a> ("Implementation Guide") 39 </DIV>
40 <li><a href="#ack">Acknowledgements</a> 40 </DIV>
41 </ul> 41 </BODY>
42 42 </HTML>
43 <p><hr>
44 <h1><a name="installation">Installation</a></h1>
45
46
47 <h2><a name="requires">Prerequisites</a></h2>
48
49 <p>
50 Python 2.1.1 is required for the correct operation of roundup.
51 </p>
52
53 <p>
54 Download the latest version from
55 <a href="http://www.python.org/">http://www.python.org/</a>.
56 </p>
57
58
59
60 <h2><a name="getting">Getting Roundup</a></h2>
61
62 Download the latest version from
63 <a href="http://roundup.sf.net/">http://roundup.sf.net/</a>.
64
65
66 <h2><a name="installing">Installing Roundup</a></h2>
67
68 <ol>
69 <li>Run:
70 <br><tt>python setup.py install</tt>
71 <li>If you would prefer the scripts installed in somewhere other than
72 <tt>/usr/local/bin</tt>, add <tt>"--install-scripts=&lt;dir&gt;"</tt>
73 to the command:
74 <br><tt>python setup.py install --install-scripts=&lt;dir&gt;</tt>
75 <li>The command:
76 <br><tt>python setup.py install --help</tt>
77 <br>gives all the options available for installation.
78 </ol>
79
80
81 <p><hr>
82 <h1><a name="starting">Getting Started</a></h1>
83
84 The following instructions assume that you have installed roundup. If you
85 haven't, you may still proceed - just preface all commands with "./"
86 ie. "./roundup-admin init".
87
88
89 <h2><a name="instance">The Instance</a></h2>
90
91 We'll be referring to the term <em>instance</em> a lot from now on. An
92 instance is
93 a directory in your filesystem that is where all the information about a
94 live issue tracker database is stored. The data that is entered as issues,
95 the users who access the database and the definition of the database itself
96 all reside there:
97 <ol>
98 <li><strong>Hyperdatabase</strong>
99 <br>This is the lowest component of Roundup and is where all the
100 issues, users, file attachments and messages are stored.
101 <li><strong>Database schema</strong>
102 <br>This describes the content of the hyperdatabase - what fields are
103 stored for issues, what user information, etc. Being stored in the
104 instance, this allows it to be customised for a particular application.
105 It also means that changes in the Roundup core code do not affect a
106 running instance.
107 <li><strong>Web Interface</strong>
108 <br>The web interface templates are defined in the instance too - and
109 the actual CGI interface class is defined (mostly using base classes in
110 the Roundup core code) so it, like the database, may be customised for
111 each instance in use.
112 </ol>
113
114 Instances are created using the <tt>roundup-admin</tt> tool.
115
116 <h2><a name="startcmd">Command Line Tool</a></h2>
117
118 To initiliase a new instance, run <tt>roundup-admin init</tt>. You will be
119 asked a series of questions:
120
121 <ol>
122 <li>Instance home directory
123 <li>Schema to use
124 <li>Database back-end to use
125 <li>Administration user "admin" password.
126 </ol>
127
128 You should also think about whether there is going to be controlled access
129 to the instance on the machine the instance is running on. That is, who can
130 actually make changes to the database using the roundup-admin tool. See
131 the section on <a href="#users">Users and Access Control</a> for
132 information on how to secure your instance from the start.
133
134 <p>
135
136 Roundup is configurable using an instance_config.py file in the instance home.
137 It should be edited before roundup is used, and may have the following
138 variable declarations:
139
140 <ol>
141 <li>MAILHOST
142 <br>The SMTP mail host that roundup will use to send mail
143 <li>MAIL_DOMAIN
144 <br>The domain name used for email addresses
145 <li>ISSUE_TRACKER_WEB
146 <br>The web address of the issue tracker's web interface
147 </ol>
148
149 <p>
150 The email addresses used by the system by default are:
151
152 <ol>
153 <li>ISSUE_TRACKER_EMAIL - issue_tracker@MAIL_DOMAIN
154 <br>submissions of issues
155 <li>ADMIN_EMAIL - roundup-admin@MAIL_DOMAIN
156 <br>roundup's internal use (problems, etc)
157 </ol>
158
159 <h2><a name="startmail">E-Mail Interface</a></h2>
160
161 <h3>Setup 1: As a mail alias pipe process</h3>
162 Set up a mail alias called "issue_tracker" as (include the quote marks):
163 <blockquote>
164 <tt>"|/usr/bin/python /usr/local/bin/roundup-mailgw &lt;instance_home&gt;"</tt>
165 </blockquote>
166
167 In some installations (e.g. RedHat 6.2 I think) you'll need to set up smrsh
168 so sendmail will accept the pipe command. In that case, symlink
169 /etc/smrsh/roundup-mailgw to /usr/local/bin/roundup-mailgw and change the
170 command to:
171 <blockquote>
172 <tt>|roundup-mailgw &lt;instance_home&gt;</tt>
173 </blockquote>
174
175 To test the mail gateway on unix systems, try:
176
177 <blockquote>
178 <tt>echo test |mail -s '[issue] test' issue_tracker@your.domain</tt>
179 </blockquote>
180
181
182 <h3>Setup 2: As a regular cron job using a mailbox source</h3>
183 Set the roundup-mailgw up to run every 10 minutes or so. For example:
184 <blockquote>
185 <tt>10 * * * * /usr/local/bin/roundup-mailgw &lt;instance_home&gt; mailbox &lt;mail_spool_file&gt;</tt>
186 </blockquote>
187 Where the mail_spool_file argument is the location of the roundup
188 submission user's mail spool. On most systems, the spool for a user
189 "issue_tracker" will be "/var/mail/issue_tracker".
190
191 <h3>Setup 3: As a regular cron job using a POP source</h3>
192 To retrieve from a POP mailbox, use a similar cron entry to the mailbox
193 one:
194 <blockquote>
195 <tt>10 * * * * /usr/local/bin/roundup-mailgw &lt;instance_home&gt; pop &lt;pop_spec&gt;</tt>
196 </blockquote>
197 where pop_spec is "username:password@server" that specifies the roundup
198 submission user's POP account name, password and server.
199
200 <h2><a name="startweb">Web Interface</a></h2>
201 This software will work through apache or stand-alone.
202 <p>
203 <strong>Stand-alone:</strong>
204 <ol>
205 <li>Edit roundup-server at the top - ROUNDUP_INSTANCE_HOMES needs to know
206 about your instance. You may also specify the values for
207 ROUNDUP_INSTANCE_HOMES on the command-line using "name=home" pairs.
208 <li><tt>roundup-server [hostname port]</tt> (hostname may be "")
209 <li>Load up the page <tt>/&lt;instance name&gt;/index</tt> where
210 instance name is the
211 name you nominated in <tt>ROUNDUP_INSTANCE_HOMES</tt>.
212 </ol>
213
214 <strong>Apache:</strong>
215 <ol>
216 <li>The CGI script is found in the cgi-bin directory of the roundup
217 distribution.
218 </li>
219 <li>Make sure roundup.cgi is executable. Edit it at the top -
220 ROUNDUP_INSTANCE_HOMES needs to know about your instance.
221 </li>
222 <li>Edit your /etc/httpd/conf/httpd.conf and make sure that the
223 /home/httpd/html/roundup/roundup.cgi script will be treated as a CGI
224 script.
225 </li>
226 <li>Re-start your apache to re-load the config if necessary.
227 </li>
228 <li>Load up the page "/roundup/roundup.cgi/<instance name>/index" where
229 instance name is the name you nominated in ROUNDUP_INSTANCE_HOMES.
230 </li>
231 <li>To use the CGI script unchanged, which allows much easier updates,
232 add these directives to your "httpd.conf":
233 <pre>
234 SetEnv ROUNDUP_LOG "/var/log/roundup.log"
235 SetEnv ROUNDUP_INSTANCE_HOMES "Default=/usr/local/share/roundup/instances/Default"
236 SetEnv ROUNDUP_DEBUG "0"
237 </pre>
238 </li>
239 <li>On Windows, write a batch file "roundup.bat" similar to the one below
240 and place it into your cgi-bin directory:
241 <pre>
242 @echo off
243 set ROUNDUP_LOG=c:\Python21\share\roundup\cgi.log
244 set ROUNDUP_INSTANCE_HOMES=Default=c:\Python21\share\roundup\instances\Default;
245 set ROUNDUP_DEBUG=0
246 c:\Python21\python.exe c:\Python21\share\roundup\cgi-bin\roundup.cgi
247 </pre>
248 </li>
249 </ol>
250
251
252
253
254 <h2><a name="users">Users</a></h2>
255
256 <h3>Users and permissions</h3>
257 By default, roundup automatically creates one user when the instance
258 database is initialised (using roundup-admin init). The user is "admin" and
259 the password is the one you supply at that time.
260 <p>
261 If users attempt to use roundup in any manner and are not identified to
262 roundup, they will be using the database in a read-only mode. That is, if
263 roundup doesn't know who they are, they can't change anything. This has the
264 following repurcussions:
265 <dl>
266 <dt><strong>Command-line interface</strong>
267 <dd>The data modification commands (create, init, retire, set) are
268 performed as the "admin" user. It is therefore important that the database
269 be protected by the filesystem if protection is required. On a Unix system,
270 the easiest and most flexible method of doing so is:
271 <ol>
272 <li>Add a new user and group to your system (e.g. "issue_tracker")
273 <li>When creating a new instance home, use the following commands
274 (substituting instance_home for the directory you want to use):<br>
275 <pre>
276 mkdir instance_home
277 chown issue_tracker:issue_tracker instance_home
278 chmod g+rwxs instance_home
279 roundup-admin -i instance_home init
280 </pre>
281 <li>Now, edit the /etc/group line for the issue_tracker group so it includes
282 the unix logins of all the users who are going to administer your roundup
283 instance. If you're running the web or mail gateways, then be sure to
284 include those users in the group too (on some Linux systems, these
285 users are "www" or "apache" and "mail".)
286 </ol>
287
288 <dt><strong>E-Mail interface</strong>
289 <dd>Users are identified by e-mail address - a new user entry will be
290 created for any e-mail address that is not recognised, so users are
291 <em>always</em> identified by roundup.
292 <dt><strong>Web interface</strong>
293 <dd>Unidentified users have read-only access. If the users database has an
294 entry with the username "anonymous", then unidentified users are
295 automatically logged in as that user. This gives them write access.
296 </dl>
297 <p>
298 *** anonymous access and the ANONYMOUS_* configuratins.
299
300 <h3>Adding users</h3>
301 To add users, use one of the following interfaces:
302
303 <ol>
304 <li>On the web, access the URL <tt>.../&lt;instance name&gt;/newuser</tt>
305 to bring up a form which may be used to add a new user.
306 <li>On the command-line, use:
307 <br><tt>roundup-admin -i &lt;instance home&gt; create user
308 username=bozo password=bozo address=richard@clown.org</tt>
309 <br>Supply the admin username and password. roundup-admin will print the
310 id of the new user.
311 <li>Any e-mail sent to roundup from an address that doesn't match an
312 existing user in the database will result in a new user entry being
313 created for that user.
314 </ol>
315
316
317
318 <h2><a name="issues">Issues</a></h2>
319 To add issues, use one of the following interfaces:
320
321 <ol>
322 <li>On the web, access the URL <tt>.../&lt;instance name&gt;/newissue</tt>
323 to bring up a form which may be used to add a new issue.
324 <li>On the command-line, use:
325 <br><tt>roundup-admin -i &lt;instance home&gt; create issue
326 title="test issue"</tt>
327 <br>Supply the admin username and password. roundup-admin will print the
328 id of the new issue.
329 <li>Any e-mail sent to roundup with the subject line containing [issue]
330 will automatically created a new issue in the database using the
331 contents of the e-mail.
332 </ol>
333
334 <p><hr>
335 <h1><a name="guide">User Guide</a></h1>
336 <h2><a name="cmd">Command Line Tool</a></h2>
337
338 Usage:
339 <tt>roundup-admin [-i instance home] [-u login] [-c] &lt;command&gt;
340 &lt;arguments&gt;</tt>
341
342 <p>
343 <table><tr><th colspan=2>Options:</th></tr>
344 <tr><td>-i instance home </td><td>specify the issue tracker "home directory" to administer
345 </td></tr>
346 <tr><td>-u </td><td>the user[:password] to use for commands
347 </td></tr>
348 <tr><td>-c </td><td>when outputting lists of data, just comma-separate them
349 </td></tr>
350 </table>
351
352 <p>
353 <table width=100% border=1 cellspacing=0>
354 <tr><th colspan=2>Command Help</th></tr>
355
356
357 <tr><td valign=top><strong>commit</strong></td>
358 <td><tt>Usage: commit</tt><p>
359 <pre>
360 The changes made during an interactive session are not
361 automatically written to the database - they must be committed
362 using this command.
363
364 One-off commands on the command-line are automatically committed if
365 they are successful.
366
367 </pre></td></tr>
368
369
370 <tr><td valign=top><strong>create</strong></td>
371 <td><tt>Usage: create classname property=value ...</tt><p>
372 <pre>
373 This creates a new entry of the given class using the property
374 name=value arguments provided on the command line after the "create"
375 command.
376
377 </pre></td></tr>
378
379
380 <tr><td valign=top><strong>display</strong></td>
381 <td><tt>Usage: display designator</tt><p>
382 <pre>
383 This lists the properties and their associated values for the given
384 node.
385
386 </pre></td></tr>
387
388
389 <tr><td valign=top><strong>export</strong></td>
390 <td><tt>Usage: export class[,class] destination_dir</tt><p>
391 <pre>
392 This action exports the current data from the database into
393 tab-separated-value files that are placed in the nominated destination
394 directory. The journals are not exported.
395
396 </pre></td></tr>
397
398
399 <tr><td valign=top><strong>find</strong></td>
400 <td><tt>Usage: find classname propname=value ...</tt><p>
401 <pre>
402 Find the nodes of the given class with a given link property value. The
403 value may be either the nodeid of the linked node, or its key value.
404
405 </pre></td></tr>
406
407
408 <tr><td valign=top><strong>get</strong></td>
409 <td><tt>Usage: get property designator[,designator]*</tt><p>
410 <pre>
411 Retrieves the property value of the nodes specified by the designators.
412
413 </pre></td></tr>
414
415
416 <tr><td valign=top><strong>help</strong></td>
417 <td><tt>Usage: help topic</tt><p>
418 <pre>
419 commands -- list commands
420 <command> -- help specific to a command
421 initopts -- init command options
422 all -- all available help
423
424 </pre></td></tr>
425
426
427 <tr><td valign=top><strong>history</strong></td>
428 <td><tt>Usage: history designator</tt><p>
429 <pre>
430 Lists the journal entries for the node identified by the designator.
431
432 </pre></td></tr>
433
434
435 <tr><td valign=top><strong>import</strong></td>
436 <td><tt>Usage: import class file</tt><p>
437 <pre>
438 The file must define the same properties as the class (including having
439 a "header" line with those property names.) The new nodes are added to
440 the existing database - if you want to create a new database using the
441 imported data, then create a new database (or, tediously, retire all
442 the old data.)
443
444 </pre></td></tr>
445
446
447 <tr><td valign=top><strong>initialise</strong></td>
448 <td><tt>Usage: initialise [template [backend [admin password]]]</tt><p>
449 <pre>
450 The command will prompt for the instance home directory (if not supplied
451 through INSTANCE_HOME or the -i option. The template, backend and admin
452 password may be specified on the command-line as arguments, in that
453 order.
454
455 See also initopts help.
456
457 </pre></td></tr>
458
459
460 <tr><td valign=top><strong>list</strong></td>
461 <td><tt>Usage: list classname [property]</tt><p>
462 <pre>
463 Lists all instances of the given class. If the property is not
464 specified, the "label" property is used. The label property is tried
465 in order: the key, "name", "title" and then the first property,
466 alphabetically.
467
468 </pre></td></tr>
469
470
471 <tr><td valign=top><strong>retire</strong></td>
472 <td><tt>Usage: retire designator[,designator]*</tt><p>
473 <pre>
474 This action indicates that a particular node is not to be retrieved by
475 the list or find commands, and its key value may be re-used.
476
477 </pre></td></tr>
478
479
480 <tr><td valign=top><strong>rollback</strong></td>
481 <td><tt>Usage: rollback</tt><p>
482 <pre>
483 The changes made during an interactive session are not
484 automatically written to the database - they must be committed
485 manually. This command undoes all those changes, so a commit
486 immediately after would make no changes to the database.
487
488 </pre></td></tr>
489
490
491 <tr><td valign=top><strong>set</strong></td>
492 <td><tt>Usage: set designator[,designator]* propname=value ...</tt><p>
493 <pre>
494 Sets the property to the value for all designators given.
495
496 </pre></td></tr>
497
498
499 <tr><td valign=top><strong>specification</strong></td>
500 <td><tt>Usage: specification classname</tt><p>
501 <pre>
502 This lists the properties for a given class.
503
504 </pre></td></tr>
505
506
507 <tr><td valign=top><strong>table</strong></td>
508 <td><tt>Usage: table classname [property[,property]*]</tt><p>
509 <pre>
510 Lists all instances of the given class. If the properties are not
511 specified, all properties are displayed. By default, the column widths
512 are the width of the property names. The width may be explicitly defined
513 by defining the property as "name:width". For example::
514 roundup> table priority id,name:10
515 Id Name
516 1 fatal-bug
517 2 bug
518 3 usability
519 4 feature
520
521 </pre></td></tr>
522
523 </table>
524
525 <p>
526 All commands (except help) require an instance specifier. This is just the path
527 to the roundup instance you're working with. A roundup instance is where
528 roundup keeps the database and configuration file that defines an issue
529 tracker. It may be thought of as the issue tracker's "home directory". It may
530 be specified in the environment variable ROUNDUP_INSTANCE or on the command
531 line as "-i instance".
532
533 <p>
534 A designator is a classname and a nodeid concatenated, eg. bug1, user10, ...
535
536 <p>
537 Property values are represented as strings in command arguments and in the
538 printed results:
539 <ul>
540 <li>Strings are, well, strings.
541 <li>Password values will display as their encoded value.
542 <li>Date values are printed in the full date format in the local time zone, and
543 accepted in the full format or any of the partial formats explained below.
544 <table>
545 <tr><th>Input of...</th><th>Means...</th></tr>
546 <tr><td>"2000-04-17.03:45"</td><td>2000-04-17.08:45:00</td></tr>
547 <tr><td>"2000-04-17"</td><td>2000-04-17.00:00:00</td></tr>
548 <tr><td>"01-25"</td><td>yyyy-01-25.00:00:00</td></tr>
549 <tr><td>"08-13.22:13"</td><td>yyyy-08-14.03:13:00</td></tr>
550 <tr><td>"11-07.09:32:43"</td><td>yyyy-11-07.14:32:43</td></tr>
551 <tr><td>"14:25"</td><td>yyyy-mm-dd.19:25:00</td></tr>
552 <tr><td>"8:47:11"</td><td>yyyy-mm-dd.13:47:11</td></tr>
553 <tr><td>"."</td><td>"right now"</td></tr>
554 </table>
555 <li>Link values are printed as node designators. When given as an argument,
556 node designators and key strings are both accepted.
557 <li>Multilink values are printed as lists of node designators joined by commas.
558 When given as an argument, node designators and key strings are both
559 accepted; an empty string, a single node, or a list of nodes joined by
560 commas is accepted.
561 </ul>
562 When multiple nodes are specified to the roundup get or roundup set
563 commands, the specified properties are retrieved or set on all the listed
564 nodes.
565 <p>
566 When multiple results are returned by the roundup get or roundup find
567 commands, they are printed one per line (default) or joined by commas (with
568 the -c) option.
569 <p>
570 Where the command changes data, a login name/password is required. The
571 login may be specified as either "name" or "name:password".
572 <ul>
573 <li>ROUNDUP_LOGIN environment variable
574 <li>the -u command-line option
575 </ul>
576 If either the name or password is not supplied, they are obtained from the
577 command-line.
578
579 <h2><a name="web">Web Interface</a></h2>
580 Index views may be modified by the following arguments:
581 <pre>
582 :sort - sort by prop name, optionally preceeded with '-'
583 to give descending or nothing for ascending sorting.
584 :group - group by prop name, optionally preceeded with '-' or
585 to sort in descending or nothing for ascending order.
586 :filter - selects which props should be displayed in the filter
587 section. Default is all.
588 :columns - selects the columns that should be displayed.
589 Default is all.
590 propname - selects the values the node properties given by propname
591 must have (very basic search/filter).
592 </pre>
593
594 <strong>Not sure what to put in here...</strong>
595
596 <h2><a name="mail">E-Mail Gateway</a></h2>
597
598 <h3>Performing Actions</h3>
599 The subject line of the incoming message is examined to determine whether
600 the message is an attempt to create a new item or to discuss an existing
601 item. A designator enclosed in square brackets is sought as the first thing
602 on the subject line (after skipping any "Fwd:" or "Re:" prefixes).
603 <p>
604 If an item designator (class name and id number) is found there, the newly
605 created "msg" node is added to the "messages" property for that item, and
606 any new "file" nodes are added to the "files" property for the item.
607 <p>
608 If just an item class name is found there, we attempt to create a new item
609 of that class with its "messages" property initialized to contain the new
610 "msg" node and its "files" property initialized to contain any new "file"
611 nodes.
612
613 <h3>Setting Properties</h3>
614 The e-mail interface also provides a simple way to set
615 properties on items. At the end of the subject line,
616 <em>propname</em><tt>=</tt><em>value</em> pairs can be
617 specified in square brackets, using the same conventions
618 as for the <tt>roundup&nbsp;set</tt> shell command.
619 explanatory message given in the exception.
620
621 <h3>Message content</h3>
622 Incoming messages are examined for multiple parts:
623 <ul>
624 <li>In a multipart/mixed message or part, each subpart is extracted and
625 examined. The text/plain subparts are assembled to form the textual
626 body of the message, to be stored in the file associated with a "msg"
627 class node. Any parts of other types are each stored in separate files
628 and given "file" class nodes that are linked to the "msg" node.
629 <li>In a multipart/alternative message or part, we look for a text/plain
630 subpart and ignore the other parts.
631 </ul>
632
633 <h4>Message summary</h4>
634 The "summary" property on message nodes is taken from the first non-quoting
635 section in the message body. The message body is divided into sections by
636 blank lines. Sections where the second and all subsequent lines begin with
637 a "&gt;" or "|" character are considered "quoting sections". The first line of
638 the first non-quoting section becomes the summary of the message.
639
640 <h3>Address handling</h3>
641 All of the addresses in the To: and Cc: headers of the incoming message are
642 looked up among the user nodes, and the corresponding users are placed in
643 the "recipients" property on the new "msg" node. The address in the From:
644 header similarly determines the "author" property of the new "msg"
645 node. The default handling for addresses that don't have corresponding
646 users is to create new users with no passwords and a username equal to the
647 address. (The web interface does not permit logins for users with no
648 passwords.) If we prefer to reject mail from outside sources, we can simply
649 register an auditor on the "user" class that prevents the creation of user
650 nodes with no passwords.
651
652 <h3>Triggers</h3>
653 Both cases may trigger detectors (in the first case we are calling the
654 set() method to add the message to the item's spool; in the second case we
655 are calling the create() method to create a new node). If an auditor raises
656 an exception, the original message is bounced back to the sender with the
657
658 <h4>Nosy Lists</h4>
659 A standard detector is provided that watches for additions
660 to the "messages" property. When a new message is added, the
661 detector sends it to all the users on the "nosy" list for the
662 item that are not already on the "recipients" list of the
663 message. Those users are then appended to the "recipients"
664 property on the message, so multiple copies of a message
665 are never sent to the same user. The journal recorded by
666 the hyperdatabase on the "recipients" property then provides
667 a log of when the message was sent to whom.
668
669 <p><hr>
670 <h1><a name="custom">Customising Roundup</a></h1>
671
672 Instances have the following structure:
673 <table>
674 <tr><td valign=top><strong>instance_config.py</strong></td>
675 <td>Holds the basic <a href="#config">instance configuration</a></td></tr>
676 <tr><td valign=top><strong>dbinit.py</strong></td>
677 <td>Holds the <a href="#custinst">instance schema</a></td></tr>
678 <tr><td valign=top><strong>interfaces.py</strong></td>
679 <td>Defines the <a href="#custweb">Web</a> and E-Mail interfaces for the instance</td></tr>
680 <tr><td valign=top><strong>select_db.py</strong></td>
681 <td>Selects the database back-end for the instance</td></tr>
682 <tr><td valign=top><strong>db/</strong></td>
683 <td>Holds the instance's database</td></tr>
684 <tr><td valign=top><strong>db/files/</strong></td>
685 <td>Holds the instance's upload files and messages</td></tr>
686 <tr><td valign=top><strong>detectors/</strong></td>
687 <td>Auditors and reactors for this instance</td></tr>
688 <tr><td valign=top><strong>html/</strong></td>
689 <td>Web interface <a href="#custweb">templates</a>, images and style sheets</td></tr>
690 </table>
691
692 <h2><a name="config">Instance Configuration</a></h2>
693 The <tt>instance_config.py</tt> located in your instance home contains the
694 basic configuration for the web and e-mail components of roundup's
695 interfaces. This file is a Python module. The default
696 <tt>instance_config.py</tt> is given below - as you can see, the
697 MAIL_DOMAIN must be edited before any interaction with the instance is
698 attempted.
699
700 <p>
701 <pre>
702 MAIL_DOMAIN=MAILHOST=HTTP_HOST=None
703 HTTP_PORT=0
704
705 # roundup home is this package's directory
706 INSTANCE_HOME=os.path.split(__file__)[0]
707
708 # The SMTP mail host that roundup will use to send mail
709 if not MAILHOST:
710 MAILHOST = 'localhost'
711
712 # The domain name used for email addresses.
713 if not MAIL_DOMAIN:
714 MAIL_DOMAIN = 'fill.me.in.'
715
716 # the next two are only used for the standalone HTTP server.
717 if not HTTP_HOST:
718 HTTP_HOST = ''
719 if not HTTP_PORT:
720 HTTP_PORT = 9080
721
722 # This is the directory that the database is going to be stored in
723 DATABASE = os.path.join(INSTANCE_HOME, 'db')
724
725 # This is the directory that the HTML templates reside in
726 TEMPLATES = os.path.join(INSTANCE_HOME, 'html')
727
728 # The email address that mail to roundup should go to
729 ISSUE_TRACKER_EMAIL = 'issue_tracker@%s'%MAIL_DOMAIN
730
731 # The web address that the instance is viewable at
732 ISSUE_TRACKER_WEB = 'http://some.useful.url/'
733
734 # The email address that roundup will complain to if it runs into trouble
735 ADMIN_EMAIL = 'roundup-admin@%s'%MAIL_DOMAIN
736
737 # Somewhere for roundup to log stuff internally sent to stdout or stderr
738 LOG = os.path.join(INSTANCE_HOME, 'roundup.log')
739
740 # Where to place the web filtering HTML on the index page
741 FILTER_POSITION = 'bottom' # one of 'top', 'bottom', 'top and bottom'
742
743 # Deny or allow anonymous access to the web interface
744 ANONYMOUS_ACCESS = 'deny'
745
746 # Deny or allow anonymous users to register through the web interface
747 ANONYMOUS_REGISTER = 'deny'
748
749 # Send nosy messages to the author of the message
750 MESSAGES_TO_AUTHOR = 'no' # either 'yes' or 'no'
751 </pre>
752
753 <h2><a name="custinst">Instance Schema</a></h2>
754 <b>Note:</b> if you modify the schema, you'll most likely need to
755 <a href="#schemarepurcussions">
756 web interface to reflect your changes</a>.
757 <p>
758 An instance schema defines what data is stored in the instance's database.
759 The two schemas shipped with Roundup turn it into a typical software bug
760 tracker (the extended schema allowing for support issues as well as bugs).
761 Schemas are defined using Python code. The "classic" schema looks like
762 this:
763 <p>
764 <pre>
765 pri = Class(db, "priority", name=String(), order=String())
766 pri.setkey("name")
767 pri.create(name="critical", order="1")
768 pri.create(name="urgent", order="2")
769 pri.create(name="bug", order="3")
770 pri.create(name="feature", order="4")
771 pri.create(name="wish", order="5")
772
773 stat = Class(db, "status", name=String(), order=String())
774 stat.setkey("name")
775 stat.create(name="unread", order="1")
776 stat.create(name="deferred", order="2")
777 stat.create(name="chatting", order="3")
778 stat.create(name="need-eg", order="4")
779 stat.create(name="in-progress", order="5")
780 stat.create(name="testing", order="6")
781 stat.create(name="done-cbb", order="7")
782 stat.create(name="resolved", order="8")
783
784 keyword = Class(db, "keyword", name=String())
785 keyword.setkey("name")
786
787 user = Class(db, "user", username=String(), password=String(),
788 address=String(), realname=String(), phone=String(), organisation=String())
789 user.setkey("username")
790 user.create(username="admin", password=adminpw, address=instance_config.ADMIN_EMAIL)
791
792 msg = FileClass(db, "msg", author=Link("user"), recipients=Multilink("user"),
793 date=Date(), summary=String(), files=Multilink("file"))
794
795 file = FileClass(db, "file", name=String(), type=String())
796
797 issue = IssueClass(db, "issue", assignedto=Link("user"),
798 topic=Multilink("keyword"), priority=Link("priority"), status=Link("status"))
799 issue.setkey('title')
800 </pre>
801
802 <h3>Classes and Properties - creating a new information store</h3>
803 In the instance above, we've defined 7 <em>classes</em> of information:
804 <dl>
805 <dt><strong>priority</strong>
806 <dd>Defines the possible levels of urgency for issues.
807 <dt><strong>status</strong>
808 <dd>Defines the possible states of processing the issue may be in.
809 <dt><strong>keyword</strong>
810 <dd>Initially empty, will hold keywords useful for searching issues.
811 <dt><strong>user</strong>
812 <dd>Initially holding the "admin" user, will eventually have an entry
813 for all users using roundup.
814 <dt><strong>msg</strong>
815 <dd>Initially empty, will all e-mail messages sent to or generated by roundup.
816 <dt><strong>file</strong>
817 <dd>Initially empty, will all files attached to issues.
818 <dt><strong>issue</strong>
819 <dd>Initially emtyp, this is where the issue information is stored.
820 </dl>
821 <p>
822 We define the "priority" and "status" classes to allow two things: reduction
823 in the amount of information stored on the issue and more powerful, accurate
824 searching of issues by priority and status. By only requiring a link on
825 the issue (which is stored as a single number) we reduce the chance
826 that someone mis-types a priority or status - or simply makes a new one
827 up.
828
829 <h4>Class and Nodes</h4>
830 A <em>Class</em> defines a particular class (or type) of data that will be
831 stored in the database. A class comprises one or more properties, which
832 given the information about the class nodes.
833 <p>
834 The actual data entered into the database, using <em>class</em>.create()
835 are called <em>nodes</em>. They have a special immutable property called
836 id. We sometimes refer to this as the <em>nodeid</em>.
837
838
839 <h4>Properties</h4>
840 A Class is comprised of one or more <em>properties</em> of the following types:
841
842 <ul>
843 <li><em>String</em> properties are for storing arbitrary-length
844 strings.
845
846 <li><em>Password</em> properties are for storing encoded arbitrary-length
847 strings. The default encoding is defined on the roundup.password.Password
848 class.
849
850 <li><em>Date</em> properties store date-and-time stamps.
851 Their values are Timestamp objects.
852
853 <li>A <em>Link</em> property refers to a single other node
854 selected from a specified class. The class is part of the property;
855 the value is an integer, the id of the chosen node.
856
857 <li>A <em>Multilink</em> property refers to possibly many nodes
858 in a specified class. The value is a list of integers.
859 </ul>
860
861 <h4>FileClass</h4>
862 FileClasses save their "content" attribute off in a separate file from the
863 rest of the database. This reduces the number of large entries in the
864 database, which generally makes databases more efficient, and also allows
865 us to use command-line tools to operate on the files. They are stored in
866 the files sub-directory of the db directory in your instance.
867
868 <h4>IssueClass</h4>
869 IssueClasses automatically include the "messages", "files", "nosy", and
870 "superseder" properties.
871 <p>
872 The messages and files properties list the links to the messages and files
873 related to the issue. The nosy property is a list of links to users who
874 wish to be informed of changes to the issue - they get "CC'ed" e-mails when
875 messages are sent to or generated by the issue. The nosy reactor (in the
876 detectors directory) handles this action. The superceder link indicates an
877 issue which has superceded this one.
878 <p>
879 They also have the dynamically generated
880 "creation", "activity" and "creator" properties.
881 <p>
882 The value of the "creation" property is the date when a node was created,
883 and the value of the "activity" property is the date when any property on
884 the node was last edited (equivalently, these are the dates on the first
885 and last records in the node's journal). The "creator" property holds a
886 link to the user that created the issue.
887
888 <h4>setkey(property)</h4>
889 Select a String property of the class to be the key property. The key
890 property muse be unique, and allows references to the nodes in the class by
891 the content of the key property. That is, we can refer to users by their
892 username, e.g. let's say that there's an issue in roundup, issue 23. There's
893 also a user, richard who happens to be user 2. To assign an issue to him,
894 we could do either of:
895 <p>
896 <blockquote><tt>roundup-admin set issue assignedto=2</tt></blockquote>
897 <p>
898 or
899 <p>
900 <blockquote><tt>roundup-admin set issue
901 assignedto=richard</tt></blockquote>
902 <p>
903 Note, the same thing can be done in the web and e-mail interfaces.
904
905 <h4>create(information)</h4>
906 Create a node in the database. This is generally used to create nodes in
907 the "definitional" classes like "priority" and "status".
908
909
910 <h2><a name="custweb">Web Interface</a></h2>
911
912 The web interface works behind the cgi-bin/roundup.cgi or roundup-server
913 scripts. In both cases, the scripts determine which instance is being
914 accessed (the first part of the URL path inside the scope of the CGI
915 handler) and pass control on to the instance interfaces.Client class which
916 handles the rest of the access through its main() method. This means that
917 you can do pretty much anything you want as a web interface to your
918 instance.
919 <p>
920 Most customisation of the web view can be done by modifying the templates
921 in the instance html directory. These are divided into index, item and
922 newitem views. The newitem view is optional - the item view will be used if
923 the newitem view doesn't exist.
924
925 <h3><a name="schemarepurcussions">Repurcussions of changing the instance schema</a></h3>
926
927 If you choose to <a href="custinst">change the instance schema</a> you will need to
928 ensure the web interface knows about it:
929 <ol>
930 <li>Index, item and filter pages for the relevant classes may need to have properties
931 added or removed,
932 <li>The default page header relies on the existence of, and some values of the
933 priority, status, assignedto and activity classes. If you change any of these (specifically
934 if you remove any of the classes or their default values) you will need to implement your
935 own pagehead() method in your instance's interfaces.py module.
936 </ol>
937
938
939 <h3>Displaying Properties</h3>
940
941 <p>
942 Properties appear in the user interface in three contexts:
943 in indices, in editors, and as filters. For each type of
944 property, there are several display possibilities. For example,
945 in an index view, a string property may just be printed as
946 a plain string, but in an editor view, that property should
947 be displayed in an editable field.
948
949 <p>
950 The display of a property is handled by functions in
951 the htmltemplate module.
952
953 <p>
954 Displayer functions are triggered by <tt>&lt;display&gt;</tt>
955 tags in templates. The <tt>call</tt> attribute of the tag
956 provides a Python expression for calling the displayer
957 function. The three standard arguments are inserted in
958 front of the arguments given. For example, the occurrence of
959
960 <blockquote><pre><small
961 > &lt;display call="plain('status')"&gt;
962 </small></pre></blockquote>
963
964 in a template triggers a call the "plain" function. The displayer
965 functions can accept extra arguments to further specify
966 details about the widgets that should be generated. By defining new
967 displayer functions, the user interface can be highly customized.
968
969 <p>
970 <table border=1 cellspacing=0>
971 <tr><th colspan=2>The displayer functions are</th></tr>
972
973 <tr><td valign="top"><strong>plain</strong></td>
974 <td>Display a String property directly.
975 <p>
976 Display a Date property in a specified time zone with an option
977 to omit the time from the date stamp.
978 <p>
979 For a Link or Multilink
980 property, display the key strings of the linked nodes (or the
981 ids if the linked class has no key property).
982 <p>
983 <em>Options:</em><br>
984 escape (boolean) - HTML-escape the resulting text.
985 </td></tr>
986
987 <tr><td valign="top"><strong>field</strong></td>
988 <td>Display a property like the
989 <strong>plain</strong> displayer above, but in a form field
990 to be edited. Strings, Dates and Intervals use TEXT fields, Links use
991 SELECT fields and Multilinks use SELECT MULTIPLE fields.
992 <p>
993 <em>Options:</em><br>
994 size (number) - width of TEXT fields.<br>
995 height (number) - number of nows in SELECT MULTIPLE tags.<br>
996 showid (boolean) - true includes the id of linked nodes in the SELECT
997 MULTIPLE fields.
998 </td></tr>
999
1000 <tr><td valign="top"><strong>menu</strong></td>
1001 <td>For a Links and Multilinks, display the same field as would be
1002 generated using <strong>field</strong>.
1003 </td></tr>
1004
1005 <tr><td valign="top"><strong>link</strong></td>
1006 <td>For a Link or Multilink property, display the names of the linked
1007 nodes, hyperlinked to the item views on those nodes.
1008 <p>
1009 For other properties, link to this node with the property as the text.
1010 <p>
1011 <em>Options:</em><br>
1012 property (property name) - the property to use in the second case.
1013 </td></tr>
1014
1015 <tr><td valign="top"><strong>count</strong></td>
1016 <td>For a Multilink property, display
1017 a count of the number of links in the list.
1018 <p>
1019 <em>Arguments:</em><br>
1020 property (property name) - the property to use.
1021
1022 </td></tr>
1023
1024 <tr><td valign="top"><strong>reldate</strong></td>
1025 <td>Display a Date property in terms
1026 of an interval relative to the current date (e.g. "+ 3w", "- 2d").
1027 <p>
1028 <em>Arguments:</em><br>
1029 property (property name) - the property to use.
1030 <p>
1031 <em>Options:</em><br>
1032 pretty (boolean) - display the relative date in an English form.
1033 </td></tr>
1034
1035 <tr><td valign="top"><strong>download</strong></td>
1036 <td>For a Link or Multilink property, display the names of the linked
1037 nodes, hyperlinked to the item views on those nodes.
1038 <p>
1039 For other properties, link to this node with the property as the text.
1040 <p>
1041 In all cases, append the name (key property) of the item to the path so it
1042 is the name of the file being downloaded.
1043 <p>
1044 <em>Arguments:</em><br>
1045 property (property name) - the property to use.
1046 </td></tr>
1047
1048 <tr><td valign="top"><strong>checklist</strong></td>
1049 <td>For a Link or Multilink property,
1050 display checkboxes for the available choices to permit filtering.
1051 <p>
1052 <em>Arguments:</em><br>
1053 property (property name) - the property to use.
1054 </td></tr>
1055
1056 <tr><td valign="top"><strong>note</strong></td>
1057 <td>Display the special notes field, which is a text area for entering a
1058 note to go along with a change.
1059 </td></tr>
1060
1061 <tr><td valign="top"><strong>list</strong></td>
1062 <td>List the nodes specified by property using the standard index for
1063 the class.
1064 <p>
1065 <em>Arguments:</em><br>
1066 property (property name) - the property to use.
1067 </td></tr>
1068
1069 <tr><td valign="top"><strong>history</strong></td>
1070 <td>List the history of the item.
1071 </td></tr>
1072
1073 <tr><td valign="top"><strong>submit</strong></td>
1074 <td>Add a submit button for the item.
1075 </td></tr>
1076
1077 </table>
1078
1079 <h3>Index Views</h3>
1080
1081 <p>An index view contains two sections: a filter section
1082 and an index section.
1083 The filter section provides some widgets for selecting
1084 which items appear in the index. The index section is
1085 a table of items.
1086
1087 <h4>Index View Specifiers</h4>
1088
1089 <p>An index view specifier (URL fragment) looks like this (whitespace
1090 has been added for clarity):
1091
1092 <blockquote><pre><small
1093 >/issue?status=unread,in-progress,resolved&amp;
1094 topic=security,ui&amp;
1095 :group=+priority&amp;
1096 :sort=-activity&amp;
1097 :filters=status,topic&amp;
1098 :columns=title,status,fixer
1099 </small></pre></blockquote>
1100
1101 <p>The index view is determined by two parts of the
1102 specifier: the layout part and the filter part.
1103 The layout part consists of the query parameters that
1104 begin with colons, and it determines the way that the
1105 properties of selected nodes are displayed.
1106 The filter part consists of all the other query parameters,
1107 and it determines the criteria by which nodes
1108 are selected for display.
1109
1110 <p>The filter part is interactively manipulated with
1111 the form widgets displayed in the filter section. The
1112 layout part is interactively manipulated by clicking
1113 on the column headings in the table.
1114
1115 <p>The filter part selects the <em>union</em> of the
1116 sets of items with values matching any specified Link
1117 properties and the <em>intersection</em> of the sets
1118 of items with values matching any specified Multilink
1119 properties.
1120
1121 <p>The example specifies an index of "issue" nodes.
1122 Only items with a "status" of <em>either</em>
1123 "unread" or "in-progres" or "resolved" are displayed,
1124 and only items with "topic" values including <em>both</em>
1125 "security" <em>and</em> "ui" are displayed. The items
1126 are grouped by priority, arranged in ascending order;
1127 and within groups, sorted by activity, arranged in
1128 descending order. The filter section shows filters
1129 for the "status" and "topic" properties, and the
1130 table includes columns for the "title", "status", and
1131 "fixer" properties.
1132
1133 <p>Associated with each item class is a default
1134 layout specifier. The layout specifier in the above
1135 example is the default layout to be provided with
1136 the default bug-tracker schema described above in
1137 section 4.4.
1138
1139 <h4>Filter Section</h4>
1140
1141 <p>The template for a filter section provides the
1142 filtering widgets at the top of the index view.
1143 Fragments enclosed in <tt>&lt;property&gt;</tt>...<tt>&lt;/property&gt;</tt>
1144 tags are included or omitted depending on whether the
1145 view specifier requests a filter for a particular property.
1146
1147 <p>A property must appear in the filter template for it to be available
1148 as a filter.
1149
1150 <p>Here's a simple example of a filter template.
1151
1152 <blockquote><pre><small>&lt;property name=status&gt;
1153 &lt;display call="checklist('status')"&gt;
1154 &lt;/property&gt;
1155 &lt;br&gt;
1156 &lt;property name=priority&gt;
1157 &lt;display call="checklist('priority')"&gt;
1158 &lt;/property&gt;
1159 &lt;br&gt;
1160 &lt;property name=fixer&gt;
1161 &lt;display call="menu('fixer')"&gt;
1162 &lt;/property&gt;</small></pre></blockquote>
1163
1164 <p>
1165 The standard index generation code appends a section to the index pages
1166 which allows selection of the filters - from those which are defined in the
1167 filter template.
1168
1169 <h4>Index Section</h4>
1170
1171 <p>The template for an index section describes one row of
1172 the index table.
1173 Fragments enclosed in <tt>&lt;property&gt;</tt>...<tt>&lt;/property&gt;</tt>
1174 tags are included or omitted depending on whether the
1175 view specifier requests a column for a particular property.
1176 The table cells should contain <tt>&lt;display&gt;</tt> tags
1177 to display the values of the item's properties.
1178
1179 <p>Here's a simple example of an index template.
1180
1181 <blockquote><pre><small>&lt;tr&gt;
1182 &lt;property name=title&gt;
1183 &lt;td&gt;&lt;display call="plain('title', max=50)"&gt;&lt;/td&gt;
1184 &lt;/property&gt;
1185 &lt;property name=status&gt;
1186 &lt;td&gt;&lt;display call="plain('status')"&gt;&lt;/td&gt;
1187 &lt;/property&gt;
1188 &lt;property name=fixer&gt;
1189 &lt;td&gt;&lt;display call="plain('fixer')"&gt;&lt;/td&gt;
1190 &lt;/property&gt;
1191 &lt;/tr&gt;</small></pre></blockquote>
1192
1193 <h4>Sorting</h4>
1194
1195 <p>String and Date values are sorted in the natural way.
1196 Link properties are sorted according to the value of the
1197 "order" property on the linked nodes if it is present; or
1198 otherwise on the key string of the linked nodes; or
1199 finally on the node ids. Multilink properties are
1200 sorted according to how many links are present.
1201
1202 <h3>Item Views</h3>
1203
1204 <p>An item view contains an editor section and a spool section.
1205 At the top of an item view, links to superseding and superseded
1206 items are always displayed.
1207
1208
1209
1210 <h4>Editor Section</h4>
1211
1212 <p>The editor section is generated from a template
1213 containing <tt>&lt;display&gt;</tt> tags to insert
1214 the appropriate widgets for editing properties.
1215
1216 <p>Here's an example of a basic editor template.
1217
1218 <blockquote><pre><small>&lt;table&gt;
1219 &lt;tr&gt;
1220 &lt;td colspan=2&gt;
1221 &lt;display call="field('title', size=60)"&gt;
1222 &lt;/td&gt;
1223 &lt;/tr&gt;
1224 &lt;tr&gt;
1225 &lt;td&gt;
1226 &lt;display call="field('fixer', size=30)"&gt;
1227 &lt;/td&gt;
1228 &lt;td&gt;
1229 &lt;display call="menu('status')&gt;
1230 &lt;/td&gt;
1231 &lt;/tr&gt;
1232 &lt;tr&gt;
1233 &lt;td&gt;
1234 &lt;display call="field('nosy', size=30)"&gt;
1235 &lt;/td&gt;
1236 &lt;td&gt;
1237 &lt;display call="menu('priority')&gt;
1238 &lt;/td&gt;
1239 &lt;/tr&gt;
1240 &lt;tr&gt;
1241 &lt;td colspan=2&gt;
1242 &lt;display call="note()"&gt;
1243 &lt;/td&gt;
1244 &lt;/tr&gt;
1245 &lt;/table&gt;
1246 </small></pre></blockquote>
1247
1248 <p>As shown in the example, the editor template can also
1249 request the display of a "note" field, which is a
1250 text area for entering a note to go along with a change.
1251
1252 <p>When a change is submitted, the system automatically
1253 generates a message describing the changed properties.
1254
1255 <p>If a note is given in the "note" field, the note is
1256 appended to the description. The message is then added
1257 to the item's message spool (thus triggering the standard
1258 detector to react by sending out this message to the nosy list).
1259
1260 <p>
1261 The message also displays all of the property values on the
1262 item and indicates which ones have changed.
1263 An example of such a message might be this:
1264
1265 <blockquote><pre>
1266 Polly's taken a turn for the worse - this is now really important!
1267 -----
1268 title: Polly Parrot is dead
1269 priority: critical
1270 status: unread -&gt; in-progress
1271 fixer: terry
1272 keywords: parrot,plumage,perch,nailed,dead
1273 </pre></blockquote>
1274
1275 <h4>Spool Section</h4>
1276
1277 <p>The spool section lists messages in the item's "messages"
1278 property. The index of messages displays the "date", "author",
1279 and "summary" properties on the message nodes, and selecting a
1280 message takes you to its content.
1281
1282 <p>The &lt;property&gt; tag used in the index may also be used here -
1283 it checks to see if the nominated Multilink property has any entries.
1284 This can be used to eliminate sections of the spool section if the
1285 property has no entries.
1286
1287 <blockquote><pre>
1288 &lt;property name="files"&gt;
1289 &lt;tr class="strong-header"&gt;
1290 &lt;td&gt;&lt;b&gt;Files&lt;/b&gt;&lt;/td&gt;
1291 &lt;/tr&gt;
1292
1293 &lt;tr&gt;
1294 &lt;td&gt;&lt;display call="list('files')"&gt;&lt;/td&gt;
1295 &lt;/tr&gt;
1296 &lt;/property&gt;
1297 </pre></blockquote>
1298
1299 <p><hr>
1300 <h1><a name="ack">Acknowledgements</a></h1>
1301
1302 Go Ping, you rock! Also, go Bizar Software for letting me implement this
1303 system on their time.
1304
1305 <p>&nbsp;</p>
1306 <hr>
1307 $Id: index.html,v 1.27 2002-01-23 05:10:27 richard Exp $
1308 <p>&nbsp;</p>
1309
1310 </body></html>

Roundup Issue Tracker: http://roundup-tracker.org/