22Customising Roundup
33===================
44
5- :Version: $Revision: 1.156 $
5+ :Version: $Revision: 1.157 $
66
77.. This document borrows from the ZopeBook section on ZPT. The original is at:
88 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
@@ -885,10 +885,10 @@ is used by ``roundup.cgi``, ``roundup-server`` and ``ZRoundup``
885885(``ZRoundup`` is broken, until further notice). In all cases, we
886886determine which tracker is being accessed (the first part of the URL
887887path inside the scope of the CGI handler) and pass control on to the
888- tracker ``interfaces. Client`` class - which uses the ``Client`` class
889- from ``roundup.cgi.client `` - which handles the rest of the access
890- through its ``main()`` method. This means that you can do pretty much
891- anything you want as a web interface to your tracker.
888+ ``roundup.cgi.client. Client`` class - which handles the rest of the
889+ access through its ``main() `` method. This means that you can do pretty
890+ much anything you want as a web interface to your tracker.
891+
892892
893893
894894Repercussions of changing the tracker schema
@@ -1051,9 +1051,8 @@ of:
10511051
10521052Each of the actions is implemented by a corresponding ``*XxxAction*`` (where
10531053"Xxx" is the name of the action) class in the ``roundup.cgi.actions`` module.
1054- These classes are registered with ``roundup.cgi.client.Client`` which also
1055- happens to be available in your tracker instance as ``interfaces.Client``. So
1056- if you need to define new actions, you may add them there (see `defining new
1054+ These classes are registered with ``roundup.cgi.client.Client``. If you need
1055+ to define new actions, you may add them there (see `defining new
10571056web actions`_).
10581057
10591058Each action class also has a ``*permission*`` method which determines whether
@@ -1995,7 +1994,9 @@ html_quote quote some text as safe in HTML (ie. <, >, ...)
19951994=============== ========================================================
19961995
19971996You may add additional utility methods by writing them in your tracker
1998- ``extensions`` directory and registering them with the templating system.
1997+ ``extensions`` directory and registering them with the templating system
1998+ using ``instance.registerUtil`` (see `adding a time log to your issues`_ for
1999+ an example of this).
19992000
20002001
20012002Batching
@@ -2336,8 +2337,10 @@ Defining new web actions
23362337------------------------
23372338
23382339You may define new actions to be triggered by the ``@action`` form variable.
2339- These are added to the tracker ``interfaces.py`` as ``Action`` classes that get
2340- called by the the ``Client`` class.
2340+ These are added to the tracker ``extensions`` directory and registered
2341+ using ``instance.registerAction``.
2342+
2343+ All the existing Actions are defined in ``roundup.cgi.actions``.
23412344
23422345Adding action classes takes three steps; first you `define the new
23432346action class`_, then you `register the action class`_ with the cgi
@@ -2351,16 +2354,16 @@ issues`_" for an example.
23512354Define the new action class
23522355~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23532356
2354- The action classes have the following interface::
2357+ Create a new action class in your tracker's ``extensions`` directory, for
2358+ example ``myaction.py``::
23552359
23562360 class MyAction(Action):
23572361 def handle(self):
23582362 ''' Perform some action. No return value is required.
23592363 '''
23602364
2361- The *self.client* attribute is an instance of your tracker ``instance.Client``
2362- class - thus it's mostly implemented by ``roundup.cgi.client.Client``. See the
2363- docstring of that class for details of what it can do.
2365+ The *self.client* attribute is an instance of ``roundup.cgi.client.Client``.
2366+ See the docstring of that class for details of what it can do.
23642367
23652368The method will typically check the ``self.form`` variable's contents.
23662369It may then:
@@ -2375,18 +2378,15 @@ It may then:
23752378Register the action class
23762379~~~~~~~~~~~~~~~~~~~~~~~~~~
23772380
2378- XXX update for new extensions setup (then search for interfaces.py and make
2379- sure there's no examples that use the old style)
2381+ The class is now written, but isn't available to the user until you register
2382+ it with the following code appended to your ``myaction.py`` file::
23802383
2381- The class is now written, but isn't available to the user until you add it to
2382- the ``instance.Client`` class ``actions`` variable, like so::
2383-
2384- actions = client.Client.actions + (
2385- ('myaction', myActionClass),
2386- )
2384+ def init(instance):
2385+ instance.registerAction('myaction', myActionClass)
23872386
23882387This maps the action name "myaction" to the action class we defined.
23892388
2389+
23902390Use the new action
23912391~~~~~~~~~~~~~~~~~~
23922392
@@ -2938,27 +2938,23 @@ be able to give a summary of the total time spent on a particular issue.
293829384. We want to display a total of the time log times that have been
29392939 accumulated for an issue. To do this, we'll need to actually write
29402940 some Python code, since it's beyond the scope of PageTemplates to
2941- perform such calculations. We do this by adding a method to the
2942- TemplatingUtils class in our tracker ``interfaces.py `` module ::
2941+ perform such calculations. We do this by adding a module ``timespent.py``
2942+ to the ``extensions `` directory in our tracker ::
29432943
2944- class TemplatingUtils :
2945- ''' Methods implemented on this class will be available to HTML
2946- templates through the 'utils' variable.
2944+ def totalTimeSpent(times) :
2945+ ''' Call me with a list of timelog items (which have an
2946+ Interval "period" property)
29472947 '''
2948- def totalTimeSpent(self, times):
2949- ''' Call me with a list of timelog items (which have an
2950- Interval "period" property)
2951- '''
2952- total = Interval('0d')
2953- for time in times:
2954- total += time.period._value
2955- return total
2948+ total = Interval('0d')
2949+ for time in times:
2950+ total += time.period._value
2951+ return total
29562952
2957- XXX update this example for TemplatingUtils -> extensions
2953+ def init(instance):
2954+ instance.registerUtil('totalTimeSpent', totalTimeSpent)
29582955
2959- Replace the ``pass`` line if one appears in your TemplatingUtils
2960- class. As indicated in the docstrings, we will be able to access the
2961- ``totalTimeSpent`` method via the ``utils`` variable in our templates.
2956+ We will now be able to access the ``totalTimeSpent`` function via the
2957+ ``utils`` variable in our templates, as shown in the next step.
29622958
296329595. Display the time log for an issue::
29642960
@@ -3060,13 +3056,17 @@ would be::
30603056Each user of Roundup must still have their information stored in the Roundup
30613057database - we just use the passwd file to check their password. To do this, we
30623058need to override the standard ``verifyPassword`` method defined in
3063- ``roundup.cgi.actions.LoginAction`` and register the new class with our
3064- ``Client`` class in the tracker home ``interfaces.py`` module::
3059+ ``roundup.cgi.actions.LoginAction`` and register the new class. The
3060+ following is added as ``externapassword.py`` in the tracker ``extensions``
3061+ directory::
30653062
30663063 from roundup.cgi.actions import LoginAction
30673064
30683065 class ExternalPasswordLoginAction(LoginAction):
30693066 def verifyPassword(self, userid, password):
3067+ '''Look through the file, line by line, looking for a
3068+ name that matches.
3069+ '''
30703070 # get the user's username
30713071 username = self.db.user.get(userid, 'username')
30723072
@@ -3083,15 +3083,10 @@ need to override the standard ``verifyPassword`` method defined in
30833083 # user doesn't exist in the file
30843084 return 0
30853085
3086- class Client(client.Client):
3087- actions = (
3088- ('login', ExternalPasswordLoginAction),
3089- ) + client.Client.actions
3086+ def init(instance):
3087+ instance.registerAction('login', ExternalPasswordLoginAction)
30903088
3091- What this does is look through the file, line by line, looking for a
3092- name that matches.
3093-
3094- We also remove the redundant password fields from the ``user.item``
3089+ You should also remove the redundant password fields from the ``user.item``
30953090template.
30963091
30973092
@@ -4089,9 +4084,9 @@ Setting up a "wizard" (or "druid") for controlled adding of issues
40894084
409040853. Determine what actions need to be taken between the pages - these are
40914086 usually to validate user choices and determine what page is next. Now encode
4092- those actions in a new ``Action`` class and insert hooks to those actions in
4093- the "actions" attribute on on the ``interfaces.Client`` class, like so (see
4094- `defining new web actions`_)::
4087+ those actions in a new ``Action`` class (see `defining new web actions`_)::
4088+
4089+ from roundup.cgi. actions import Action
40954090
40964091 class Page1SubmitAction(Action):
40974092 def handle(self):
@@ -4105,9 +4100,8 @@ Setting up a "wizard" (or "druid") for controlled adding of issues
41054100 # everything's ok, move on to the next page
41064101 self.template = 'add_page2'
41074102
4108- actions = client.Client.actions + (
4109- ('page1_submit', Page1SubmitAction),
4110- )
4103+ def init(instance):
4104+ instance.registerAction('page1_submit', Page1SubmitAction)
41114105
411241064. Use the usual "new" action as the ``@action`` on the final page, and
41134107 you're done (the standard context/submit method can do this for you).
0 commit comments