Mercurial > p > roundup > code
changeset 1073:cf30c6cdca02
More documentation.
Simplified the "klass", "item" and "*classname*" variables into "context.
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 09 Sep 2002 00:45:06 +0000 |
| parents | 88ded00fa0e0 |
| children | 954ad22eb7d9 |
| files | TODO.txt doc/customizing.txt roundup/cgi/client.py roundup/cgi/templating.py roundup/templates/classic/html/_generic.index roundup/templates/classic/html/file.index roundup/templates/classic/html/issue.index roundup/templates/classic/html/issue.item roundup/templates/classic/html/msg.index roundup/templates/classic/html/msg.item roundup/templates/classic/html/user.index roundup/templates/classic/html/user.item roundup/templates/classic/html/user.register |
| diffstat | 13 files changed, 188 insertions(+), 116 deletions(-) [+] |
line wrap: on
line diff
--- a/TODO.txt Sat Sep 07 22:46:19 2002 +0000 +++ b/TODO.txt Mon Sep 09 00:45:06 2002 +0000 @@ -53,7 +53,7 @@ in a class bug: request.url is incorrect in cgi-bin environments - +bug: query editing not translated to new templating done web: Re-enable link backrefs from messages (feature request #568714) done web: have the page layout (header/footer) be templatable
--- a/doc/customizing.txt Sat Sep 07 22:46:19 2002 +0000 +++ b/doc/customizing.txt Mon Sep 09 00:45:06 2002 +0000 @@ -2,7 +2,7 @@ Customising Roundup =================== -:Version: $Revision: 1.19 $ +:Version: $Revision: 1.20 $ .. This document borrows from the ZopeBook section on ZPT. The original is at: http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx @@ -591,6 +591,9 @@ the access through its main() method. This means that you can do pretty much anything you want as a web interface to your instance. +Figuring out what is displayed +:::::::::::::::::::::::::::::: + Most customisation of the web view can be done by modifying the templates in the instance **html** directory. There are several types of files in there: @@ -615,6 +618,9 @@ style.css a static file that is served up as-is +How requests are processed +:::::::::::::::::::::::::: + The basic processing of a web request proceeds as follows: 1. figure out who we are, defaulting to the "anonymous" user @@ -636,6 +642,9 @@ - NotFound (raised wherever it needs to be) this exception percolates up to the CGI interface that called the client +Determining web context +::::::::::::::::::::::: + To determine the "context" of a request, we look at the URL and the special request variable ``:template``. The URL path after the instance identifier is examined. Typical URL paths look like: @@ -679,8 +688,14 @@ - only classname suplied: "index" - full item designator supplied: "item" -Actions are triggered by using a ``:action`` CGI variable, where the value is -one of: + +Performing actions in web requests +:::::::::::::::::::::::::::::::::: + +When a user requests a web page, they may optionally also request for an +action to take place. As described in `how requests are processed`_, the +action is performed before the requested page is generated. Actions are +triggered by using a ``:action`` CGI variable, where the value is one of: login Attempt to log a user in. @@ -910,6 +925,83 @@ equivalent to ``item/status/checklist``, assuming that ``checklist`` is a method. +Information available to templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following variables are available to templates. + +.. taken from roundup.cgi.templating.RoundupPageTemplate docstring + +*context* + The current context. This is either None, a wrapper around a + hyperdb class (an HTMLClass) or a wrapper around a hyperdb item (an + HTMLItem). +*request* + Includes information about the current request, including: + - the url + - the current index information (``filterspec``, ``filter`` args, + ``properties``, etc) parsed out of the form. + - methods for easy filterspec link generation + - *user*, the current user node as an HTMLItem instance + - *form* + The current CGI form information as a mapping of form argument + name to value +*instance* + The current instance +*db* + The current database, through which db.config may be reached. + +The context variable +:::::::::::::::::: + +The *context* variable is one of three things based on the current context +(see `determining web context`_ for how we figure this out): + +1. if we're looking at a "home" page, then it's None +2. if we're looking at a specific hyperdb class, it's an HTMLClass instance +3. if we're looking at a specific hyperdb item, it's an HTMLItem instance + +If the context is not None, we can access the properties of the class or item. +The only real difference between cases 2 and 3 above are: + +1. the properties may have a real value behind them, and this will appear if + the property is displayed through ``context/property`` or + ``context/property/field``. +2. the context's "id" property will be a false value in the second case, but + a real, or true value in the third. Thus we can determine whether we're + looking at a real item from the hyperdb by testing "context/id". + + +The request variable +:::::::::::::::::::: + +The request variable is packed with information about the current request. + +.. taken from roundup.cgi.templating.HTMLRequest docstring + +=========== ================================================================ +Variable Holds +=========== ================================================================ +form the CGI form as a cgi.FieldStorage +env the CGI environment variables +url the current URL path for this request +base the base URL for this instance +user a HTMLUser instance for this user +classname the current classname (possibly None) +template the current template (suffix, also possibly None) +form the current CGI form variables in a FieldStorage +**Index page specific variables (indexing arguments)** +columns dictionary of the columns to display in an index page +show a convenience access to columns - request/show/colname will + be true if the columns should be displayed, false otherwise +sort index sort column (direction, column name) +group index grouping property (direction, column name) +filter properties to filter the index on +filterspec values to filter the index on +search_text text to perform a full-text search on for an index +----------- ---------------------------------------------------------------- + + Displaying Properties ~~~~~~~~~~~~~~~~~~~~~ @@ -931,11 +1023,11 @@ added for clarity):: /issue?status=unread,in-progress,resolved& - topic=security,ui& - :group=+priority& - :sort=-activity& - :filters=status,topic& - :columns=title,status,fixer + topic=security,ui& + :group=+priority& + :sort=-activity& + :filters=status,topic& + :columns=title,status,fixer The index view is determined by two parts of the specifier: the layout part and the filter part. The layout part consists of the query parameters that begin @@ -958,10 +1050,6 @@ the "status" and "topic" properties, and the table includes columns for the "title", "status", and "fixer" properties. -Associated with each item class is a default layout specifier. The layout -specifier in the above example is the default layout to be provided with the -default bug-tracker schema described above in section 4.4. - Filtering of indexes ::::::::::::::::::::
--- a/roundup/cgi/client.py Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/cgi/client.py Mon Sep 09 00:45:06 2002 +0000 @@ -1,4 +1,4 @@ -# $Id: client.py,v 1.20 2002-09-06 22:54:51 richard Exp $ +# $Id: client.py,v 1.21 2002-09-09 00:45:06 richard Exp $ __doc__ = """ WWW request handler (also used in the stand-alone server). @@ -1069,10 +1069,8 @@ must be supplied or a ValueError will be raised. ''' required = [] - print form.keys() if form.has_key(':required'): value = form[':required'] - print 'required', value if isinstance(value, type([])): required = [i.value.strip() for i in value] else:
--- a/roundup/cgi/templating.py Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/cgi/templating.py Mon Sep 09 00:45:06 2002 +0000 @@ -123,26 +123,13 @@ Interrogate the client to set up the various template variables to be available: - *class* - The current class of node being displayed as an HTMLClass - instance. - *item* - The current node from the database, if we're viewing a specific - node, as an HTMLItem instance. If it doesn't exist, then we're - on a new item page. - (*classname*) - this is one of two things: - - 1. the *item* is also available under its classname, so a *user* - node would also be available under the name *user*. This is - also an HTMLItem instance. - 2. if there's no *item* then the current class is available - through this name, thus "user/name" and "user/name/menu" will - still work - the latter will pull information from the form - if it can. - *form* - The current CGI form information as a mapping of form argument - name to value + *context* + this is one of three things: + 1. None - we're viewing a "home" page + 2. The current class of item being displayed. This is an HTMLClass + instance. + 3. The current item from the database, if we're viewing a specific + item, as an HTMLItem instance. *request* Includes information about the current request, including: - the url @@ -150,20 +137,14 @@ ``properties``, etc) parsed out of the form. - methods for easy filterspec link generation - *user*, the current user node as an HTMLItem instance + - *form*, the current CGI form information as a FieldStorage *instance* The current instance *db* The current database, through which db.config may be reached. - - Maybe also: - - *modules* - python modules made available (XXX: not sure what's actually in - there tho) ''' def getContext(self, client, classname, request): c = { - 'klass': HTMLClass(client, classname), 'options': {}, 'nothing': None, 'request': request, @@ -173,10 +154,9 @@ } # add in the item if there is one if client.nodeid: - c['item'] = HTMLItem(client, classname, client.nodeid) - c[classname] = c['item'] + c['context'] = HTMLItem(client, classname, client.nodeid) else: - c[classname] = c['klass'] + c['context'] = HTMLClass(client, classname) return c def render(self, client, classname, request, **options): @@ -237,11 +217,15 @@ ''' return an HTMLProperty instance ''' #print 'getitem', (self, item) - if item == 'creator': - return HTMLUser(self.client, 'user', client.userid) - if not self.props.has_key(item): - raise KeyError, item + # we don't exist + if item == 'id': + return None + if item == 'creator': + # but we will be created by this user... + return HTMLUser(self.client, 'user', self.client.userid) + + # get the property prop = self.props[item] # look up the correct HTMLProperty class @@ -398,8 +382,8 @@ #print 'getitem', (self, item) if item == 'id': return self.nodeid - if not self.props.has_key(item): - raise KeyError, item + + # get the property prop = self.props[item] # get the value, handling missing values
--- a/roundup/templates/classic/html/_generic.index Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/_generic.index Mon Sep 09 00:45:06 2002 +0000 @@ -19,7 +19,7 @@ </p> <form onSubmit="return submit_once()" method="POST"> -<textarea rows="15" cols="60" name="rows" tal:content="klass/csv"></textarea> +<textarea rows="15" cols="60" name="rows" tal:content="context/csv"></textarea> <br> <input type="hidden" name=":action" value="editCSV"> <input type="submit" value="Edit Items">
--- a/roundup/templates/classic/html/file.index Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/file.index Mon Sep 09 00:45:06 2002 +0000 @@ -1,5 +1,5 @@ <!-- dollarId: file.index,v 1.4 2002/01/23 05:10:27 richard Exp dollar--> -<tr tal:repeat="file class/list"> +<tr tal:repeat="file context/list"> <td tal:condition="display/properties/name"> <a href="" tal:attributes="href string:file${file/id}/${file/name}">dld link</a> </td>
--- a/roundup/templates/classic/html/issue.index Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/issue.index Mon Sep 09 00:45:06 2002 +0000 @@ -59,7 +59,7 @@ <td> <select name=":sort"> <option value="">- nothing -</option> - <option tal:repeat="col klass/properties" + <option tal:repeat="col context/properties" tal:attributes="value col/name; selected python:col.name == request.sort[1]" tal:content="col/name">column</option> @@ -75,7 +75,7 @@ <td> <select name=":group"> <option value="">- nothing -</option> - <option tal:repeat="col klass/properties" + <option tal:repeat="col context/properties" tal:attributes="value col/name; selected python:col.name == request.group[1]" tal:content="col/name">column</option>
--- a/roundup/templates/classic/html/issue.item Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/issue.item Mon Sep 09 00:45:06 2002 +0000 @@ -7,35 +7,35 @@ <table border=0 cellspacing=0 cellpadding=2 class="form"> <tr> <th nowrap>Title</th> - <td colspan=3 class="form-text" tal:content="structure python:issue.title.field(size=60)">title</td> + <td colspan=3 class="form-text" tal:content="structure python:context.title.field(size=60)">title</td> </tr> <tr class="form"> <th nowrap>Priority</th> - <td class="form-text" tal:content="structure issue/priority/menu">priority</td> + <td class="form-text" tal:content="structure context/priority/menu">priority</td> <th nowrap>Status</th> - <td class="form-text" tal:content="structure issue/status/menu">status</td> + <td class="form-text" tal:content="structure context/status/menu">status</td> </tr> <tr class="form"> <th nowrap>Superseder</th> <td> - <span tal:replace="structure python:issue.superseder.field(showid=1, size=20)" /> + <span tal:replace="structure python:context.superseder.field(showid=1, size=20)" /> <span tal:replace="structure python:db.issue.classhelp('id,title', label='list', width=500)" /> - <span tal:condition="issue/superseder"> - <br>View: <span tal:replace="structure python:issue.superseder.link(showid=1)" /> + <span tal:condition="context/superseder"> + <br>View: <span tal:replace="structure python:context.superseder.link(showid=1)" /> </span> </td> <th nowrap>Nosy List</th> <td> - <span tal:replace="structure issue/nosy/field" /> + <span tal:replace="structure context/nosy/field" /> <span tal:replace="structure python:db.user.classhelp('username,realname,address,phone', label='list', width=500)" /> </td> </tr> <tr class="form"> <th nowrap>Assigned To</th> - <td class="form-text" tal:content="structure issue/assignedto/menu"> + <td class="form-text" tal:content="structure context/assignedto/menu"> assignedto menu </td> <td> </td> @@ -58,18 +58,20 @@ <tr class="form"> <td> </td> - <td colspan=3 class="form-text" tal:content="structure issue/submit"> + <td colspan=3 class="form-text" tal:content="structure context/submit"> submit button will go here </td> </tr> </table> -<span tal:condition="exists:item" tal:content="structure string:Created on <b>${issue/creation}</b> by <b>${issue/creator/username}</b>, last changed <b>${issue/activity}</b>.">activity info</span> +<span tal:condition="context/id" tal:content="structure string:Created on +<b>${context/creation}</b> by <b>${context/creator/username}</b>, last +changed <b>${context/activity}</b>.">activity info</span> -<tal:block tal:condition="exists:item"> - <table class="messages" tal:condition="issue/messages"> +<tal:block tal:condition="context/id"> + <table class="messages" tal:condition="context/messages"> <tr><th colspan=2 class="header">Messages</th></tr> - <tal:block tal:repeat="msg issue/messages/reverse"> + <tal:block tal:repeat="msg context/messages/reverse"> <tr> <th tal:content="string:Author: ${msg/author}">author</th> <th tal:content="string:Date: ${msg/date}">date</th> @@ -80,10 +82,10 @@ </tal:block> </table> - <table class="files" tal:condition="issue/files"> + <table class="files" tal:condition="context/files"> <tr><th colspan="2" class="header">Files</th></tr> <tr><th>File name</th><th>Uploaded</th></tr> - <tr tal:repeat="file issue/files"> + <tr tal:repeat="file context/files"> <td> <a tal:attributes="href string:file${file/id}/${file/name}" tal:content="file/name">dld link</a> @@ -97,7 +99,7 @@ <table class="history"> <tr><th colspan="2" class="header">History</th></tr> - <tr><td colspan="2" tal:content="structure issue/history">history</td></tr> + <tr><td colspan="2" tal:content="structure context/history">history</td></tr> </table> </tal:block>
--- a/roundup/templates/classic/html/msg.index Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/msg.index Mon Sep 09 00:45:06 2002 +0000 @@ -1,6 +1,6 @@ <table class="messages" tal:condition="request/filter"> <tr><th colspan=2 class="header">Messages</th></tr> - <tal:block tal:repeat="msg issue/messages/reverse"> + <tal:block tal:repeat="msg context/list"> <tr> <th tal:content="string:Author: ${msg/author}">author</th> <th tal:content="string:Date: ${msg/date}">date</th>
--- a/roundup/templates/classic/html/msg.item Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/msg.item Mon Sep 09 00:45:06 2002 +0000 @@ -3,28 +3,28 @@ <tr bgcolor="ffffea"> <td width=1% nowrap align=right><span class="form-label">Author</span></td> - <td class="form-text" tal:content="msg/author"></td> + <td class="form-text" tal:content="context/author"></td> </tr> <tr bgcolor="ffffea"> <td width=1% nowrap align=right><span class="form-label">Recipients</span></td> - <td class="form-text" tal:content="msg/recipients"></td> + <td class="form-text" tal:content="context/recipients"></td> </tr> <tr bgcolor="ffffea"> <td width=1% nowrap align=right><span class="form-label">Date</span></td> - <td class="form-text" tal:content="msg/date"></td> + <td class="form-text" tal:content="context/date"></td> </tr> <tr bgcolor="ffeaff"> <td colspan=2 class="form-text"> - <pre tal:content="msg/content"></pre> + <pre tal:content="context/content"></pre> </td> </tr> <property name="files"> <tr class="strong-header"><td colspan=2><b>Files</b></td></tr> -<tr tal:repeat="file msg/files"> +<tr tal:repeat="file context/files"> <td> <a tal:attributes="href string:file${file/id}/${file/name}" tal:content="file/name">dld link</a> @@ -37,6 +37,6 @@ </property> <tr class="history-header"><td colspan=2><b>History</b></td><tr> -<tr><td colspan="2" tal:content="structure msg/history">history</td></tr> +<tr><td colspan="2" tal:content="structure context/history">history</td></tr> </table>
--- a/roundup/templates/classic/html/user.index Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/user.index Mon Sep 09 00:45:06 2002 +0000 @@ -7,15 +7,15 @@ <th>Email address</th> <th>Phone number</th> </tr> -<tr tal:repeat="u user/list" - tal:attributes="class python:['row-normal', 'row-alt'][repeat['u'].even()]"> +<tr tal:repeat="user context/list" + tal:attributes="class python:['row-normal', 'row-alt'][repeat['user'].even()]"> <td valign="top"> - <a tal:attributes="href string:user${u/id}" - tal:content="u/username">username</a> + <a tal:attributes="href string:user${user/id}" + tal:content="user/username">username</a> </td> - <td valign="top" tal:content="u/realname">realname</td> - <td valign="top" tal:content="u/organisation">organisation</td> - <td valign="top" tal:content="python:u.address.email()">address</td> - <td valign="top" tal:content="u/phone">phone</td> + <td valign="top" tal:content="user/realname">realname</td> + <td valign="top" tal:content="user/organisation">organisation</td> + <td valign="top" tal:content="python:user.address.email()">address</td> + <td valign="top" tal:content="user/phone">phone</td> </tr> </table>
--- a/roundup/templates/classic/html/user.item Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/user.item Mon Sep 09 00:45:06 2002 +0000 @@ -1,7 +1,7 @@ <!-- dollarId: user.item,v 1.7 2002/08/16 04:29:04 richard Exp dollar--> <tal:block tal:define=" editok python:request.user.hasPermission('Edit') or - user.id == request.user.id; + context.id == request.user.id; viewok python:request.user.hasPermission('View')"> <span tal:condition="python:not (viewok or editok)"> @@ -16,52 +16,52 @@ <table class="form"> <tr> <th>Name</th> - <td tal:content="structure user/realname/field">realname</td> + <td tal:content="structure context/realname/field">realname</td> </tr> <tr> <th>Login Name</th> - <td tal:content="structure user/username/field">username</td> + <td tal:content="structure context/username/field">username</td> </tr> <tr> <th>Login Password</th> - <td tal:content="structure user/password/field">password</td> + <td tal:content="structure context/password/field">password</td> </tr> <tr tal:condition="python:request.user.hasPermission('Web Roles')"> <th>Roles</th> - <td tal:condition="exists:item" - tal:content="structure user/roles/field">roles</td> - <td tal:condition="not:exists:item"> + <td tal:condition="item/created" + tal:content="structure context/roles/field">roles</td> + <td tal:condition="not:item/created"> <input name="roles" tal:attributes="value db/config/NEW_WEB_USER_ROLES"> </td> </tr> <tr> <th>Phone</th> - <td tal:content="structure user/phone/field">phone</td> + <td tal:content="structure context/phone/field">phone</td> </tr> <tr> <th>Organisation</th> - <td tal:content="structure user/organisation/field">organisation</td> + <td tal:content="structure context/organisation/field">organisation</td> </tr> <tr> <th>E-mail address</th> - <td tal:content="structure user/address/field">address</td> + <td tal:content="structure context/address/field">address</td> </tr> <tr> <th>Alternate E-mail addresses<br>One address per line</th> - <td tal:content="structure user/alternate_addresses/multiline">alternate_addresses</td> + <td tal:content="structure context/alternate_addresses/multiline">alternate_addresses</td> </tr> <tr> <td> </td> - <td tal:content="structure user/submit">submit button here</td> + <td tal:content="structure context/submit">submit button here</td> </tr> </table> </form> -<tal:block tal:condition="exists:item"> - <table class="otherinfo" tal:condition="user/queries"> +<tal:block tal:condition="item/created"> + <table class="otherinfo" tal:condition="context/queries"> <tr><th class="header">Queries</th></tr> - <tr tal:repeat="query user/queries"> + <tr tal:repeat="query context/queries"> <td tal:content="query">query</td> </tr> </table> @@ -69,7 +69,7 @@ <table class="otherinfo"> <tr><th class="header">History</th></tr> <tr> - <td tal:content="structure user/history">history</td> + <td tal:content="structure context/history">history</td> </tr> </table> </tal:block> @@ -78,23 +78,23 @@ <table class="form" tal:condition="python:viewok and not editok"> <tr> - <th colspan=2 class="header" tal:content="user/realname">realname</th> + <th colspan=2 class="header" tal:content="context/realname">realname</th> </tr> <tr> <th>Login Name</th> - <td tal:content="user/username">username</td> + <td tal:content="context/username">username</td> </tr> <tr> <th>Phone</th> - <td tal:content="user/phone">phone</td> + <td tal:content="context/phone">phone</td> </tr> <tr> <th>Organisation</th> - <td tal:content="user/organisation">organisation</td> + <td tal:content="context/organisation">organisation</td> </tr> <tr> <th>E-mail address</th> - <td tal:content="user/address/email">address</td> + <td tal:content="context/address/email">address</td> </tr> </table>
--- a/roundup/templates/classic/html/user.register Sat Sep 07 22:46:19 2002 +0000 +++ b/roundup/templates/classic/html/user.register Mon Sep 09 00:45:06 2002 +0000 @@ -12,39 +12,39 @@ <table class="form"> <tr> <th>Name</th> - <td tal:content="structure user/realname/field">realname</td> + <td tal:content="structure context/realname/field">realname</td> </tr> <tr> <th>Login Name</th> - <td tal:content="structure user/username/field">username</td> + <td tal:content="structure context/username/field">username</td> </tr> <tr> <th>Login Password</th> - <td tal:content="structure user/password/field">password</td> + <td tal:content="structure context/password/field">password</td> </tr> <tr tal:condition="python:request.user.hasPermission('Web Roles')"> <th>Roles</th> <td tal:condition="exists:item" - tal:content="structure user/roles/field">roles</td> + tal:content="structure context/roles/field">roles</td> <td tal:condition="not:exists:item"> <input name="roles" tal:attributes="value db/config/NEW_WEB_USER_ROLES"> </td> </tr> <tr> <th>Phone</th> - <td tal:content="structure user/phone/field">phone</td> + <td tal:content="structure context/phone/field">phone</td> </tr> <tr> <th>Organisation</th> - <td tal:content="structure user/organisation/field">organisation</td> + <td tal:content="structure context/organisation/field">organisation</td> </tr> <tr> <th>E-mail address</th> - <td tal:content="structure user/address/field">address</td> + <td tal:content="structure context/address/field">address</td> </tr> <tr> <th>Alternate E-mail addresses<br>One address per line</th> - <td tal:content="structure user/alternate_addresses/multiline">alternate_addresses</td> + <td tal:content="structure context/alternate_addresses/multiline">alternate_addresses</td> </tr> <tr>
