comparison doc/customizing.txt @ 659:e429649ed124

More documentation cleanups. - renamed .stx to .txt so they're identifiable as readable files. - fixed FAQ and announcement formatting
author Richard Jones <richard@users.sourceforge.net>
date Wed, 13 Mar 2002 23:00:48 +0000
parents
children 604c84696461 54333751e98d
comparison
equal deleted inserted replaced
658:1409d4d55f92 659:e429649ed124
1 Customising Roundup
2 ===================
3
4 Instances have the following structure:
5
6 +-------------------+--------------------------------------------------------+
7 |instance_config.py |Holds the basic instance_configuration |
8 +-------------------+--------------------------------------------------------+
9 |dbinit.py |Holds the instance_schema |
10 +-------------------+--------------------------------------------------------+
11 |interfaces.py |Defines the Web and E-Mail interfaces for the instance |
12 +-------------------+--------------------------------------------------------+
13 |select_db.py |Selects the database back-end for the instance |
14 +-------------------+--------------------------------------------------------+
15 |db/ |Holds the instance's database |
16 +-------------------+--------------------------------------------------------+
17 |db/files/ |Holds the instance's upload files and messages |
18 +-------------------+--------------------------------------------------------+
19 |detectors/ |Auditors and reactors for this instance |
20 +-------------------+--------------------------------------------------------+
21 |html/ |Web interface templates, images and style sheets |
22 +-------------------+--------------------------------------------------------+
23
24 Instance Configuration
25 ----------------------
26
27 The instance_config.py located in your instance home contains the basic
28 configuration for the web and e-mail components of roundup's interfaces. This
29 file is a Python module. The default instance_config.py is given below - as you
30 can see, the MAIL_DOMAIN must be edited before any interaction with the
31 instance is attempted.::
32
33 MAIL_DOMAIN=MAILHOST=HTTP_HOST=None
34 HTTP_PORT=0
35
36 # roundup home is this package's directory
37 INSTANCE_HOME=os.path.split(__file__)[0]
38
39 # The SMTP mail host that roundup will use to send mail
40 if not MAILHOST:
41 MAILHOST = 'localhost'
42
43 # The domain name used for email addresses.
44 if not MAIL_DOMAIN:
45 MAIL_DOMAIN = 'fill.me.in.'
46
47 # the next two are only used for the standalone HTTP server.
48 if not HTTP_HOST:
49 HTTP_HOST = ''
50 if not HTTP_PORT:
51 HTTP_PORT = 9080
52
53 # This is the directory that the database is going to be stored in
54 DATABASE = os.path.join(INSTANCE_HOME, 'db')
55
56 # This is the directory that the HTML templates reside in
57 TEMPLATES = os.path.join(INSTANCE_HOME, 'html')
58
59 # The email address that mail to roundup should go to
60 ISSUE_TRACKER_EMAIL = 'issue_tracker@%s'%MAIL_DOMAIN
61
62 # The web address that the instance is viewable at
63 ISSUE_TRACKER_WEB = 'http://some.useful.url/'
64
65 # The email address that roundup will complain to if it runs into trouble
66 ADMIN_EMAIL = 'roundup-admin@%s'%MAIL_DOMAIN
67
68 # Somewhere for roundup to log stuff internally sent to stdout or stderr
69 LOG = os.path.join(INSTANCE_HOME, 'roundup.log')
70
71 # Where to place the web filtering HTML on the index page
72 FILTER_POSITION = 'bottom' # one of 'top', 'bottom', 'top and bottom'
73
74 # Deny or allow anonymous access to the web interface
75 ANONYMOUS_ACCESS = 'deny'
76
77 # Deny or allow anonymous users to register through the web interface
78 ANONYMOUS_REGISTER = 'deny'
79
80 # Send nosy messages to the author of the message
81 MESSAGES_TO_AUTHOR = 'no' # either 'yes' or 'no'
82
83
84 Instance Schema
85 ---------------
86
87 Note: if you modify the schema, you'll most likely need to edit the
88 `web interface`_ HTML template files to reflect your changes.
89
90 An instance schema defines what data is stored in the instance's database. The
91 two schemas shipped with Roundup turn it into a typical software bug tracker
92 (the extended schema allowing for support issues as well as bugs). Schemas are
93 defined using Python code. The "classic" schema looks like this::
94
95 pri = Class(db, "priority", name=String(), order=String())
96 pri.setkey("name")
97 pri.create(name="critical", order="1")
98 pri.create(name="urgent", order="2")
99 pri.create(name="bug", order="3")
100 pri.create(name="feature", order="4")
101 pri.create(name="wish", order="5")
102
103 stat = Class(db, "status", name=String(), order=String())
104 stat.setkey("name")
105 stat.create(name="unread", order="1")
106 stat.create(name="deferred", order="2")
107 stat.create(name="chatting", order="3")
108 stat.create(name="need-eg", order="4")
109 stat.create(name="in-progress", order="5")
110 stat.create(name="testing", order="6")
111 stat.create(name="done-cbb", order="7")
112 stat.create(name="resolved", order="8")
113
114 keyword = Class(db, "keyword", name=String())
115 keyword.setkey("name")
116
117 user = Class(db, "user", username=String(), password=String(),
118 address=String(), realname=String(), phone=String(),
119 organisation=String())
120 user.setkey("username")
121 user.create(username="admin", password=adminpw,
122 address=instance_config.ADMIN_EMAIL)
123
124 msg = FileClass(db, "msg", author=Link("user"), recipients=Multilink
125 ("user"), date=Date(), summary=String(), files=Multilink("file"))
126
127 file = FileClass(db, "file", name=String(), type=String())
128
129 issue = IssueClass(db, "issue", assignedto=Link("user"),
130 topic=Multilink("keyword"), priority=Link("priority"), status=Link
131 ("status"))
132 issue.setkey('title')
133
134 Classes and Properties - creating a new information store
135 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136
137 In the instance above, we've defined 7 classes of information:
138
139 priority
140 Defines the possible levels of urgency for issues.
141
142 status
143 Defines the possible states of processing the issue may be in.
144
145 keyword
146 Initially empty, will hold keywords useful for searching issues.
147
148 user
149 Initially holding the "admin" user, will eventually have an entry for all
150 users using roundup.
151
152 msg
153 Initially empty, will all e-mail messages sent to or generated by
154 roundup.
155
156 file
157 Initially empty, will all files attached to issues.
158
159 issue
160 Initially emtyp, this is where the issue information is stored.
161
162 We define the "priority" and "status" classes to allow two things: reduction in
163 the amount of information stored on the issue and more powerful, accurate
164 searching of issues by priority and status. By only requiring a link on the
165 issue (which is stored as a single number) we reduce the chance that someone
166 mis-types a priority or status - or simply makes a new one up.
167
168 Class and Nodes
169 :::::::::::::::
170
171 A Class defines a particular class (or type) of data that will be stored in the
172 database. A class comprises one or more properties, which given the information
173 about the class nodes.
174 The actual data entered into the database, using class.create() are called
175 nodes. They have a special immutable property called id. We sometimes refer to
176 this as the nodeid.
177
178 Properties
179 ::::::::::
180
181 A Class is comprised of one or more properties of the following types:
182 * String properties are for storing arbitrary-length strings.
183 * Password properties are for storing encoded arbitrary-length strings. The
184 default encoding is defined on the roundup.password.Password class.
185 * Date properties store date-and-time stamps. Their values are Timestamp
186 objects.
187 * A Link property refers to a single other node selected from a specified
188 class. The class is part of the property; the value is an integer, the id
189 of the chosen node.
190 * A Multilink property refers to possibly many nodes in a specified class.
191 The value is a list of integers.
192
193 FileClass
194 :::::::::
195
196 FileClasses save their "content" attribute off in a separate file from the rest
197 of the database. This reduces the number of large entries in the database,
198 which generally makes databases more efficient, and also allows us to use
199 command-line tools to operate on the files. They are stored in the files sub-
200 directory of the db directory in your instance.
201
202 IssueClass
203 ::::::::::
204
205 IssueClasses automatically include the "messages", "files", "nosy", and
206 "superseder" properties.
207 The messages and files properties list the links to the messages and files
208 related to the issue. The nosy property is a list of links to users who wish to
209 be informed of changes to the issue - they get "CC'ed" e-mails when messages
210 are sent to or generated by the issue. The nosy reactor (in the detectors
211 directory) handles this action. The superceder link indicates an issue which
212 has superceded this one.
213 They also have the dynamically generated "creation", "activity" and "creator"
214 properties.
215 The value of the "creation" property is the date when a node was created, and
216 the value of the "activity" property is the date when any property on the node
217 was last edited (equivalently, these are the dates on the first and last
218 records in the node's journal). The "creator" property holds a link to the user
219 that created the issue.
220
221 setkey(property)
222 ::::::::::::::::
223
224 Select a String property of the class to be the key property. The key property
225 muse be unique, and allows references to the nodes in the class by the content
226 of the key property. That is, we can refer to users by their username, e.g.
227 let's say that there's an issue in roundup, issue 23. There's also a user,
228 richard who happens to be user 2. To assign an issue to him, we could do either
229 of::
230
231 roundup-admin set issue assignedto=2
232
233 or::
234
235 roundup-admin set issue assignedto=richard
236
237 Note, the same thing can be done in the web and e-mail interfaces.
238
239 create(information)
240 :::::::::::::::::::
241
242 Create a node in the database. This is generally used to create nodes in the
243 "definitional" classes like "priority" and "status".
244
245 Web Interface
246 -------------
247
248 The web interface works behind the cgi-bin/roundup.cgi or roundup-server
249 scripts. In both cases, the scripts determine which instance is being accessed
250 (the first part of the URL path inside the scope of the CGI handler) and pass
251 control on to the instance interfaces.Client class which handles the rest of
252 the access through its main() method. This means that you can do pretty much
253 anything you want as a web interface to your instance.
254 Most customisation of the web view can be done by modifying the templates in
255 the instance html directory. These are divided into index, item and newitem
256 views. The newitem view is optional - the item view will be used if the newitem
257 view doesn't exist.
258
259 Repurcussions of changing the instance schema
260 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261
262 If you choose to change_the_instance_schema you will need to ensure the web
263 interface knows about it:
264
265 1. Index, item and filter pages for the relevant classes may need to have
266 properties added or removed,
267 2. The default page header relies on the existence of, and some values of
268 the priority, status, assignedto and activity classes. If you change any
269 of these (specifically if you remove any of the classes or their default
270 values) you will need to implement your own pagehead() method in your
271 instance's interfaces.py module.
272
273 Displaying Properties
274 ~~~~~~~~~~~~~~~~~~~~~
275
276 Properties appear in the user interface in three contexts: in indices, in
277 editors, and as filters. For each type of property, there are several display
278 possibilities. For example, in an index view, a string property may just be
279 printed as a plain string, but in an editor view, that property should be
280 displayed in an editable field.
281
282 The display of a property is handled by functions in the htmltemplate module.
283 Displayer functions are triggered by <display> tags in templates. The call
284 attribute of the tag provides a Python expression for calling the displayer
285 function. The three standard arguments are inserted in front of the arguments
286 given. For example, the occurrence of::
287
288 <display call="plain('status')">
289
290 in a template triggers a call the "plain" function. The displayer functions can
291 accept extra arguments to further specify details about the widgets that should
292 be generated. By defining new displayer functions, the user interface can be
293 highly customized.
294
295 +-----------------------------------------------------------------------------+
296 |The displayer functions are |
297 +---------+-------------------------------------------------------------------+
298 |plain |Display a String property directly. |
299 | |Display a Date property in a specified time zone with an option to |
300 | |omit the time from the date stamp. |
301 | |For a Link or Multilink property, display the key strings of the |
302 | |linked nodes (or the ids if the linked class has no key property). |
303 | |Options: |
304 | |escape (boolean) - HTML-escape the resulting text. |
305 +---------+-------------------------------------------------------------------+
306 |field |Display a property like the plain displayer above, but in a form |
307 | |field to be edited. Strings, Dates and Intervals use TEXT fields, |
308 | |Links use SELECT fields and Multilinks use SELECT MULTIPLE fields. |
309 | |Options: |
310 | |size (number) - width of TEXT fields. |
311 | |height (number) - number of nows in SELECT MULTIPLE tags. |
312 | |showid (boolean) - true includes the id of linked nodes in the |
313 | |SELECT MULTIPLE fields. |
314 +---------+-------------------------------------------------------------------+
315 |menu |For a Links and Multilinks, display the same field as would be |
316 | |generated using field. |
317 +---------+-------------------------------------------------------------------+
318 |link |For a Link or Multilink property, display the names of the linked |
319 | |nodes, hyperlinked to the item views on those nodes. |
320 | |For other properties, link to this node with the property as the |
321 | |text. |
322 | |Options: |
323 | |property (property name) - the property to use in the second case. |
324 +---------+-------------------------------------------------------------------+
325 |count |For a Multilink property, display a count of the number of links in|
326 | |the list. |
327 | |Arguments: |
328 | |property (property name) - the property to use. |
329 +---------+-------------------------------------------------------------------+
330 |reldate |Display a Date property in terms of an interval relative to the |
331 | |current date (e.g. "+ 3w", "- 2d"). |
332 | |Arguments: |
333 | |property (property name) - the property to use. |
334 | |Options: |
335 | |pretty (boolean) - display the relative date in an English form. |
336 +---------+-------------------------------------------------------------------+
337 |download |For a Link or Multilink property, display the names of the linked |
338 | |nodes, hyperlinked to the item views on those nodes. |
339 | |For other properties, link to this node with the property as the |
340 | |text. |
341 | |In all cases, append the name (key property) of the item to the |
342 | |path so it is the name of the file being downloaded. |
343 | |Arguments: |
344 | |property (property name) - the property to use. |
345 +---------+-------------------------------------------------------------------+
346 |checklist|For a Link or Multilink property, display checkboxes for the |
347 | |available choices to permit filtering. |
348 | |Arguments: |
349 | |property (property name) - the property to use. |
350 +---------+-------------------------------------------------------------------+
351 |note |Display the special notes field, which is a text area for entering |
352 | |a note to go along with a change. |
353 +---------+-------------------------------------------------------------------+
354 |list |List the nodes specified by property using the standard index for |
355 | |the class. |
356 | |Arguments: |
357 | |property (property name) - the property to use. |
358 +---------+-------------------------------------------------------------------+
359 |history |List the history of the item. |
360 +---------+-------------------------------------------------------------------+
361 |submit |Add a submit button for the item. |
362 +---------+-------------------------------------------------------------------+
363
364
365 Index Views
366 ~~~~~~~~~~~
367
368 An index view contains two sections: a filter section and an index section. The
369 filter section provides some widgets for selecting which items appear in the
370 index. The index section is a table of items.
371
372 Index View Specifiers
373 :::::::::::::::::::::
374
375 An index view specifier (URL fragment) looks like this (whitespace has been
376 added for clarity)::
377
378 /issue?status=unread,in-progress,resolved&
379 topic=security,ui&
380 :group=+priority&
381 :sort=-activity&
382 :filters=status,topic&
383 :columns=title,status,fixer
384
385 The index view is determined by two parts of the specifier: the layout part and
386 the filter part. The layout part consists of the query parameters that begin
387 with colons, and it determines the way that the properties of selected nodes
388 are displayed. The filter part consists of all the other query parameters, and
389 it determines the criteria by which nodes are selected for display.
390 The filter part is interactively manipulated with the form widgets displayed in
391 the filter section. The layout part is interactively manipulated by clicking on
392 the column headings in the table.
393
394 The filter part selects the union of the sets of items with values matching any
395 specified Link properties and the intersection of the sets of items with values
396 matching any specified Multilink properties.
397
398 The example specifies an index of "issue" nodes. Only items with a "status" of
399 either "unread" or "in-progres" or "resolved" are displayed, and only items
400 with "topic" values including both "security" and "ui" are displayed. The items
401 are grouped by priority, arranged in ascending order; and within groups, sorted
402 by activity, arranged in descending order. The filter section shows filters for
403 the "status" and "topic" properties, and the table includes columns for the
404 "title", "status", and "fixer" properties.
405
406 Associated with each item class is a default layout specifier. The layout
407 specifier in the above example is the default layout to be provided with the
408 default bug-tracker schema described above in section 4.4.
409
410 Filter Section
411 ::::::::::::::
412
413 The template for a filter section provides the filtering widgets at the top of
414 the index view. Fragments enclosed in <property>...</property> tags are
415 included or omitted depending on whether the view specifier requests a filter
416 for a particular property.
417
418 A property must appear in the filter template for it to be available as a
419 filter.
420
421 Here's a simple example of a filter template.::
422
423 <property name=status>
424 <display call="checklist('status')">
425 </property>
426 <br>
427 <property name=priority>
428 <display call="checklist('priority')">
429 </property>
430 <br>
431 <property name=fixer>
432 <display call="menu('fixer')">
433 </property>
434
435 The standard index generation code appends a section to the index pages which
436 allows selection of the filters - from those which are defined in the filter
437 template.
438
439 Index Section
440 :::::::::::::
441
442 The template for an index section describes one row of the index table.
443 Fragments enclosed in <property>...</property> tags are included or omitted
444 depending on whether the view specifier requests a column for a particular
445 property. The table cells should contain <display> tags to display the values
446 of the item's properties.
447
448 Here's a simple example of an index template.::
449
450 <tr>
451 <property name=title>
452 <td><display call="plain('title', max=50)"></td>
453 </property>
454 <property name=status>
455 <td><display call="plain('status')"></td>
456 </property>
457 <property name=fixer>
458 <td><display call="plain('fixer')"></td>
459 </property>
460 </tr>
461
462 Sorting
463 :::::::
464
465 String and Date values are sorted in the natural way. Link properties are
466 sorted according to the value of the "order" property on the linked nodes if it
467 is present; or otherwise on the key string of the linked nodes; or finally on
468 the node ids. Multilink properties are sorted according to how many links are
469 present.
470
471 Item Views
472 ~~~~~~~~~~
473
474 An item view contains an editor section and a spool section. At the top of an
475 item view, links to superseding and superseded items are always displayed.
476
477 Editor Section
478 ::::::::::::::
479
480 The editor section is generated from a template containing <display> tags to
481 insert the appropriate widgets for editing properties.
482
483 Here's an example of a basic editor template.::
484
485 <table>
486 <tr>
487 <td colspan=2>
488 <display call="field('title', size=60)">
489 </td>
490 </tr>
491 <tr>
492 <td>
493 <display call="field('fixer', size=30)">
494 </td>
495 <td>
496 <display call="menu('status')>
497 </td>
498 </tr>
499 <tr>
500 <td>
501 <display call="field('nosy', size=30)">
502 </td>
503 <td>
504 <display call="menu('priority')>
505 </td>
506 </tr>
507 <tr>
508 <td colspan=2>
509 <display call="note()">
510 </td>
511 </tr>
512 </table>
513
514 As shown in the example, the editor template can also request the display of a
515 "note" field, which is a text area for entering a note to go along with a
516 change.
517
518 When a change is submitted, the system automatically generates a message
519 describing the changed properties.
520
521 If a note is given in the "note" field, the note is appended to the
522 description. The message is then added to the item's message spool (thus
523 triggering the standard detector to react by sending out this message to the
524 nosy list).
525
526 The message also displays all of the property values on the item and indicates
527 which ones have changed. An example of such a message might be this::
528
529 Polly's taken a turn for the worse - this is now really important!
530 -----
531 title: Polly Parrot is dead
532 priority: critical
533 status: unread -> in-progress
534 fixer: terry
535 keywords: parrot,plumage,perch,nailed,dead
536
537 Spool Section
538 :::::::::::::
539
540 The spool section lists messages in the item's "messages" property. The index
541 of messages displays the "date", "author", and "summary" properties on the
542 message nodes, and selecting a message takes you to its content.
543
544 The <property> tag used in the index may also be used here - it checks to see
545 if the nominated Multilink property has any entries. This can be used to
546 eliminate sections of the spool section if the property has no entries.::
547
548 <property name="files">
549 <tr class="strong-header">
550 <td><b>Files</b></td>
551 </tr>
552
553 <tr>
554 <td><display call="list('files')"></td>
555 </tr>
556 </property>
557
558

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