Index: Page.py =================================================================== RCS file: /cvsroot/webware/Webware/WebKit/Page.py,v retrieving revision 1.33 diff -u -r1.33 Page.py --- Page.py 1 Dec 2003 21:12:09 -0000 1.33 +++ Page.py 2 Oct 2004 18:39:32 -0000 @@ -1,16 +1,12 @@ from Common import * -from HTTPServlet import HTTPServlet +from HTTPContent import HTTPContent, HTTPContentError from WebUtils import Funcs from Application import EndResponse -class PageError(Exception): - pass - - -class Page(HTTPServlet): +class Page(HTTPContent): """ - Page is a type of HTTPServlet that is more convenient for + Page is a type of HTTPContent that is more convenient for Servlets which represent HTML pages generated in response to GET and POST requests. In fact, this is the most common type of Servlet. @@ -20,13 +16,6 @@ They might also choose to override `writeHTML` entirely. - In `awake`, the page sets self attributes: `_transaction`, - `_response` and `_request` which subclasses should use as - appropriate. - - For the purposes of output, the `write` and `writeln` - convenience methods are provided. - When developing a full-blown website, it's common to create a subclass of `Page` called `SitePage` which defines the common look and feel of the website and provides site-specific convenience @@ -36,120 +25,11 @@ ## Transactions ## - def awake(self, transaction): - """ - Makes instance variables from the transaction. This is - where Page becomes unthreadsafe, as the page is tied to - the transaction. This is also what allows us to - implement functions like `write`, where you don't - need to pass in the transaction or response. - """ - HTTPServlet.awake(self, transaction) - self._response = transaction.response() - self._request = transaction.request() - self._session = None # don't create unless needed - assert self._transaction is not None - assert self._response is not None - assert self._request is not None - - def respondToGet(self, transaction): - """ - Invoked in response to a GET request method. All methods - are passed to `_respond` - """ - self._respond(transaction) - - def respondToPost(self, transaction): - """ - Invoked in response to a GET request method. All methods - are passed to `_respond` - """ - self._respond(transaction) - - def _respond(self, transaction): - """ - Handles actions if an ``_action_`` or ``_action_XXX`` - field is defined, otherwise invokes `writeHTML`. - Invoked by both `respondToGet` and `respondToPost`. - """ - req = transaction.request() - - # Support old style actions from 0.5.x and below. - # Use setting OldStyleActions in Application.config - # to use this. - if self.transaction().application().setting('OldStyleActions', ) \ - and req.hasField('_action_'): - action = self.methodNameForAction(req.field('_action_')) - actions = self._actionSet() - if actions.has_key(action): - self.preAction(action) - apply(getattr(self, action), (transaction,)) - self.postAction(action) - return - else: - raise PageError, "Action '%s' is not in the public list of actions, %s, for %s." % (action, actions.keys(), self) - - # Check for actions - for action in self.actions(): - if req.hasField('_action_%s' % action) or \ - req.field('_action_', None) == action or \ - (req.hasField('_action_%s.x' % action) and \ - req.hasField('_action_%s.y' % action)): - self.handleAction(action) - return - - self.defaultAction() - def defaultAction(self): - self.writeHTML() - - def sleep(self, transaction): - """ - :ignore: - We unset some variables. Very boring. - """ - self._session = None - self._request = None - self._response = None - self._transaction = None - HTTPServlet.sleep(self, transaction) - - - ## Access ## - - def application(self): - """ - The `Application` instance we're using. - """ - return self._transaction.application() - - def transaction(self): - """ - The `Transaction` we're currently handling. - """ - return self._transaction - - def request(self): - """ - The request (`HTTPRequest`) we're handling. - """ - return self._request - - def response(self): - """ - The response (`HTTPResponse`) we're handling. - """ - return self._response - - def session(self): """ - The session object, i.e., a state for the current - user (associated with a browser instance, really). - If no session exists, then a session will be created. + The default action in a Page is to writeHTML(). """ - if not self._session: - self._session = self._transaction.session() - return self._session + self.writeHTML() ## Generating results ## @@ -180,10 +60,12 @@ tag. Invoked by writeBody(). With the prevalence of stylesheets (CSS), you can - probably skip this particular HTML feature. + probably skip this particular HTML feature, but for + historical reasons this sets the page to black text + on white. """ - return 'color=black bgcolor=white' + return 'color="black" bgcolor="white"' def writeHTML(self): """ @@ -267,7 +149,7 @@ implementation does nothing. Subclasses should override if necessary. A typical implementation is: - self.writeln('\t') + self.writeln('\t') """ pass @@ -317,109 +199,23 @@ self.writeln('
This page has not yet customized its content.
') - ## Writing ## - - def write(self, *args): - """ - Writes the arguments, which are turned to strings - (with `str`) and concatenated before being written - to the response. - """ - for arg in args: - self._response.write(str(arg)) - - def writeln(self, *args): - """ - Writes the arguments (like `write`), adding a newline - after. - """ - for arg in args: - self._response.write(str(arg)) - self._response.write('\n') - - - ## Threading ## - - def canBeThreaded(self): - """ - Returns 0 because of the instance variables we set up - in `awake`. """ - return 0 - - - ## Actions ## - - def handleAction(self, action): - """ - Invoked by `_respond` when a legitimate action has - been found in a form. Invokes `preAction`, the actual - action method and `postAction`. - - Subclasses rarely override this method. - """ - self.preAction(action) - getattr(self, action)() - self.postAction(action) - - def actions(self): - """ - Returns a list of method names that are allowable - actions from HTML forms. The default implementation - returns []. See `_respond` for more about actions. - """ - - return [] - def preAction(self, actionName): """ - Invoked by self prior to invoking a action method. The - implementation basically writes everything up to but - not including the body tag. Subclasses may override - to customize and may or may not invoke super as they - see fit. The `actionName` is passed to this method, - although it seems a generally bad idea to rely on - this. However, it's still provided just in case you - need that hook. + For a page, we first writeDocType(), , and then + writeHead(). """ - ## 2003-03 ib @@: Whyzit a bad idea to rely on it? self.writeDocType() self.writeln('') self.writeHead() def postAction(self, actionName): """ - Invoked by self after invoking a action method. The - implementation basically writes everything after the - close of the body tag (in other words, just the - ```` tag). Subclasses may override to - customize and may or may not invoke super as they see - fit. The `actionName` is passed to this method, - although it seems a generally bad idea to rely on - this. However, it's still provided just in case you - need that hook. + Simply close the html tag (). """ self.writeln('