comparison doc/customizing.txt @ 1262:a66dd1573ebd

new example
author Richard Jones <richard@users.sourceforge.net>
date Thu, 10 Oct 2002 07:24:13 +0000
parents e5af1b963837
children c3424abf7f77
comparison
equal deleted inserted replaced
1261:85d71588a1cf 1262:a66dd1573ebd
1 =================== 1 ===================
2 Customising Roundup 2 Customising Roundup
3 =================== 3 ===================
4 4
5 :Version: $Revision: 1.55 $ 5 :Version: $Revision: 1.56 $
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::
703 Perform an edit of an item in the database. There are some special form 703 Perform an edit of an item in the database. There are some special form
704 elements you may use: 704 elements you may use:
705 705
706 :link=designator:property and :multilink=designator:property 706 :link=designator:property and :multilink=designator:property
707 The value specifies an item designator and the property on that 707 The value specifies an item designator and the property on that
708 item to add _this_ item to as a link or multilink. 708 item to add *this* item to as a link or multilink.
709 :note 709 :note
710 Create a message and attach it to the current item's 710 Create a message and attach it to the current item's
711 "messages" property. 711 "messages" property.
712 :file 712 :file
713 Create a file and attach it to the current item's 713 Create a file and attach it to the current item's
2262 3. Determine what actions need to be taken between the pages - these are 2262 3. Determine what actions need to be taken between the pages - these are
2263 usually to validate user choices and determine what page is next. Now 2263 usually to validate user choices and determine what page is next. Now
2264 encode those actions in methods on the interfaces Client class and insert 2264 encode those actions in methods on the interfaces Client class and insert
2265 hooks to those actions in the "actions" attribute on that class, like so:: 2265 hooks to those actions in the "actions" attribute on that class, like so::
2266 2266
2267 actions = client.Class.actions + ( 2267 actions = client.Client.actions + (
2268 ('page1_submit', 'page1SubmitAction'), 2268 ('page1_submit', 'page1SubmitAction'),
2269 ) 2269 )
2270 2270
2271 def page1SubmitAction(self): 2271 def page1SubmitAction(self):
2272 ''' Verify that the user has selected a category, and then move on 2272 ''' Verify that the user has selected a category, and then move on
2409 sendto = [i for i in sendto if not users.get(i, 'vacation', 0)] 2409 sendto = [i for i in sendto if not users.get(i, 'vacation', 0)]
2410 2410
2411 which filters out the users that have the vacation flag set to true. 2411 which filters out the users that have the vacation flag set to true.
2412 2412
2413 2413
2414 Adding a time log to your issues
2415 --------------------------------
2416
2417 We want to log the dates and amount of time spent working on issues, and be
2418 able to give a summary of the total time spent on a particular issue.
2419
2420 1. Add a new class to your tracker ``dbinit.py``::
2421
2422 # storage for time logging
2423 timelog = Class(db, "timelog", period=Interval())
2424
2425 Note that we automatically get the date of the time log entry creation
2426 through the standard property "creation".
2427
2428 2. Link to the new class from your issue class (again, in ``dbinit.py``)::
2429
2430 issue = IssueClass(db, "issue",
2431 assignedto=Link("user"), topic=Multilink("keyword"),
2432 priority=Link("priority"), status=Link("status"),
2433 times=Multilink("timelog"))
2434
2435 the "times" property is the new link to the "timelog" class.
2436
2437 3. We'll need to let people add in times to the issue, so in the web interface
2438 we'll have a new entry field, just below the change note box::
2439
2440 <tr>
2441 <th nowrap>Time Log</th>
2442 <td colspan=3><input name=":timelog">
2443 (enter as "3y 1m 4d 2:40:02" or parts thereof)
2444 </td>
2445 </tr>
2446
2447 Note that we've made up a new form variable, but since we place a colon ":"
2448 in front of it, it won't clash with any existing property variables. The
2449 names you *can't* use are ``:note``, ``:file``, ``:action``, ``:required``
2450 and ``:template``. These variables are described in the section
2451 `performing actions in web requests`_.
2452
2453 4. We also need to handle this new field in the CGI interface - the way to
2454 do this is through implementing a new form action (see `Setting up a
2455 "wizard" (or "druid") for controlled adding of issues`_ for another example
2456 where we implemented a new CGI form action).
2457
2458 In this case, we'll want our action to:
2459
2460 1. create a new "timelog" entry,
2461 2. fake that the issue's "times" property has been edited, and then
2462 3. call the normal CGI edit action handler.
2463
2464 The code to do this is::
2465
2466 actions = client.Client.actions + (
2467 ('edit_with_timelog', 'timelogEditAction'),
2468 )
2469
2470 def timelogEditAction(self):
2471 ''' Handle the creation of a new time log entry if necessary.
2472
2473 If we create a new entry, fake up a CGI form value for the altered
2474 "times" property of the issue being edited.
2475
2476 Punt to the regular edit action when we're done.
2477 '''
2478 # if there's a timelog value specified, create an entry
2479 if self.form.has_key(':timelog') and \
2480 self.form[':timelog'].value.strip():
2481 period = Interval(self.form[':timelog'].value)
2482 # create it
2483 newid = self.db.timelog.create(period=period)
2484
2485 # if we're editing an existing item, get the old timelog value
2486 if self.nodeid:
2487 l = self.db.issue.get(self.nodeid, 'times')
2488 l.append(newid)
2489 else:
2490 l = [newid]
2491
2492 # now make the fake CGI form values
2493 for entry in l:
2494 self.form.list.append(MiniFieldStorage('times', entry))
2495
2496 # punt to the normal edit action
2497 return self.editItemAction()
2498
2499 you add this code to your Client class in your tracker's ``interfaces.py``
2500 file.
2501
2502 5. You'll also need to modify your ``issue.item`` form submit action so it
2503 calls the time logging action we just created::
2504
2505 <tr>
2506 <td>&nbsp;</td>
2507 <td colspan=3>
2508 <tal:block tal:condition="context/id">
2509 <input type="hidden" name=":action" value="edit_with_timelog">
2510 <input type="submit" name="submit" value="Submit Changes">
2511 </tal:block>
2512 <tal:block tal:condition="not:context/id">
2513 <input type="hidden" name=":action" value="new">
2514 <input type="submit" name="submit" value="Submit New Issue">
2515 </tal:block>
2516 </td>
2517 </tr>
2518
2519 Note that the "context/submit" command usually handles all that for you -
2520 isn't it handy? The important change is setting the action to
2521 "edit_with_timelog" for edit operations (where the item exists)
2522
2523 6. Display the time log for an issue::
2524
2525 <table class="otherinfo" tal:condition="context/times">
2526 <tr><th colspan="3" class="header">Time Log</th></tr>
2527 <tr><th>Date</th><th>Period</th><th>Logged By</th></tr>
2528 <tr tal:repeat="time context/times">
2529 <td tal:content="time/creation"></td>
2530 <td tal:content="time/period"></td>
2531 <td tal:content="time/creator"></td>
2532 </tr>
2533 </table>
2534
2535 I put this just above the Messages log in my issue display.
2536
2537 6. If you're using a persistent web server - roundup-server or mod_python for
2538 example - then you'll need to restart that to pick up the code changes.
2539 When that's done, you'll be able to use the new time logging interface.
2540
2541
2414 ------------------- 2542 -------------------
2415 2543
2416 Back to `Table of Contents`_ 2544 Back to `Table of Contents`_
2417 2545
2418 .. _`Table of Contents`: index.html 2546 .. _`Table of Contents`: index.html

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