Mercurial > p > roundup > code
comparison doc/customizing.txt @ 1089:43ab730ee194
instance -> tracker, node -> item
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Tue, 10 Sep 2002 00:15:59 +0000 |
| parents | 40fc5f8cd55c |
| children | d870139aeb5c |
comparison
equal
deleted
inserted
replaced
| 1088:32e41ddf2edb | 1089:43ab730ee194 |
|---|---|
| 1 =================== | 1 =================== |
| 2 Customising Roundup | 2 Customising Roundup |
| 3 =================== | 3 =================== |
| 4 | 4 |
| 5 :Version: $Revision: 1.22 $ | 5 :Version: $Revision: 1.23 $ |
| 6 | 6 |
| 7 .. This document borrows from the ZopeBook section on ZPT. The original is at: | 7 .. This document borrows from the ZopeBook section on ZPT. The original is at: |
| 8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx | 8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx |
| 9 | 9 |
| 10 .. contents:: | 10 .. contents:: |
| 13 What You Can Do | 13 What You Can Do |
| 14 --------------- | 14 --------------- |
| 15 | 15 |
| 16 Customisation of Roundup can take one of five forms: | 16 Customisation of Roundup can take one of five forms: |
| 17 | 17 |
| 18 1. `instance configuration`_ file changes | 18 1. `tracker configuration`_ file changes |
| 19 2. database, or `instance schema`_ changes | 19 2. database, or `tracker schema`_ changes |
| 20 3. "definition" class `database content`_ changes | 20 3. "definition" class `database content`_ changes |
| 21 4. behavioural changes, through detectors_ | 21 4. behavioural changes, through detectors_ |
| 22 5. `access controls`_ | 22 5. `access controls`_ |
| 23 | 23 |
| 24 The third case is special because it takes two distinctly different forms | 24 The third case is special because it takes two distinctly different forms |
| 25 depending upon whether the instance has been initialised or not. The other two | 25 depending upon whether the tracker has been initialised or not. The other two |
| 26 may be done at any time, before or after instance initialisation. Yes, this | 26 may be done at any time, before or after tracker initialisation. Yes, this |
| 27 includes adding or removing properties from classes. | 27 includes adding or removing properties from classes. |
| 28 | 28 |
| 29 | 29 |
| 30 Instances in a Nutshell | 30 Trackers in a Nutshell |
| 31 ----------------------- | 31 ---------------------- |
| 32 | 32 |
| 33 Instances have the following structure: | 33 Trackers have the following structure: |
| 34 | 34 |
| 35 +-------------------+--------------------------------------------------------+ | 35 +-------------------+--------------------------------------------------------+ |
| 36 |instance_config.py |Holds the basic instance_configuration | | 36 |config.py |Holds the basic `tracker configuration`_ | |
| 37 +-------------------+--------------------------------------------------------+ | 37 +-------------------+--------------------------------------------------------+ |
| 38 |dbinit.py |Holds the instance_schema | | 38 |dbinit.py |Holds the `tracker schema`_ | |
| 39 +-------------------+--------------------------------------------------------+ | 39 +-------------------+--------------------------------------------------------+ |
| 40 |interfaces.py |Defines the Web and E-Mail interfaces for the instance | | 40 |interfaces.py |Defines the Web and E-Mail interfaces for the tracker | |
| 41 +-------------------+--------------------------------------------------------+ | 41 +-------------------+--------------------------------------------------------+ |
| 42 |select_db.py |Selects the database back-end for the instance | | 42 |select_db.py |Selects the database back-end for the tracker | |
| 43 +-------------------+--------------------------------------------------------+ | 43 +-------------------+--------------------------------------------------------+ |
| 44 |db/ |Holds the instance's database | | 44 |db/ |Holds the tracker's database | |
| 45 +-------------------+--------------------------------------------------------+ | 45 +-------------------+--------------------------------------------------------+ |
| 46 |db/files/ |Holds the instance's upload files and messages | | 46 |db/files/ |Holds the tracker's upload files and messages | |
| 47 +-------------------+--------------------------------------------------------+ | 47 +-------------------+--------------------------------------------------------+ |
| 48 |detectors/ |Auditors and reactors for this instance | | 48 |detectors/ |Auditors and reactors for this tracker | |
| 49 +-------------------+--------------------------------------------------------+ | 49 +-------------------+--------------------------------------------------------+ |
| 50 |html/ |Web interface templates, images and style sheets | | 50 |html/ |Web interface templates, images and style sheets | |
| 51 +-------------------+--------------------------------------------------------+ | 51 +-------------------+--------------------------------------------------------+ |
| 52 | 52 |
| 53 Instance Configuration | 53 Tracker Configuration |
| 54 ---------------------- | 54 --------------------- |
| 55 | 55 |
| 56 The instance_config.py located in your instance home contains the basic | 56 The config.py located in your tracker home contains the basic |
| 57 configuration for the web and e-mail components of roundup's interfaces. This | 57 configuration for the web and e-mail components of roundup's interfaces. This |
| 58 file is a Python module. The configuration variables available are: | 58 file is a Python module. The configuration variables available are: |
| 59 | 59 |
| 60 **INSTANCE_HOME** - ``os.path.split(__file__)[0]`` | 60 **INSTANCE_HOME** - ``os.path.split(__file__)[0]`` |
| 61 The instance home directory. The above default code will automatically | 61 The tracker home directory. The above default code will automatically |
| 62 determine the instance home for you. | 62 determine the tracker home for you. |
| 63 | 63 |
| 64 **MAILHOST** - ``'localhost'`` | 64 **MAILHOST** - ``'localhost'`` |
| 65 The SMTP mail host that roundup will use to send e-mail. | 65 The SMTP mail host that roundup will use to send e-mail. |
| 66 | 66 |
| 67 **MAIL_DOMAIN** - ``'your.tracker.email.domain.example'`` | 67 **MAIL_DOMAIN** - ``'your.tracker.email.domain.example'`` |
| 68 The domain name used for email addresses. | 68 The domain name used for email addresses. |
| 69 | 69 |
| 70 **DATABASE** - ``os.path.join(INSTANCE_HOME, 'db')`` | 70 **DATABASE** - ``os.path.join(INSTANCE_HOME, 'db')`` |
| 71 This is the directory that the database is going to be stored in. By default | 71 This is the directory that the database is going to be stored in. By default |
| 72 it is in the instance home. | 72 it is in the tracker home. |
| 73 | 73 |
| 74 **TEMPLATES** - ``os.path.join(INSTANCE_HOME, 'html')`` | 74 **TEMPLATES** - ``os.path.join(INSTANCE_HOME, 'html')`` |
| 75 This is the directory that the HTML templates reside in. By default they are | 75 This is the directory that the HTML templates reside in. By default they are |
| 76 in the instance home. | 76 in the tracker home. |
| 77 | 77 |
| 78 **INSTANCE_NAME** - ``'Roundup issue tracker'`` | 78 **INSTANCE_NAME** - ``'Roundup issue tracker'`` |
| 79 A descriptive name for your roundup instance. This is sent out in e-mails and | 79 A descriptive name for your roundup tracker. This is sent out in e-mails and |
| 80 appears in the heading of CGI pages. | 80 appears in the heading of CGI pages. |
| 81 | 81 |
| 82 **ISSUE_TRACKER_EMAIL** - ``'issue_tracker@%s'%MAIL_DOMAIN`` | 82 **ISSUE_TRACKER_EMAIL** - ``'issue_tracker@%s'%MAIL_DOMAIN`` |
| 83 The email address that e-mail sent to roundup should go to. Think of it as the | 83 The email address that e-mail sent to roundup should go to. Think of it as the |
| 84 instance's personal e-mail address. | 84 tracker's personal e-mail address. |
| 85 | 85 |
| 86 **ISSUE_TRACKER_WEB** - ``'http://your.tracker.url.example/'`` | 86 **ISSUE_TRACKER_WEB** - ``'http://your.tracker.url.example/'`` |
| 87 The web address that the instance is viewable at. This will be included in | 87 The web address that the tracker is viewable at. This will be included in |
| 88 information sent to users of the tracker. | 88 information sent to users of the tracker. |
| 89 | 89 |
| 90 **ADMIN_EMAIL** - ``'roundup-admin@%s'%MAIL_DOMAIN`` | 90 **ADMIN_EMAIL** - ``'roundup-admin@%s'%MAIL_DOMAIN`` |
| 91 The email address that roundup will complain to if it runs into trouble. | 91 The email address that roundup will complain to if it runs into trouble. |
| 92 | 92 |
| 170 Default is all. | 170 Default is all. |
| 171 **COLUMNS** - ``['id','activity','title','creator','assignedto']`` | 171 **COLUMNS** - ``['id','activity','title','creator','assignedto']`` |
| 172 Selects the columns that should be displayed. Default is all. | 172 Selects the columns that should be displayed. Default is all. |
| 173 **FILTERSPEC** - *a dictionary giving the filter specification* | 173 **FILTERSPEC** - *a dictionary giving the filter specification* |
| 174 The ``FILTERSPEC`` gives the filtering arguments. This selects the values | 174 The ``FILTERSPEC`` gives the filtering arguments. This selects the values |
| 175 the node properties given by propname must have. | 175 the item properties given by propname must have. |
| 176 | 176 |
| 177 Where the ``FILTERSPEC`` value is ``'CURRENT USER'``, it will be replaced | 177 Where the ``FILTERSPEC`` value is ``'CURRENT USER'``, it will be replaced |
| 178 by the id of the logged-in user. For example:: | 178 by the id of the logged-in user. For example:: |
| 179 | 179 |
| 180 'FILTERSPEC': { | 180 'FILTERSPEC': { |
| 181 'status': ['-1', '1', '2', '3', '4', '5', '6', '7'], | 181 'status': ['-1', '1', '2', '3', '4', '5', '6', '7'], |
| 182 'assignedto': 'CURRENT USER', | 182 'assignedto': 'CURRENT USER', |
| 183 }, | 183 }, |
| 184 | 184 |
| 185 **HEADER_ADD_LINKS** - ``['issue']`` | 185 **HEADER_ADD_LINKS** - ``['issue']`` |
| 186 List the classes that users are able to add nodes to. | 186 List the classes that users are able to add items to. |
| 187 | 187 |
| 188 **HEADER_SEARCH_LINKS** - ``['issue']`` | 188 **HEADER_SEARCH_LINKS** - ``['issue']`` |
| 189 List the classes that users can search. | 189 List the classes that users can search. |
| 190 | 190 |
| 191 **SEARCH_FILTERS** - ``['ISSUE_FILTER', 'SUPPORT_FILTER']`` | 191 **SEARCH_FILTERS** - ``['ISSUE_FILTER', 'SUPPORT_FILTER']`` |
| 204 The class that the search page is for. | 204 The class that the search page is for. |
| 205 **FILTER** - ``['status', 'priority', 'assignedto', 'creator']`` | 205 **FILTER** - ``['status', 'priority', 'assignedto', 'creator']`` |
| 206 Selects which props should be displayed on the filter page. Default is | 206 Selects which props should be displayed on the filter page. Default is |
| 207 all. | 207 all. |
| 208 | 208 |
| 209 The default instance_config.py is given below - as you | 209 The default config.py is given below - as you |
| 210 can see, the MAIL_DOMAIN must be edited before any interaction with the | 210 can see, the MAIL_DOMAIN must be edited before any interaction with the |
| 211 instance is attempted.:: | 211 tracker is attempted.:: |
| 212 | 212 |
| 213 # roundup home is this package's directory | 213 # roundup home is this package's directory |
| 214 INSTANCE_HOME=os.path.split(__file__)[0] | 214 INSTANCE_HOME=os.path.split(__file__)[0] |
| 215 | 215 |
| 216 # The SMTP mail host that roundup will use to send mail | 216 # The SMTP mail host that roundup will use to send mail |
| 227 DATABASE = os.path.join(INSTANCE_HOME, 'db') | 227 DATABASE = os.path.join(INSTANCE_HOME, 'db') |
| 228 | 228 |
| 229 # This is the directory that the HTML templates reside in | 229 # This is the directory that the HTML templates reside in |
| 230 TEMPLATES = os.path.join(INSTANCE_HOME, 'html') | 230 TEMPLATES = os.path.join(INSTANCE_HOME, 'html') |
| 231 | 231 |
| 232 # A descriptive name for your roundup instance | 232 # A descriptive name for your roundup tracker |
| 233 INSTANCE_NAME = 'Roundup issue tracker' | 233 INSTANCE_NAME = 'Roundup issue tracker' |
| 234 | 234 |
| 235 # The email address that mail to roundup should go to | 235 # The email address that mail to roundup should go to |
| 236 ISSUE_TRACKER_EMAIL = 'issue_tracker@%s'%MAIL_DOMAIN | 236 ISSUE_TRACKER_EMAIL = 'issue_tracker@%s'%MAIL_DOMAIN |
| 237 | 237 |
| 238 # The web address that the instance is viewable at | 238 # The web address that the tracker is viewable at |
| 239 ISSUE_TRACKER_WEB = 'http://your.tracker.url.example/' | 239 ISSUE_TRACKER_WEB = 'http://your.tracker.url.example/' |
| 240 | 240 |
| 241 # The email address that roundup will complain to if it runs into trouble | 241 # The email address that roundup will complain to if it runs into trouble |
| 242 ADMIN_EMAIL = 'roundup-admin@%s'%MAIL_DOMAIN | 242 ADMIN_EMAIL = 'roundup-admin@%s'%MAIL_DOMAIN |
| 243 | 243 |
| 284 # subjects. To disable, comment out the variable below or leave it blank. | 284 # subjects. To disable, comment out the variable below or leave it blank. |
| 285 # Examples: | 285 # Examples: |
| 286 MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default | 286 MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default |
| 287 #MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out) | 287 #MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out) |
| 288 | 288 |
| 289 Instance Schema | 289 Tracker Schema |
| 290 --------------- | 290 -------------- |
| 291 | 291 |
| 292 Note: if you modify the schema, you'll most likely need to edit the | 292 Note: if you modify the schema, you'll most likely need to edit the |
| 293 `web interface`_ HTML template files and `detectors`_ to reflect | 293 `web interface`_ HTML template files and `detectors`_ to reflect |
| 294 your changes. | 294 your changes. |
| 295 | 295 |
| 296 An instance schema defines what data is stored in the instance's database. The | 296 A tracker schema defines what data is stored in the tracker's database. The |
| 297 two schemas shipped with Roundup turn it into a typical software bug tracker | 297 two schemas shipped with Roundup turn it into a typical software bug tracker |
| 298 (the extended schema allowing for support issues as well as bugs). Schemas are | 298 (the extended schema allowing for support issues as well as bugs). Schemas are |
| 299 defined using Python code. The "classic" schema looks like this:: | 299 defined using Python code. The "classic" schema looks like this:: |
| 300 | 300 |
| 301 pri = Class(db, "priority", name=String(), order=String()) | 301 pri = Class(db, "priority", name=String(), order=String()) |
| 323 user = Class(db, "user", username=String(), password=String(), | 323 user = Class(db, "user", username=String(), password=String(), |
| 324 address=String(), realname=String(), phone=String(), | 324 address=String(), realname=String(), phone=String(), |
| 325 organisation=String()) | 325 organisation=String()) |
| 326 user.setkey("username") | 326 user.setkey("username") |
| 327 user.create(username="admin", password=adminpw, | 327 user.create(username="admin", password=adminpw, |
| 328 address=instance_config.ADMIN_EMAIL) | 328 address=config.ADMIN_EMAIL) |
| 329 | 329 |
| 330 msg = FileClass(db, "msg", author=Link("user"), recipients=Multilink | 330 msg = FileClass(db, "msg", author=Link("user"), recipients=Multilink |
| 331 ("user"), date=Date(), summary=String(), files=Multilink("file")) | 331 ("user"), date=Date(), summary=String(), files=Multilink("file")) |
| 332 | 332 |
| 333 file = FileClass(db, "file", name=String(), type=String()) | 333 file = FileClass(db, "file", name=String(), type=String()) |
| 340 XXX security definitions | 340 XXX security definitions |
| 341 | 341 |
| 342 Classes and Properties - creating a new information store | 342 Classes and Properties - creating a new information store |
| 343 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 343 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 344 | 344 |
| 345 In the instance above, we've defined 7 classes of information: | 345 In the tracker above, we've defined 7 classes of information: |
| 346 | 346 |
| 347 priority | 347 priority |
| 348 Defines the possible levels of urgency for issues. | 348 Defines the possible levels of urgency for issues. |
| 349 | 349 |
| 350 status | 350 status |
| 376 Class and Nodes | 376 Class and Nodes |
| 377 ::::::::::::::: | 377 ::::::::::::::: |
| 378 | 378 |
| 379 A Class defines a particular class (or type) of data that will be stored in the | 379 A Class defines a particular class (or type) of data that will be stored in the |
| 380 database. A class comprises one or more properties, which given the information | 380 database. A class comprises one or more properties, which given the information |
| 381 about the class nodes. | 381 about the class items. |
| 382 The actual data entered into the database, using class.create() are called | 382 The actual data entered into the database, using class.create() are called |
| 383 nodes. They have a special immutable property called id. We sometimes refer to | 383 items. They have a special immutable property called id. We sometimes refer to |
| 384 this as the nodeid. | 384 this as the itemid. |
| 385 | 385 |
| 386 Properties | 386 Properties |
| 387 :::::::::: | 387 :::::::::: |
| 388 | 388 |
| 389 A Class is comprised of one or more properties of the following types: | 389 A Class is comprised of one or more properties of the following types: |
| 390 * String properties are for storing arbitrary-length strings. | 390 * String properties are for storing arbitrary-length strings. |
| 391 * Password properties are for storing encoded arbitrary-length strings. The | 391 * Password properties are for storing encoded arbitrary-length strings. The |
| 392 default encoding is defined on the roundup.password.Password class. | 392 default encoding is defined on the roundup.password.Password class. |
| 393 * Date properties store date-and-time stamps. Their values are Timestamp | 393 * Date properties store date-and-time stamps. Their values are Timestamp |
| 394 objects. | 394 objects. |
| 395 * A Link property refers to a single other node selected from a specified | 395 * A Link property refers to a single other item selected from a specified |
| 396 class. The class is part of the property; the value is an integer, the id | 396 class. The class is part of the property; the value is an integer, the id |
| 397 of the chosen node. | 397 of the chosen item. |
| 398 * A Multilink property refers to possibly many nodes in a specified class. | 398 * A Multilink property refers to possibly many items in a specified class. |
| 399 The value is a list of integers. | 399 The value is a list of integers. |
| 400 | 400 |
| 401 FileClass | 401 FileClass |
| 402 ::::::::: | 402 ::::::::: |
| 403 | 403 |
| 404 FileClasses save their "content" attribute off in a separate file from the rest | 404 FileClasses save their "content" attribute off in a separate file from the rest |
| 405 of the database. This reduces the number of large entries in the database, | 405 of the database. This reduces the number of large entries in the database, |
| 406 which generally makes databases more efficient, and also allows us to use | 406 which generally makes databases more efficient, and also allows us to use |
| 407 command-line tools to operate on the files. They are stored in the files sub- | 407 command-line tools to operate on the files. They are stored in the files sub- |
| 408 directory of the db directory in your instance. | 408 directory of the db directory in your tracker. |
| 409 | 409 |
| 410 IssueClass | 410 IssueClass |
| 411 :::::::::: | 411 :::::::::: |
| 412 | 412 |
| 413 IssueClasses automatically include the "messages", "files", "nosy", and | 413 IssueClasses automatically include the "messages", "files", "nosy", and |
| 418 are sent to or generated by the issue. The nosy reactor (in the detectors | 418 are sent to or generated by the issue. The nosy reactor (in the detectors |
| 419 directory) handles this action. The superceder link indicates an issue which | 419 directory) handles this action. The superceder link indicates an issue which |
| 420 has superceded this one. | 420 has superceded this one. |
| 421 They also have the dynamically generated "creation", "activity" and "creator" | 421 They also have the dynamically generated "creation", "activity" and "creator" |
| 422 properties. | 422 properties. |
| 423 The value of the "creation" property is the date when a node was created, and | 423 The value of the "creation" property is the date when a item was created, and |
| 424 the value of the "activity" property is the date when any property on the node | 424 the value of the "activity" property is the date when any property on the item |
| 425 was last edited (equivalently, these are the dates on the first and last | 425 was last edited (equivalently, these are the dates on the first and last |
| 426 records in the node's journal). The "creator" property holds a link to the user | 426 records in the item's journal). The "creator" property holds a link to the user |
| 427 that created the issue. | 427 that created the issue. |
| 428 | 428 |
| 429 setkey(property) | 429 setkey(property) |
| 430 :::::::::::::::: | 430 :::::::::::::::: |
| 431 | 431 |
| 432 Select a String property of the class to be the key property. The key property | 432 Select a String property of the class to be the key property. The key property |
| 433 muse be unique, and allows references to the nodes in the class by the content | 433 muse be unique, and allows references to the items in the class by the content |
| 434 of the key property. That is, we can refer to users by their username, e.g. | 434 of the key property. That is, we can refer to users by their username, e.g. |
| 435 let's say that there's an issue in roundup, issue 23. There's also a user, | 435 let's say that there's an issue in roundup, issue 23. There's also a user, |
| 436 richard who happens to be user 2. To assign an issue to him, we could do either | 436 richard who happens to be user 2. To assign an issue to him, we could do either |
| 437 of:: | 437 of:: |
| 438 | 438 |
| 445 Note, the same thing can be done in the web and e-mail interfaces. | 445 Note, the same thing can be done in the web and e-mail interfaces. |
| 446 | 446 |
| 447 create(information) | 447 create(information) |
| 448 ::::::::::::::::::: | 448 ::::::::::::::::::: |
| 449 | 449 |
| 450 Create a node in the database. This is generally used to create nodes in the | 450 Create a item in the database. This is generally used to create items in the |
| 451 "definitional" classes like "priority" and "status". | 451 "definitional" classes like "priority" and "status". |
| 452 | 452 |
| 453 | 453 |
| 454 Examples of adding to your schema | 454 Examples of adding to your schema |
| 455 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 455 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 459 | 459 |
| 460 Detectors - adding behaviour to your tracker | 460 Detectors - adding behaviour to your tracker |
| 461 -------------------------------------------- | 461 -------------------------------------------- |
| 462 .. _detectors: | 462 .. _detectors: |
| 463 | 463 |
| 464 The detectors in your instance fire before (*auditors*) and after (*reactors*) | 464 The detectors in your tracker fire before (*auditors*) and after (*reactors*) |
| 465 changes to the contents of your database. They are Python modules that sit in | 465 changes to the contents of your database. They are Python modules that sit in |
| 466 your instance's ``detectors`` directory. You will have some installed by | 466 your tracker's ``detectors`` directory. You will have some installed by |
| 467 default - have a look. You can write new detectors or modify the existing | 467 default - have a look. You can write new detectors or modify the existing |
| 468 ones. The existing detectors installed for you are: | 468 ones. The existing detectors installed for you are: |
| 469 | 469 |
| 470 **nosyreaction.py** | 470 **nosyreaction.py** |
| 471 This provides the automatic nosy list maintenance and email sending. The nosy | 471 This provides the automatic nosy list maintenance and email sending. The nosy |
| 474 what changes need to be made to the nosy list (like adding new authors etc) | 474 what changes need to be made to the nosy list (like adding new authors etc) |
| 475 **statusauditor.py** | 475 **statusauditor.py** |
| 476 This provides the ``chatty`` auditor which changes the issue status from | 476 This provides the ``chatty`` auditor which changes the issue status from |
| 477 ``unread`` or ``closed`` to ``chatting`` if new messages appear. It also | 477 ``unread`` or ``closed`` to ``chatting`` if new messages appear. It also |
| 478 provides the ``presetunread`` auditor which pre-sets the status to | 478 provides the ``presetunread`` auditor which pre-sets the status to |
| 479 ``unread`` on new nodes if the status isn't explicitly defined. | 479 ``unread`` on new items if the status isn't explicitly defined. |
| 480 | 480 |
| 481 See the detectors section in the `design document`__ for details of the | 481 See the detectors section in the `design document`__ for details of the |
| 482 interface for detectors. | 482 interface for detectors. |
| 483 | 483 |
| 484 __ design.html | 484 __ design.html |
| 494 | 494 |
| 495 Database Content | 495 Database Content |
| 496 ---------------- | 496 ---------------- |
| 497 | 497 |
| 498 Note: if you modify the content of definitional classes, you'll most likely | 498 Note: if you modify the content of definitional classes, you'll most likely |
| 499 need to edit the instance `detectors`_ to reflect your changes. | 499 need to edit the tracker `detectors`_ to reflect your changes. |
| 500 | 500 |
| 501 Customisation of the special "definitional" classes (eg. status, priority, | 501 Customisation of the special "definitional" classes (eg. status, priority, |
| 502 resolution, ...) may be done either before or after the instance is | 502 resolution, ...) may be done either before or after the tracker is |
| 503 initialised. The actual method of doing so is completely different in each | 503 initialised. The actual method of doing so is completely different in each |
| 504 case though, so be careful to use the right one. | 504 case though, so be careful to use the right one. |
| 505 | 505 |
| 506 **Changing content before instance initialisation** | 506 **Changing content before tracker initialisation** |
| 507 Edit the dbinit module in your instance to alter the nodes created in using | 507 Edit the dbinit module in your tracker to alter the items created in using |
| 508 the create() methods. | 508 the create() methods. |
| 509 | 509 |
| 510 | 510 |
| 511 **Changing content after instance initialisation** | 511 **Changing content after tracker initialisation** |
| 512 Use the roundup-admin interface's create, set and retire methods to add, | 512 Use the roundup-admin interface's create, set and retire methods to add, |
| 513 alter or remove nodes from the classes in question. | 513 alter or remove items from the classes in question. |
| 514 | 514 |
| 515 | 515 |
| 516 | 516 |
| 517 Web Interface | 517 Web Interface |
| 518 ------------- | 518 ------------- |
| 519 | 519 |
| 520 The web interface works behind the cgi-bin/roundup.cgi or roundup-server | 520 The web interface works behind the cgi-bin/roundup.cgi or roundup-server |
| 521 scripts. In both cases, the scripts determine which instance is being accessed | 521 scripts. In both cases, the scripts determine which tracker is being accessed |
| 522 (the first part of the URL path inside the scope of the CGI handler) and pass | 522 (the first part of the URL path inside the scope of the CGI handler) and pass |
| 523 control on to the instance interfaces.Client class which handles the rest of | 523 control on to the tracker interfaces.Client class which handles the rest of |
| 524 the access through its main() method. This means that you can do pretty much | 524 the access through its main() method. This means that you can do pretty much |
| 525 anything you want as a web interface to your instance. | 525 anything you want as a web interface to your tracker. |
| 526 | 526 |
| 527 Figuring out what is displayed | 527 Figuring out what is displayed |
| 528 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 528 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 529 | 529 |
| 530 Most customisation of the web view can be done by modifying the templates in | 530 Most customisation of the web view can be done by modifying the templates in |
| 531 the instance **html** directory. There are several types of files in there: | 531 the tracker **html** directory. There are several types of files in there: |
| 532 | 532 |
| 533 page | 533 page |
| 534 defines the overall look of your tracker. When you | 534 defines the overall look of your tracker. When you |
| 535 view an issue, it appears inside this template. When you view an index, it | 535 view an issue, it appears inside this template. When you view an index, it |
| 536 also appears inside this template. | 536 also appears inside this template. |
| 579 | 579 |
| 580 Determining web context | 580 Determining web context |
| 581 ~~~~~~~~~~~~~~~~~~~~~~~ | 581 ~~~~~~~~~~~~~~~~~~~~~~~ |
| 582 | 582 |
| 583 To determine the "context" of a request, we look at the URL and the special | 583 To determine the "context" of a request, we look at the URL and the special |
| 584 request variable ``:template``. The URL path after the instance identifier | 584 request variable ``:template``. The URL path after the tracker identifier |
| 585 is examined. Typical URL paths look like: | 585 is examined. Typical URL paths look like: |
| 586 | 586 |
| 587 1. ``/tracker/issue`` | 587 1. ``/tracker/issue`` |
| 588 2. ``/tracker/issue1`` | 588 2. ``/tracker/issue1`` |
| 589 3. ``/tracker/_file/style.css`` | 589 3. ``/tracker/_file/style.css`` |
| 590 4. ``/cgi-bin/roundup.cgi/tracker/file1`` | 590 4. ``/cgi-bin/roundup.cgi/tracker/file1`` |
| 591 5. ``/cgi-bin/roundup.cgi/tracker/file1/kitten.png`` | 591 5. ``/cgi-bin/roundup.cgi/tracker/file1/kitten.png`` |
| 592 | 592 |
| 593 where the "instance identifier" is "tracker" in the above cases. That means | 593 where the "tracker identifier" is "tracker" in the above cases. That means |
| 594 we're looking at "issue", "issue1", "_file/style.css", "file1" and | 594 we're looking at "issue", "issue1", "_file/style.css", "file1" and |
| 595 "file1/kitten.png" in the cases above. The path is generally only one | 595 "file1/kitten.png" in the cases above. The path is generally only one |
| 596 entry long - longer paths are handled differently. | 596 entry long - longer paths are handled differently. |
| 597 | 597 |
| 598 a. if there is no path, then we are in the "home" context. | 598 a. if there is no path, then we are in the "home" context. |
| 599 b. if the path starts with "_file" (as in example 3, | 599 b. if the path starts with "_file" (as in example 3, |
| 600 "/tracker/_file/style.css"), then the additional path entry, | 600 "/tracker/_file/style.css"), then the additional path entry, |
| 601 "style.css" specifies the filename of a static file we're to serve up | 601 "style.css" specifies the filename of a static file we're to serve up |
| 602 from the instance "html" directory. Raises a SendStaticFile | 602 from the tracker "html" directory. Raises a SendStaticFile |
| 603 exception. | 603 exception. |
| 604 c. if there is something in the path (as in example 1, "issue"), it identifies | 604 c. if there is something in the path (as in example 1, "issue"), it identifies |
| 605 the tracker class we're to display. | 605 the tracker class we're to display. |
| 606 d. if the path is an item designator (as in examples 2 and 4, "issue1" and | 606 d. if the path is an item designator (as in examples 2 and 4, "issue1" and |
| 607 "file1"), then we're to display a specific item. | 607 "file1"), then we're to display a specific item. |
| 642 edit | 642 edit |
| 643 Perform an edit of an item in the database. There are some special form | 643 Perform an edit of an item in the database. There are some special form |
| 644 elements you may use: | 644 elements you may use: |
| 645 | 645 |
| 646 :link=designator:property and :multilink=designator:property | 646 :link=designator:property and :multilink=designator:property |
| 647 The value specifies a node designator and the property on that | 647 The value specifies an item designator and the property on that |
| 648 node to add _this_ node to as a link or multilink. | 648 item to add _this_ item to as a link or multilink. |
| 649 __note | 649 :note |
| 650 Create a message and attach it to the current node's | 650 Create a message and attach it to the current item's |
| 651 "messages" property. | 651 "messages" property. |
| 652 __file | 652 :file |
| 653 Create a file and attach it to the current node's | 653 Create a file and attach it to the current item's |
| 654 "files" property. Attach the file to the message created from | 654 "files" property. Attach the file to the message created from |
| 655 the __note if it's supplied. | 655 the __note if it's supplied. |
| 656 :required=property,property,... | 656 :required=property,property,... |
| 657 The named properties are required to be filled in the form. | 657 The named properties are required to be filled in the form. |
| 658 | 658 |
| 675 Also handle the ":queryname" variable and save off the query to | 675 Also handle the ":queryname" variable and save off the query to |
| 676 the user's query list. | 676 the user's query list. |
| 677 | 677 |
| 678 Each of the actions is implemented by a corresponding *actionAction* (where | 678 Each of the actions is implemented by a corresponding *actionAction* (where |
| 679 "action" is the name of the action) method on | 679 "action" is the name of the action) method on |
| 680 the roundup.cgi.Client class, which also happens to be in your instance as | 680 the roundup.cgi.Client class, which also happens to be in your tracker as |
| 681 interfaces.Client. So if you need to define new actions, you may add them | 681 interfaces.Client. So if you need to define new actions, you may add them |
| 682 there (see `definining new web actions`_). | 682 there (see `definining new web actions`_). |
| 683 | 683 |
| 684 Each action also has a corresponding *actionPermission* (where | 684 Each action also has a corresponding *actionPermission* (where |
| 685 "action" is the name of the action) method which determines | 685 "action" is the name of the action) method which determines |
| 711 search | 711 search |
| 712 Determine whether the user has permission to search this class. | 712 Determine whether the user has permission to search this class. |
| 713 Base behaviour is to check the user can view this class. | 713 Base behaviour is to check the user can view this class. |
| 714 | 714 |
| 715 | 715 |
| 716 Repurcussions of changing the instance schema | 716 Repurcussions of changing the tracker schema |
| 717 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 717 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 718 | 718 |
| 719 If you choose to change the `instance schema`_ you will need to ensure the web | 719 If you choose to change the `tracker schema`_ you will need to ensure the web |
| 720 interface knows about it: | 720 interface knows about it: |
| 721 | 721 |
| 722 1. Index, item and search pages for the relevant classes may need to have | 722 1. Index, item and search pages for the relevant classes may need to have |
| 723 properties added or removed, | 723 properties added or removed, |
| 724 2. The "page" template may require links to be changed, as might the "home" | 724 2. The "page" template may require links to be changed, as might the "home" |
| 725 page's content arguments. | 725 page's content arguments. |
| 726 | 726 |
| 727 Overall Look - "page" template | 727 Overall Look - "page" template |
| 728 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 728 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 729 | 729 |
| 730 The "page" template in your instances | 730 XXX |
| 731 roundup.cgi_client.Class. This class is mixed-in to your instance through the | |
| 732 instance's interfaces module. This means you can override the header and | |
| 733 footer with your own code. This allows you to use a sidebar navigation scheme, | |
| 734 for example. | |
| 735 | |
| 736 | 731 |
| 737 How the templates work | 732 How the templates work |
| 738 ~~~~~~~~~~~~~~~~~~~~~~ | 733 ~~~~~~~~~~~~~~~~~~~~~~ |
| 739 | 734 |
| 740 Roundup's templates consist of special attributes on your template tags. These | 735 Roundup's templates consist of special attributes on your template tags. These |
| 871 Includes information about the current request, including: | 866 Includes information about the current request, including: |
| 872 - the url | 867 - the url |
| 873 - the current index information (``filterspec``, ``filter`` args, | 868 - the current index information (``filterspec``, ``filter`` args, |
| 874 ``properties``, etc) parsed out of the form. | 869 ``properties``, etc) parsed out of the form. |
| 875 - methods for easy filterspec link generation | 870 - methods for easy filterspec link generation |
| 876 - *user*, the current user node as an HTMLItem instance | 871 - *user*, the current user item as an HTMLItem instance |
| 877 - *form* | 872 - *form* |
| 878 The current CGI form information as a mapping of form argument | 873 The current CGI form information as a mapping of form argument |
| 879 name to value | 874 name to value |
| 880 *instance* | 875 *tracker* |
| 881 The current instance | 876 The current tracker |
| 882 *db* | 877 *db* |
| 883 The current database, through which db.config may be reached. | 878 The current database, through which db.config may be reached. |
| 884 *nothing* | 879 *nothing* |
| 885 XXX a special variable | 880 XXX a special variable |
| 886 *default* | 881 *default* |
| 918 Variable Holds | 913 Variable Holds |
| 919 =========== ================================================================ | 914 =========== ================================================================ |
| 920 form the CGI form as a cgi.FieldStorage | 915 form the CGI form as a cgi.FieldStorage |
| 921 env the CGI environment variables | 916 env the CGI environment variables |
| 922 url the current URL path for this request | 917 url the current URL path for this request |
| 923 base the base URL for this instance | 918 base the base URL for this tracker |
| 924 user a HTMLUser instance for this user | 919 user a HTMLUser instance for this user |
| 925 classname the current classname (possibly None) | 920 classname the current classname (possibly None) |
| 926 template the current template (suffix, also possibly None) | 921 template the current template (suffix, also possibly None) |
| 927 form the current CGI form variables in a FieldStorage | 922 form the current CGI form variables in a FieldStorage |
| 928 =========== ================================================================ | 923 =========== ================================================================ |
| 973 :filters=status,topic& | 968 :filters=status,topic& |
| 974 :columns=title,status,fixer | 969 :columns=title,status,fixer |
| 975 | 970 |
| 976 The index view is determined by two parts of the specifier: the layout part and | 971 The index view is determined by two parts of the specifier: the layout part and |
| 977 the filter part. The layout part consists of the query parameters that begin | 972 the filter part. The layout part consists of the query parameters that begin |
| 978 with colons, and it determines the way that the properties of selected nodes | 973 with colons, and it determines the way that the properties of selected items |
| 979 are displayed. The filter part consists of all the other query parameters, and | 974 are displayed. The filter part consists of all the other query parameters, and |
| 980 it determines the criteria by which nodes are selected for display. | 975 it determines the criteria by which items are selected for display. |
| 981 The filter part is interactively manipulated with the form widgets displayed in | 976 The filter part is interactively manipulated with the form widgets displayed in |
| 982 the filter section. The layout part is interactively manipulated by clicking on | 977 the filter section. The layout part is interactively manipulated by clicking on |
| 983 the column headings in the table. | 978 the column headings in the table. |
| 984 | 979 |
| 985 The filter part selects the union of the sets of items with values matching any | 980 The filter part selects the union of the sets of items with values matching any |
| 986 specified Link properties and the intersection of the sets of items with values | 981 specified Link properties and the intersection of the sets of items with values |
| 987 matching any specified Multilink properties. | 982 matching any specified Multilink properties. |
| 988 | 983 |
| 989 The example specifies an index of "issue" nodes. Only items with a "status" of | 984 The example specifies an index of "issue" items. Only items with a "status" of |
| 990 either "unread" or "in-progres" or "resolved" are displayed, and only items | 985 either "unread" or "in-progres" or "resolved" are displayed, and only items |
| 991 with "topic" values including both "security" and "ui" are displayed. The items | 986 with "topic" values including both "security" and "ui" are displayed. The items |
| 992 are grouped by priority, arranged in ascending order; and within groups, sorted | 987 are grouped by priority, arranged in ascending order; and within groups, sorted |
| 993 by activity, arranged in descending order. The filter section shows filters for | 988 by activity, arranged in descending order. The filter section shows filters for |
| 994 the "status" and "topic" properties, and the table includes columns for the | 989 the "status" and "topic" properties, and the table includes columns for the |
| 1064 </tr> | 1059 </tr> |
| 1065 | 1060 |
| 1066 <tr> | 1061 <tr> |
| 1067 <th nowrap>Change Note</th> | 1062 <th nowrap>Change Note</th> |
| 1068 <td colspan=3> | 1063 <td colspan=3> |
| 1069 <textarea name="__note" wrap="hard" rows="5" cols="60"></textarea> | 1064 <textarea name=":note" wrap="hard" rows="5" cols="60"></textarea> |
| 1070 </td> | 1065 </td> |
| 1071 </tr> | 1066 </tr> |
| 1072 | 1067 |
| 1073 <tr> | 1068 <tr> |
| 1074 <th nowrap>File</th> | 1069 <th nowrap>File</th> |
| 1075 <td colspan=3><input type="file" name="__file" size="40"></td> | 1070 <td colspan=3><input type="file" name=":file" size="40"></td> |
| 1076 </tr> | 1071 </tr> |
| 1077 | 1072 |
| 1078 <tr> | 1073 <tr> |
| 1079 <td> </td> | 1074 <td> </td> |
| 1080 <td colspan=3 tal:content="structure context/submit"> | 1075 <td colspan=3 tal:content="structure context/submit"> |
| 1084 </table> | 1079 </table> |
| 1085 | 1080 |
| 1086 | 1081 |
| 1087 When a change is submitted, the system automatically generates a message | 1082 When a change is submitted, the system automatically generates a message |
| 1088 describing the changed properties. As shown in the example, the editor | 1083 describing the changed properties. As shown in the example, the editor |
| 1089 template can use the "__note" and "__file" fields, which are added to the | 1084 template can use the ":note" and ":file" fields, which are added to the |
| 1090 standard change note message generated by Roundup. | 1085 standard change note message generated by Roundup. |
| 1091 | 1086 |
| 1092 Spool Section | 1087 Spool Section |
| 1093 ::::::::::::: | 1088 ::::::::::::: |
| 1094 | 1089 |
| 1106 | 1101 |
| 1107 <tal:block tal:replace="structure context/history" /> | 1102 <tal:block tal:replace="structure context/history" /> |
| 1108 | 1103 |
| 1109 *To be done:* | 1104 *To be done:* |
| 1110 | 1105 |
| 1111 *The actual history entries of the node may be accessed for manual templating | 1106 *The actual history entries of the item may be accessed for manual templating |
| 1112 through the "journal" method of the item*:: | 1107 through the "journal" method of the item*:: |
| 1113 | 1108 |
| 1114 <tal:block tal:repeat="entry context/journal"> | 1109 <tal:block tal:repeat="entry context/journal"> |
| 1115 a journal entry | 1110 a journal entry |
| 1116 </tal:block> | 1111 </tal:block> |
| 1158 You may alter the configuration variables to change the Role that new web or | 1153 You may alter the configuration variables to change the Role that new web or |
| 1159 email users get, for example to not give them access to the web interface if | 1154 email users get, for example to not give them access to the web interface if |
| 1160 they register through email. | 1155 they register through email. |
| 1161 | 1156 |
| 1162 You may use the ``roundup-admin`` "``security``" command to display the | 1157 You may use the ``roundup-admin`` "``security``" command to display the |
| 1163 current Role and Permission configuration in your instance. | 1158 current Role and Permission configuration in your tracker. |
| 1164 | 1159 |
| 1165 Adding a new Permission | 1160 Adding a new Permission |
| 1166 ~~~~~~~~~~~~~~~~~~~~~~~ | 1161 ~~~~~~~~~~~~~~~~~~~~~~~ |
| 1167 | 1162 |
| 1168 When adding a new Permission, you will need to: | 1163 When adding a new Permission, you will need to: |
| 1169 | 1164 |
| 1170 1. add it to your instance's dbinit so it is created | 1165 1. add it to your tracker's dbinit so it is created |
| 1171 2. enable it for the Roles that should have it (verify with | 1166 2. enable it for the Roles that should have it (verify with |
| 1172 "``roundup-admin security``") | 1167 "``roundup-admin security``") |
| 1173 3. add it to the relevant HTML interface templates | 1168 3. add it to the relevant HTML interface templates |
| 1174 4. add it to the appropriate xxxPermission methods on in your instance | 1169 4. add it to the appropriate xxxPermission methods on in your tracker |
| 1175 interfaces module | 1170 interfaces module |
| 1176 | 1171 |
| 1177 | 1172 |
| 1178 | 1173 |
| 1179 ----------------- | 1174 ----------------- |
