summaryrefslogtreecommitdiff
path: root/pypers/europython05/Quixote-2.0/doc/demo.txt
diff options
context:
space:
mode:
Diffstat (limited to 'pypers/europython05/Quixote-2.0/doc/demo.txt')
-rwxr-xr-xpypers/europython05/Quixote-2.0/doc/demo.txt221
1 files changed, 221 insertions, 0 deletions
diff --git a/pypers/europython05/Quixote-2.0/doc/demo.txt b/pypers/europython05/Quixote-2.0/doc/demo.txt
new file mode 100755
index 0000000..4272223
--- /dev/null
+++ b/pypers/europython05/Quixote-2.0/doc/demo.txt
@@ -0,0 +1,221 @@
+Running the Quixote Demos
+=========================
+
+Quixote comes with some demonstration applications in the demo directory.
+After quixote is installed (see INSTALL.txt for instructions),
+you can run the demos using the scripts located in the server directory.
+
+Each server script is written for a specific method of connecting a
+quixote publisher to a web server, and you will ultimately want to
+choose the one that matches your needs. More information about the
+different server scripts may be found in the scripts themselves and in
+web-server.txt. To start, though, the easiest way to view the demos
+is as follows: in a terminal window, run server/simple_server.py, and
+in a browser, open http://localhost:8080.
+
+The simple_server.py script prints a usage message if you run it with
+a '--help' command line argument. You can run different demos by
+using the '--factory' option to identify a callable that creates the
+publisher you want to use. In particular, you might try these demos:
+
+ simple_server.py --factory quixote.demo.mini_demo.create_publisher
+
+or
+
+ simple_server.py --factory quixote.demo.altdemo.create_publisher
+
+
+
+Understanding the mini_demo
+---------------------------
+
+Start the mini demo by running the command:
+ simple_server.py --factory quixote.demo.mini_demo.create_publisher
+
+In a browser, load http://localhost:8080. In your browser, you should
+see "Welcome ..." page. In your terminal window, you will see a
+"localhost - - ..." line for each request. These are access log
+messages from the web server.
+
+Look at the source code in demo/mini_demo.py. Near the bottom you
+will find the create_publisher() function. The create_publisher()
+function creates a Publisher instance whose root directory is an
+instance of the RootDirectory class defined just above. When a
+request arrives, the Publisher calls the _q_traverse() method on the
+root directory. In this case, the RootDirectory is using the standard
+_q_traverse() implementation, inherited from Directory.
+
+Look, preferably in another window, at the source code for
+_q_traverse() in directory.py. The path argument provided to
+_q_traverse() is a list of string components of the path part of the
+URL, obtained by splitting the request location at each '/' and
+dropping the first element (which is always '') For example, if the
+path part of the URL is '/', the path argument to _q_traverse() is
+['']. If the path part of the URL is '/a', the path argument to
+_q_traverse() is ['a']. If the path part of the URL is '/a/', the
+path argument to _q_traverse() is ['a', ''].
+
+Looking at the code of _q_traverse(), observe that it starts by
+splitting off the first component of the path and calling
+_q_translate() to see if there is a designated attribute name
+corresponding to this component. For the '/' page, the component is
+'', and _q_translate() returns the attribute name '_q_index'. The
+_q_traverse() function goes on to lookup the _q_index method and
+return the result of calling it.
+
+Looking back at mini_demo.py, you can see that the RootDirectory class
+includes a _q_index() method, and this method does return the HTML for
+http://localhost:8080/
+
+As mentioned above, the _q_translate() identifies a "designated"
+attribute name for a given component. The default implementation uses
+self._q_exports to define this designation. In particular, if the
+component is in self._q_exports, then it is returned as the attribute
+name, except in the special case of '', which is translated to the
+special attribute name '_q_index'.
+
+When you click on the link on the top page, you get
+http://localhost:8080/hello. In this case, the path argument to the
+_q_traverse() call is ['hello'], and the return value is the result of
+calling the hello() method.
+
+Feeling bold? (Just kidding, this won't hurt at all.) Try opening
+http://localhost:8080/bogus. This is what happens when _q_traverse()
+raises a TraversalError. A TraversalError is no big deal, but how
+does quixote handle more exceptional exceptions? To see, you can
+introduce one by editing mini_demo.py. Try inserting the line "raise
+'ouch'" into the hello() method. Kill the demo server (Control-c) and
+start a new one with the same command as before. Now load the
+http://localhost:8080/hello page. You should see a plain text python
+traceback followed by some information extracted from the HTTP
+request. This information is always printed to the error log on an
+exception. Here, it is also displayed in the browser because the
+create_publisher() function made a publisher using the 'plain' value
+for the display_exceptions keyword argument. If you omit that keyword
+argument from the Publisher constructor, the browser will get an
+"Internal Server Error" message instead of the full traceback. If you
+provide the value 'html', the browser displays a prettier version of
+the traceback.
+
+One more thing to try here. Replace your 'raise "ouch"' line in the hello() method with 'print "ouch"'. If you restart the server and load the /hello page,
+you will see that print statements go the the error log (in this case, your
+terminal window). This can be useful.
+
+
+Understanding the root demo
+---------------------------
+
+Start the root demo by running the command:
+ simple_server.py --factory quixote.demo.create_publisher
+
+In a browser, open http://localhost:8080 as before.
+Click around at will.
+
+This is the default demo, but it is more complicated than the
+mini_demo described above. The create_publisher() function in
+quixote.demo.__init__.py creates a publisher whose root directory is
+an instance of quixote.demo.root.RootDirectory. Note that the source
+code is a file named "root.ptl". The suffix of "ptl" indicates that
+it is a PTL file, and the import must follow a call to
+quixote.enable_ptl() or else the source file will not be found or
+compiled. The quixote.demo.__init__.py file takes care of that.
+
+Take a look at the source code in root.ptl. You will see code that
+looks like regular python, except that some function definitions have
+"[html]" between the function name and the parameter list. These
+functions are ptl templates. For details about PTL, see the PTL.txt
+file.
+
+This RootDirectory class is similar to the one in mini_demo.py, in
+that it has a _q_index() method and '' appears in the _q_exports list.
+One new feature here is the presence of a tuple in the _q_exports
+list. Most of the time, the elements of the _q_exports lists are just
+strings that name attributes that should be available as URL
+components. This pattern does not work, however, when the particular
+URL component you want to use includes characters (like '.') that
+can't appear in Python attribute names. To work around these cases,
+the _q_exports list may contain tuples such as ("favicon.ico",
+"favicon_ico") to designate "favicon_ico" as the attribute name
+corresponding the the "favicon.ico" URL component.
+
+Looking at the RootDirectoryMethods, including plain(), css() and
+favon_ico(), you will see examples where, in addition to returning a
+string containing the body of the HTTP response, the function also
+makes side-effect modifications to the response object itself, to set
+the content type and the expiration time for the response.
+Most of the time, these direct modifications to the response are
+not needed. When they are, though, the get_response() function
+gives you direct access to the response instance.
+
+The RootDirectory here also sets an 'extras' attribute to be an
+instance of ExtraDirectory, imported from the quixote.demo.extras
+module. Note that 'extras' also appears in the _q_exports list. This
+is the ordinary way to extend your URL space through another '/'.
+For example, the URL path '/extras/' will result in a call to
+the ExtraDirectory instance's _q_index() method.
+
+The _q_lookup() method
+----------------------
+
+Now take a look at the ExtraDirectory class in extras.ptl. This class
+exhibits some more advanced publishing features. If you look back at
+the default _q_traverse() implementation (in directory.py), you will
+see that the _q_traverse does not give up if _q_translate() returns
+None, indicating that the path component has no designated
+corresponding attribute name. In this case, _q_traverse() tries
+calling self._q_lookup() to see if the object of interest can be found
+in a different way. Note that _q_lookup() takes the component as an
+argument and must return either (if there is more path to traverse) a
+Directory instance, or else (if the component is the last in the path)
+a callable or a string.
+
+In this particular case, the ExtrasDirectory._q_lookup() call returns
+an instance of IntegerUI (a subclass of Directory). The interest
+here, unlike the ExtrasDirectory() instance itself, is created
+on-the-fly during the traversal, especially for this particular
+component. Try loading http://localhost:8080/extras/12/ to see how
+this behaves.
+
+Note that the correct URL to get to the IntegerUI(12)._q_index() call
+ends with a '/'. This can sometimes be confusing to people who expect
+http://localhost:8080/extras/12 to yield the same page as
+http://localhost:8080/extras/12/. If given the path ['extras', '12'],
+the default _q_traverse() ends up *calling* the instance of IntegerUI.
+The Directory.__call__() (see directory.py) determines the result: if
+no form values were submitted and adding a slash would produce a page,
+the call returns the result of calling quixote.redirect(). The
+redirect() call here causes the server to issue a permanent redirect
+response to the path with the slash added. When this automatic
+redirect is used, a message is printed to the error log. If the
+conditions for a redirect are not met, the call falls back to raising
+a TraversalError. [Note, if you don't like this redirect behavior,
+override, replace, or delete Directory.__call__]
+
+The _q_lookup() pattern is useful when you want to allow URL
+components that you either don't know or don't want to list in
+_q_exports ahead of time.
+
+The _q_resolve() method
+-----------------------
+
+Note that the ExtraDirectory class inherits from Resolving (in
+addition to Directory). The Resolving mixin modifies the
+_q_traverse() so that, when a component has an attribute name
+designated by _q_translate(), but the Directory instance does not
+actually *have* that attribute, the _q_resolve() method is called to
+"resolve" the trouble. Typically, the _q_resolve() imports or
+constructs what *should* be the value of the designated attribute.
+The modified _q_translate() sets the attribute value so that the
+_q_resolve() won't be called again for the same attribute. The
+_q_resolve() pattern is useful when you want to delay the work of
+constructing the values for exported attributes.
+
+Forms
+-----
+
+You can't get very far writing web applications without writing forms.
+The root demo includes, at http://localhost:8080/extras/form, a page
+that demonstrates basic usage of the Form class and widgets defined in
+the quixote.form package.
+
+$Id: demo.txt 25695 2004-11-30 20:53:44Z dbinger $