SVN: r20329 - trunk/quixote/doc

akuchlin-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected] Tue, 21 Jan 2003 15:14:03 -0500
Newsgroups gmane.comp.web.quixote.cvs
Message-ID <[email protected]>
Author: akuchlin
Date: 2003-01-21 15:14:02 -0500 (Tue, 21 Jan 2003)
New Revision: 20329

Modified:
   trunk/quixote/doc/programming.txt
Log:
Add docs for _q_resolve; clarify relation between _q_getname and _q_exports

Modified: trunk/quixote/doc/programming.txt
==============================================================================
--- trunk/quixote/doc/programming.txt	(original)
+++ trunk/quixote/doc/programming.txt	2003-01-21 15:14:03.000000000 -0500
@@ -297,8 +297,9 @@
 to view the documentation for the HTTPRequest and HTTPResponse classes,
 or consult the source code for all the gory details.
 
-There are exactly two ways to affect the how Quixote traverses a URL to
-determine how to handle it: ``_q_access()`` and ``_q_getname()``.
+There are a few special functions that affect Quixote's 
+traversal of a URL to determine how to handle it: ``_q_access()``,
+``_q_getname()``, and  ``_q_resolve()``.
 
 
 ``_q_access(request)``
@@ -331,11 +332,13 @@
 
 This function translates an arbitrary string into an object that we
 continue traversing.  This is very handy; it lets you put user-space
-objects into your URL-space, eliminating the need for digging ID strings
-out of a query, or checking ``PATH_INFO`` after Quixote's done with it.
-But it is a compromise with security: it opens up the traversal
-algorithm to arbitrary names not listed in ``_q_exports``.  You should
-therefore be extremely paranoid about checking the value of ``name``.
+objects into your URL-space, eliminating the need for digging ID
+strings out of a query, or checking ``PATH_INFO`` after Quixote's done
+with it.  But it is a compromise with security: it opens up the
+traversal algorithm to arbitrary names not listed in ``_q_exports``.
+(``_q_getname()`` is never called for names listed in ``_q_exports``.)
+You should therefore be extremely paranoid about checking the value of
+``name``.
 
 ``request`` is the request object, as it is everywhere else; ``name`` is
 a string containing the next chunk of the path.  ``_q_getname()`` should
@@ -399,5 +402,43 @@
         def prefs (self, request):
             # ... generate prefs-editing page ...
 
+``_q_resolve(name)``
+-------------------
+
+``_q_resolve()`` looks a bit like ``_q_getname()``, but is intended for
+a different purpose.  Quixote applications can be slow to start up 
+because they have to import a large number of Python and PTL modules.
+``_q_resolve()`` is a hook that lets time-consuming imports 
+be postponed until the code is actually needed
+
+``name`` is a string containing the next chunk of the path.
+``_q_resolve()`` should do whatever imports are necessary and return a
+module that will be traversed further.  (Other things can be returned,
+such as class instances or whatever, but modules are likely to be the
+most common return type.)
+
+``_q_resolve()`` is only ever called for names that are in
+``_q_exports`` and that don't already exist in the module or instance.
+It is not passed the request object, so its return value can't depend
+on the client in any way.  Calls are also memoized; after being called
+the object returned will be added as an attribute of the containing
+module or instance, so ``_q_resolve()`` will be called at most once
+for a given name.
+
+Most commonly, ``_q_resolve()`` will look something like this:
+
+    _q_exports = [..., 'expensive', ...]
+
+    def _q_resolve(name):
+        if name == 'expensive':
+            from otherpackage import expensive
+            return expensive
+
+Let's say this function is in app.ui.  The first time /expensive is
+accessed, _q_resolve('expensive') is called, the
+otherpackage.expensive module is returned and traversal continues.
+app.ui.expensive is also set to the module objects, so future
+references to /expensive won't need to invoke the ``_q_resolve()``
+hook.
 
 $Id$