[Checkins] SVN: zope2book/trunk/ Remove already converted stx documents

Hanno Schlichting plone at hannosch.info
Mon Feb 16 13:49:35 EST 2009


Log message for revision 96599:
  Remove already converted stx documents
  

Changed:
  D   zope2book/trunk/InstallingZope.stx
  D   zope2book/trunk/ObjectOrientation.stx
  D   zope2book/trunk/OldAdvDTML.stx

-=-
Deleted: zope2book/trunk/InstallingZope.stx
===================================================================
--- zope2book/trunk/InstallingZope.stx	2009-02-16 18:42:26 UTC (rev 96598)
+++ zope2book/trunk/InstallingZope.stx	2009-02-16 18:49:35 UTC (rev 96599)
@@ -1,739 +0,0 @@
-Installing and Starting Zope
-  
-  By the end of this chapter, you should be able to install and start
-  Zope.  It is fairly easy to install Zope on most platforms, and it
-  typically takes no longer than ten minutes to complete an installation.
-  
-  Downloading Zope
-  
-    There are typically two types of Zope releases: a "stable" release
-    and a "development" release.  If you are new to Zope, you almost
-    certainly want to use the "stable" Zope release.
-    
-    You may download Zope from the "Zope.org":http://www.zope.org web
-    site, from which the most recent stable and development versions are always
-    available in the "Download":http://www.zope.org/Products/
-    area.
-    
-    Zope comes as a "binary" release for the Windows platform,
-    and in source format for UNIX-like operating systems. Zope
-    may be compiled on almost any UNIX-like operating system.
-    Zope has reportedly been successfully compiled on Linux,
-    FreeBSD, NetBSD, OpenBSD, Mac OS X, HPUX, IRIX, DEC OFS/1,
-    and even Cygwin (the UNIX emulation platform for Windows).
-    As a general rule of thumb: if
-    "Python":http://www.python.org is available for your
-    operating system, and if you have a C compiler and associated
-    development utilities, then it is highly likely that you will be able to compile Zope.
-    A notable exception is Mac OS between versions 7 through 9, as Zope does not run at all on these platforms.
-    
-    Various binary Zope packages exist that are not distributed
-    by Zope Corporation, but are instead distributed by third
-    parties.  Provided here is a list of URLs to these for the sake of 
-    convenience.  While these packages are not directly
-    supported by Zope Corporation, Zope Corporation
-    encourages alternate binary distributions for unsupported
-    platforms by third parties. Not all versions of Zope are
-    available for all platforms.
-    
-     "SPVI's Mac OS X binary distro":http://sourceforge.net/projects/mosxzope
-     
-     "Marcus Schopens Zope packages for Linux":http://zope.org/Members/medienlabor/packages
-     
-     "FreeBSD Zope port":http://www.freebsd.org/ports/zope.html
-     
-     "Debian Linux Zope package":http://packages.debian.org/zope
-     
-     "Gentoo Zope ebuild":http://packages.gentoo.org/ebuilds/?zope-2.6.1
-     
-     Some other Linux distributions, e.g., SUSE, include Zope
-     with their products. Check your vendor's product documentation to
-     find out more.
-     
-  Installing Zope
-  
-    Zope's installation steps vary somewhat, depending on your
-    operating system platform.  The sections below detail installing
-    the binary version of Zope on Windows on Intel platforms,
-    and a source installation on Linux.
-    
-    Installing Zope for Windows With Binaries from Zope.org
-    
-      The "Win32" version of Zope works under Windows 95,
-      Windows 98, Windows ME, Windows NT, Windows 2000, Windows
-      XP, and Windows Server 2003.  Zope for Windows comes as a
-      self-installing *.exe* file.  To install Zope, first,
-      download the Win32 executable installer from the
-      "Download":http://www.zope.org/Products area on Zope.org.
-      It is typically named something like
-      "Zope-2.X.X-win32-x86.exe" where the "X"'s refer to the
-      current Zope version number.
-      
-      "Current stable Zope release for Windows":img:2-1:Figures/download-zope.png
-      
-      Download the current stable release installer for Windows from
-      Zope.org using your web browser.  Place the file in a temporary
-      directory on your hard disk or on your Desktop.  Once the
-      installer file has been downloaded, navigate to the folder into 
-      which you downloaded the file, and double-click on the file's
-      icon.  The installer then begins to walk you through the
-      installation process.
-      
-      "Zope installer":img:2-2:Figures/installer-package-icon.png
-      
-      "Beginning the installer":img:2-3:Figures/installer-first-screen.png
-      
-      Click *Next*. The installer asks for an installation
-      path. The default is usually acceptable, though you are, of
-      course, free to choose another path. Then click *Next*. You
-      then can choose which components to install.
-
-      "Select components":img:2-4:Figures/component-selection.png 
-
-      You should select "Full installation" unless you have previously installed Zope and know what 
-      you are doing. On the next screen, you may customize the
-      entry placed in your *Start Menu* folder. Click *Next*
-      again. The installer now asks you whether you would like to
-      run Zope as a *service*, unless you are running Windows 98
-      or ME, on which such services are not available. If you are only 
-      running Zope for personal use, there is no need to run it as
-      a service.
-      
-      "Server options":img:2-5:Figures/start-as-service.png
-
-      Upon clicking *Next*, the installer takes you to the
-      "Instance Setup" Screen.
-
-      "Instance setup":img:2-6:Figures/instance-path.png
-
-      You can have more than one Zope running on your PC, but
-      each has to have its own *Instance Home*, which is the path to specify here.  This 
-      path is where Zope will later place its database files. Make
-      sure that you have enough disk space left on the specified
-      drive and that you can make backups easily. 
-      
-      The *Next* screen asks you for a password for an initial
-      administrative account. You use this account to log in for
-      the first time and create more users. Note that the
-      installer does not ask you to verify your password, so be
-      careful not to mis-type it.
-      
-      "Administrative password":img:2-7:Figures/instance-passwd.png
-      
-      Click *Next* after entering a password. The installer
-      presents an overview, form which you can commence installation by clicking
-      *Install*. After a few moments, the Zope installer will 
-      present you with a "Completion" screen.
-      
-      "Installation completion":img:2-8:Figures/installer-complete.png 
-      
-      Let the installer start Zope for you, or start Zope
-      manually by navigating to the Zope folder in the Start
-      Menu and selecting "Run Zope in Console". See the section below 
-      entitled "Starting Zope".
-
-    Compiling and Installing Zope from Source Code
-    
-      If binaries aren't available for your platform, chances are good
-      that you will be able to compile Zope from its source code.  To
-      do this, however, you first must:
-      
-       - ensure that you have a "C" compiler on your system (*GNU gcc* is
-         preferred)
-         
-       - ensure that you have a recent "make" on your system (*GNU make* is
-         preferred)
-         
-       - install the "Python":http://www.python.org language on your
-         system from source, or install a binary Python package
-         including development headers
-         
-      Zope is written primarily in the Python language, and Zope
-      requires Python in order to be able to run at all.  While binary
-      versions of Zope ship with a recent Python version, the source
-      Zope distribution does not.  Zope developers try to use the
-      most recent Python for Zope, but often the latest Python
-      version is more recent than the officially-supported Zope version.  
-	  Zope 2.7 requires Python 2.3.2 or later, and Zope versions 2.5 and 2.6
-      require a Python 2.1.*x* version equal to or greater than
-      2.1.3.  For the most recent information on 
-      which version of Python is required for compiling Zope, see
-      the release notes on the release Web page. 
-            
-      You can obtain detailed instructions for downloading, compiling, and
-      installing Python from source at the
-      "Python.org":http://www.python.org website.  Some Linux
-      distributions ship with a pre-installed Python 2.3, but care
-      is required when attempting to use a
-      vendor-installed Python to compile Zope: some of these
-      vendor-supplied Python distributions do not ship the
-      necessary Python development files needed to compile Zope
-      from source.  Sometimes these development files are
-      included in a separate "python-devel" package that may
-      be installed separately, but sometimes they are not.  The binary packages that ship with Debian have been used with 
-      some level of success, but it is generally advisable to compile
-      and install Python from source if you wish to also compile and
-      install Zope from source.
-      
-      After downloading, compiling, and installing Python from source,
-      download the current Zope source distribution.  See the Zope.org
-      "Downloads":http://www.zope.org:/Products area for the latest
-      Zope source release.  
-      
-      Download the source to your home, or some other directory, 'cd' to that directory, and unpack it with something similar to::
-      
-        $ gunzip -c Zope-*.tgz | tar xvf -
-        
-      where * represents the Zope release version of the source tarball.  
-        
-      Zope now uses the conventional UNIX build sequence: 
-      'configure', 'make', 'make install'. 
-      
-      To configure Zope, 'cd' to the Zope directory and issue
-      the configure command::
-
-        $ cd Zope-*
-        $ ./configure --prefix=/where/to/install/zope
-        
-      Replace */where/to/install/zope* above with an appropriate
-      path, such as '~/myzope/zope2.7'.  This path is
-      referred to as the *ZOPE_HOME*.  If you want to install
-      Zope in a system directory instead of your user home,
-      replace '~/myzope/zope2.7' with an appropriate path,
-      e.g., '/usr/local/zope2.7', and make sure that you have suitable
-      privileges for installing and starting Zope ('sudo' or 'root').
-      
-      If the configure script is unable to find your Python
-      installation, it will report an error not unlike this
-      one::
-      
-        $ ./configure --prefix=~/myzope/zope2.7
-        
-        Configuring Zope installation
-        Testing for an acceptable Python interpreter...
-        
-        No suitable Python version found. You should install
-        Python version 2.3.3 before continuing. Versions
-        2.3.2 2.3.1 2.3 2.2.3 2.2.2 also work, but not as optimally.
-        
-      In this case, you must point the installer to your Python
-      interpreter, which you should have installed previously, either from
-      a binary package or compiled from source.
-      
-      Use the '--with-python' option to the
-      configure script, e.g,. for a python living under
-      '/usr/local' ::
-
-        $ ./configure --prefix=~/myzope/zope2.7 \
-        --with-python=/usr/local/bin/python
-
-      Replace '/usr/local/bin/python' with the path to your
-      Python executable. 
-      
-      Zope is now ready to be built. From within the source
-      directory, issue::
-      
-        $ make 
-        [ lots of output snipped ]
-        Zope built. Next, do 'make install' (or 'make instance'
-        to run a Zope instance directly from the build directory). 
-        
-      You are now ready to install Zope. To do this, you will
-      have to execute 'make install' ::
-
-        $ make install
-        [ lots of output snipped ]
-        Zope binaries installed successfully.
-        Now run '~/myzope/zope2.7/bin/mkzopeinstance.py'      
-      
-      With the Zope binaries installed, you are now ready to
-      install a *Zope instance*, which holds
-      configuration and runtime data for a single Zope server
-      process.  This helps keep your own or third-party
-      software separate from the main Zope source.
-      
-      Assuming that you want to install a Zope instance in the
-      directory '~/myzope/instance', in order to create a Zope instance,
-      you would run the following command::
-      
-        $ ~/myzope/zope2.7/bin/mkzopeinstance.py
-        
-      You will need to provide the following
-      values:
-
-      * The directory where your instance should be located, or 
-        the *INSTANCE_HOME*. The instance home will hold your
-        database files, log files, the "Extensions" and
-        "Products" directories, configuration files, and scripts
-        to start and stop the instance.  For our example, we
-        assume the instance home to be located at
-        '~/myzope/instance'
-        
-      * Username and Password for an initial Zope user. You will
-        log in with this username and password to create your
-        own Zope users.  To change the username or password for
-        your initial Zope user, run::
-
-          $ cd ~/myzope/instance
-          $ ~/myzope/zope2.7/bin/zpasswd.py inituser
-
-        You will have to provide the username and password you
-        wish to set; optionally, you can specify the hashing
-        method and an additional domain restriction.
-        
-      
-      Zope installation is now complete. Read on to see how to
-      start your brand-new Zope.
-      
-      
-  Starting Zope
-  
-    Zope is managed via a web browser, and Zope contains its own web
-    server (called "ZServer").  A successful Zope startup implies that
-    Zope's web server starts, which allows you to access the Zope management
-    interface (ZMI) via your web browser.  You can access the 
-    ZMI from the same machine on which Zope runs, or you can
-    access it from a remote machine that is connected to the same
-    network as your Zope server.
-    
-    Zope's ZServer will "listen" for HTTP requests on TCP port 8080.  If your Zope instance fails to start, make sure that another 
-    application isn't already running on the same TCP port (8080).
-    
-    Zope also has the capability to listen on other TCP ports.  Zope
-    supports separate TCP ports for FTP (File Transfer Protocol),
-    "monitor" (internal debugging), WebDAV (Web Distributed Authoring
-    and Versioning), and ICP (Internet Cache Protocol) access.  If you
-    see messages that indicate that Zope is listening on ports other
-    than the default 8080 HTTP, don't panic: it's likely just 
-    one of these additional ports.
-    
-  Using Zope With an Existing Web Server
-  
-    If you wish, you can configure your existing web server to serve
-    Zope content.  Zope interfaces with Microsoft IIS, Apache, and
-    other popular webservers.
-    
-    The "Virtual Hosting Services":VirtualHosting.stx chapter of this
-    book provides rudimentary setup information for configuring Zope
-    behind Apache.  However, configuring Zope for use behind an
-    existing web server can be a complicated task, and there is more
-    than one way to get it done.  Here are some additional resources 
-    that should get you started:
-    
-      - Apache: see the excellent DevShed article entitled "Using Zope
-        With
-        Apache":http://devshed.com/Server_Side/Zope/ZopeWithApache .
-        
-      - IIS: see "brianh's
-        HowTo":http://www.zope.org/Members/brianh/iis_howto on using
-        IIS with Zope.  Also of interest may be the 'WEBSERVER.txt' file
-        in your Zope installation's 'doc' directory, and
-        hiperlogica's "Connecting IIS to
-        Zope":http://www.zope.org/Members/hiperlogica/ASP404 article.
-        
-     If you are just getting started with Zope, note that it is not
-     necessary to configure Apache, IIS, or any other web server to
-     serve your Zope pages, as Zope comes with its own web server.  You
-     typically only need to configure your existing web server if you
-     want to use it to serve Zope pages in a production environment.
-     
-  Starting Zope on Windows
-  
-    If you've installed Zope to "run manually" (as opposed to installing
-    Zope as a "service"), navigate to the Zope folder in your
-    Start Menu and click on *Run Zope in Console*. A console
-    window with process startup information will be displayed. 
-    
-    If you chose to run Zope as a "service" on Windows NT/2000/XP, you can
-    start Zope via the standard Windows "Services" control panel
-    application.  A Zope instance started as a service writes events to the
-    standard Windows Event Log; you can keep track of the Zope 
-    service's start and stop events by reviewing the Event Log.  A
-    Zope instance which has been installed as a "service" can also be
-    run manually by invoking the *Run Zope in Console* menu
-    entry as described earlier. Take care not to 
-    run Zope manually *and* as a service at one time: 
-    make sure to stop the Zope service first before starting it
-    manually. 
-    
-  Starting Zope on UNIX
-    
-    **Important note: If you installed Zope from an RPM or a
-    another "vendor distribution" instead of installing a Zope
-    Corporation-distributed source release, the instructions
-    below may be not be applicable.  Under these circumstances,
-    please read the documentation supplied by the vendor to
-    determine how to start your Zope instance instead of relying
-    on these instructions.**
-    
-    To start your Zope instance (which we assume lives in
-    ~/myzope/instance), issue the command::
-    
-      $ ~/myzope/instance/bin/zopectl start
-      
-    This will start the instance in the
-    background. Alternatively, you can start it in the foreground
-    and watch its progress by issuing the command::
-    
-      $ ~/myzope/instance/bin/zopectl fg
-      
-    Run the 'zopectl' script with a parameter of 'help' to get a
-    list of additional commands::
-    
-      $ ~/myzope/instance/bin/zopectl help
-      
-      
-    Starting Zope as the Root User
-      
-      ZServer (Zope's server) supports 'setuid()' on POSIX
-      systems in order to be able to listen on low-numbered ports, such as
-      21 (FTP) and 80 (HTTP), but drop root privileges when
-      running; on most POSIX systems, only the 'root' user can do
-      this.  Versions of Zope prior to 2.6 had less robust
-      versions of this support.  Several problems were corrected
-      for the 2.6 release.
-      
-      The most important thing to remember about this support is
-      that you don't *have* to start ZServer as root, unless you
-      want to listen for requests on "low" ports.  In fact, if
-      you don't have this need, you are much better off just
-      starting ZServer as a user account dedicated to running
-      Zope.  'nobody' is not a good idea for this user account,
-      because if any other daemon on a system that ran as
-      'nobody' were to be compromised, this would open up your
-      Zope object data to vulnerability.
-      
-      If you do need to have ZServer listening on low ports, you
-      will need to start 'zopectl' as the 'root' user, and to 
-      specify what user ZServer should 'setuid()' to.  This can be done 
-      by setting the *effective-user* parameter in your Zope
-      instances configuration file, residing in
-      '$INSTANCE_HOME/etc/zope.conf', and by making sure that the log and
-      database files are writeable by this user.
-      
-      
-  Your Zope Installation
-  
-    To use and manage Zope, you will need a web browser.  Since Zope's
-    management interface (ZMI) is written entirely in HTML, any
-    browser that understands modern HTML enables you to manage a Zope
-    installation.  Mozilla, any 3.0+ version of Microsoft Internet
-    Explorer, or Netscape Navigator will do.  Other browsers that are
-    known to work with Zope include Opera, Galeon, Konqueror, OmniWeb,
-    Lynx, and W3M.
-    
-    Start a web browser on the same machine on which you installed
-    Zope, and browse to the URL "http://localhost:8080/":http://localhost:8080/.
-    If your Zope instance has beens installed properly, and you're visiting the correct URL,
-    you will be presented with the Zope "QuickStart" screen.
-    
-      "Zope QuickStart":img:2-8:Figures/quickstart.png
-      
-    If you see this screen, congratulations!  You've installed Zope
-    successfully.  If you don't, see the *Troubleshooting* section
-    below.
-    
-  Logging In
-  
-    To do anything remotely interesting with Zope, you need to
-    use its management interface: the *ZMI*.
-    Zope is completely web-manageable.  To log into the ZMI, use your web browser to navigate to
-    Zope's management URL.  Assuming you have Zope installed on
-    the same machine from which you are running your web
-    browser, the Zope management URL will be
-    "http://localhost:8080/manage":http://localhost:8080/manage.
-    
-    Successful contact with Zope via this URL will result in an
-    authentication dialog, into which you can enter the "initial"
-    username and password you chose when you installed Zope.  You will
-    then be presented with the ZMI.
-    
-    "The Zope Management Interface (ZMI).":img:2-9:Figures/zmi.png
-    
-    If you do not see an authentication dialog and the ZMI, 
-    refer to the *Troubleshooting* section of this chapter.
-    
-  Controlling the Zope Process with the Control Panel
-  
-    When you are using the ZMI, you can use the Zope *Control Panel*
-    to control the Zope process.  Find and click the **Control_Panel**
-    object in ZMI.
-    
-    "The Control Panel":img:2-10:Figures/controlpanel.jpg
-    
-    The Control Panel displays information about your Zope, such
-    as the Zope version you are running, the Python version that
-    Zope is using, the system platform, the INSTANCE_HOME, the
-    ZOPE_HOME, Zope's process id, the network services that have
-    been started, how long Zope has been running for, and other
-    installation specifics.  Several buttons and links will also
-    be shown.
-    
-    If you are running Zope on UNIX or as a service on Windows,
-    you will see a *Restart* button in the Control Panel.
-    Clicking *Restart* will cause Zope to shut down and
-    then immediately start back up again.  It may take Zope a few
-    seconds to come back up and start handling requests.  You
-    don't need to shut your web browser down and restart it to resume
-    using Zope after pressing *Restart*, as the page refreshes automatically; 
-    just wait for the Control Panel display to reappear.
-    
-    To shut Zope down from the ZMI, click *Shutdown*.
-    Shutting Zope down will cause the server to stop handling
-    requests and exit. You will have to manually start Zope to
-    resume using it. Shut Zope down only if you are finished
-    using it and you have the ability to access the server on
-    which Zope is running, so that you can manually restart it
-    later as needed.
-    
-    
-  Controlling the Zope Process from the Command Line
-  
-    To stop a manually-run Zope on Windows, press "Ctrl+C" while in
-    the console window under which Zope is running is selected.
-    To stop a Zope on Windows that was run as a service, find
-    the service with the name you assigned to your Zope
-    in the Services Control Panel application, and stop
-    the service.
-    
-    To stop Zope on UNIX, do one of the following:
-
-    * If you started Zope in the foreground, press "Ctrl+C" in the terminal 
-    window from which you started Zope
-
-    * if you started Zope in the background, use the 'zopectl'
-      script::
-      
-        $ ~/myzope/instance/bin/zopectl stop
-      
-    * use the UNIX "kill" command against the process id in the
-      "var/Z2.pid" file inside the Zope instance directory::
-
-        $ kill `cat var/Z2.pid`
-      
-
-  Troubleshooting and Caveats
-  
-    Running zopectl returns with an OSError
-            
-      When running Zope on a 2.6.x Linux kernel, Solaris or Mac
-      OS X, zopectl returns an error 'OSError: [Errno 10] No child
-      processes'. This is due to a bug in Zope 2.7.0. You have
-      the following options:
-      
-      * Install a patch currently in CVS. See 
-      http://zope.org/Collectors/Zope/1235 for the collector log
-      and a small patch. The patch file is named
-      zdctl.diff. Download it to a temporary directory,
-      e.g., '/tmp'. Then 'cd' to the directory
-      '$ZOPE_HOME/lib/python/zdaemon' (continuing our previous example,
-      this would be '~/myzope/zope2.7/lib/python/zdaemon') and
-      run the patch command: 'patch < /tmp/zdctl.diff'. The
-      patch program should respond with an output similar to 'patching
-      file zdctl.py'.
-      
-      * If running on Linux: downgrade to a 2.4.x kernel
-            
-      * Work around this issue by placing Zope in the background
-        manually with::
-        
-        $ nohup ~/myzope/instance/bin/runzope &
-        
-      Note though that your Zope instance will not be
-      automatically restarted by 'zdaemon' this way, and that this method 
-      should not be used on a production server. 
-      
-    Browser cannot connect to port 8080
-    
-      If your browser fails to connect with anything on TCP port
-      8080, your Zope instance may be running on a non-standard TCP port
-      (for example, some versions of Debian Linux ship with
-      Zope's default TCP port as 9673).  To find out exactly which URL
-      to use, look at the logging information Zope prints as it
-      starts up when started in the foreground, i.e., when started
-      with './runzope' or './zopectl fg'. For example::
-      
-        ------
-        2004-04-21T21:48:27 INFO(0) ZServer HTTP server started at Wed Apr 21 21:48:27 2004
-        Hostname: arod
-        Port: 9673
-        ------
-        2004-04-21T21:48:27 INFO(0) ZServer FTP server started at Wed Apr 21 21:48:27 2004
-        Hostname: arod
-        Port: 8021
-        
-         ...
-         
-      The first log entry indicates that Zope's web server is
-      listening on port 9673 on host 'arod'. This means that the
-      management URL is *http://arod:9673/manage*.
-
-      As mentioned previously, Zope only prints to the console when 
-      started in the foreground, with './runzope' or
-      'runzope.bat'. This logging information can be
-      found in the 'log/event.log' file in your INSTANCE_HOME
-      directory.
-      
-      Certain versions of Microsoft Internet Explorer 5.0.1 and 5.5 are 
-      incompatible with the ZMI in some respects, which manifest
-      themselves as an inability to properly log in.  If you have
-      trouble logging in with IE 5.0.1 or IE 5.5, try a different
-      browser or upgrade to a later version.
-      
-    Forgot administrative password
-    
-      If you forget or lose your initial Zope user name and password,
-      shut Zope down, change the initial user password with
-      the *zpasswd.py* script, and restart Zope. See the chapter
-      entitled "Users and Security":Security.stx for more
-      information about configuring the initial user account.
-      
-      
-  Customizing your Zope instance
-  
-    As of Zope 2.7.0, configuration is no longer done with a mix
-    of environment variables and command line options. Instead,
-    the file '$INSTANCE_HOME/etc/zope.conf' contains numerous configuration
-    directives for customization.  This configuration scheme greatly enhances
-    Zope manageability and configurability.
-    
-    The 'zope.conf' file features extensive inline documentation, 
-    which we will not reproduce here.  Instead, we will give an overview
-    and some additional hints for the most-widely used
-    directives:
-
-      Server stanzas and 'port-base'
-      
-        The 'port-base' directive, together with stanzas for
-        the individual servers, determine the ports on which specific servers
-        listen for incoming Zope requests. The stanzas are formed with XML-like
-        constructs::
-        
-          <http-server>
-            # valid keys are "address" and "force-connection-close"
-            address 8080
-          </http-server>
-          <ftp-server>
-            ...
-          </ftp-server>
-          <webdav-source-server>
-            ...
-          </webdav-source-server>
-          
-        The 'address' directive determines the port on which the
-        respective server listens.  The HTTP Server in this
-        example listens on port 8080.
-
-        The 'port-base' directive comes in handy if you want to
-        run several Zope instances on one machine.  'port-base'
-        specifies an offset to the port on which **all** servers listen. 
-        Let us assume that our HTTP Server's 'address' directive
-        is set to 8080, as in our example above, and
-        'port-base' is specified as 1000. The port on which the
-        HTTP server will listen, will be the 'address' value of 8080, plus the 
-        'port-base' offset value of 1000, or 9080.  Assuming the
-        FTP server's 'address' directive is set to 8021, the FTP
-        Server will then listen on port 9021, and so on.
-
-      The 'debug-mode' directive
-
-        This directive is a switch, specified as either 'on' or
-        'off'.  When set to 'on' (the default), Zope runs in
-        *debug mode*, which causes Zope to reload file system-based
-        templates, and several other settings
-        suitable for development, in real time.  In a production 
-        environment, to reduce unnecessary overhead, you should ensure that this 
-        directive is set to 'off' unless you are actively troubleshooting 
-        a problem.
-
-      Additional 'products' directories
-        
-        This directive can be used to specify additional 'Products'
-        directories, or additional folders in which Zope looks for
-        third-party and other add-on Zope Products.  Specifying a separate 
-        directory for commonly-used, third-party Products, such as 
-        CookieCrumbler or CMF and
-        Plone packages, maintains a better separation of core Zope
-        Products and third-party add-ons and improves maintainability.  
-        Another common use for this directive is employed by Zope Product developers, who use it to specify a version-controlled
-        development directory. 
-
-      Switch the User the Zope process runs as: 'effective-user'
-
-        This directive causes Zope to setuid(2) to the specified
-        user when run as root on a UNIX system.  This method boosts
-        system security, as a compromised Zope instance would not lend itself to
-        enable a compromised user to easily damage an entire system.  One motivation 
-        for running Zope as root in the first place is to be able to
-        bind to *privileged* ports, or ports with values below 1024.
-        
-      Configuring the Session machinery
-
-        Use the 'maximum-number-of-session-objects' directive to
-        limit the number of session objects.  This value
-        defaults to 1000 objects; 0 means unlimited.
-
-        'session-timeout-minutes' sets the Session timeout period in
-        minutes. The default is 20.
-
-      Logging
-
-        Three log facilities are provided:
-
-        * *Access logging* logs individual HTTP Requests in a common format, 
-        by default to the file 'log/Z2.log' in your instance home.
-
-        * *Event logging* logs Zope events, such as start and stop
-        information and debugging messages.
-        
-        * *Trace logging* logs detailed Zope debugging information. 
-
-        Each log message has an associated severity level,
-        ranging from 'CRITICAL', 'ERROR', 'WARN', and 'INFO', to
-        'DEBUG' and 'ALL'.  You can specify a filter for log
-        messages with the 'level' directive inside a logger
-        stanza.  Set the level to 'ALL' to get all log messages,
-        or to 'ERROR' or 'CRITICAL' to see only the most serious
-        messages. 
-
-        Although the default is to write the messages to a log file, you
-        can instead arrange for log messages to be mailed to you,
-        or to go to syslog(3) (on UNIX) or the event log (on
-        MS Windows)
-        
-    For further documentation, see the inline comments in
-    'zope.conf' 
-
-        
-  When All Else Fails
-  
-    If there's a problem with your installation that you just cannot
-    solve, do not despair.  You have many places to turn for
-    help, including the Zope mailing lists and the '#zope' IRC channel.
-    
-    If you are new to open-source software, please realize that, for
-    the most part, participants in the various "free" Zope support
-    forums are volunteers.  Though they are typically friendly and
-    helpful, they are not obligated to answer your questions.
-    Therefore, it's in your own self-interest to exercise your best
-    manners in these forums in order to get your problem resolved
-    quickly.
-    
-    The most reliable way to get installation help is to send a
-    message to the general Zope mailing list detailing your installation
-    problem.  For more information on the available Zope mailing
-    lists, see the "Resources":http://www.zope.org/Resources section
-    of Zope.org.  Typically, someone on the "zope at zope.org" list will
-    be willing and able to help you solve the problem.
-    
-    For even more immediate help, you may choose to visit the #zope
-    channel on the OpenProjects IRC (Internet Relay Chat) network.
-    See "the OpenProjects website":http://www.openprojects.net for
-    more information on how to connect to the OpenProjects IRC
-    network.
-    
-    If you are truly desperate and under a time constraint that
-    prohibits you from utilizing "free" support channels, Zope
-    Corporation provides for-fee service contracts 
-    for Zope installation help.  See "Zope.com":http://www.zope.com
-    for more information about Zope Corporation service contracts.

Deleted: zope2book/trunk/ObjectOrientation.stx
===================================================================
--- zope2book/trunk/ObjectOrientation.stx	2009-02-16 18:42:26 UTC (rev 96598)
+++ zope2book/trunk/ObjectOrientation.stx	2009-02-16 18:49:35 UTC (rev 96599)
@@ -1,87 +0,0 @@
-Object Orientation
-
-    To make the best use of Zope, you will need a grasp on the concept of *object orientation*, which is a software development pattern used in many programming languages (C++, Java, Python, Eiffel, Modula-2, and others) and computer systems that simulate "real-world" behavior.  It stipulates that you should design an application in terms of *objects*.  This chapter provides a broad overview of the fundamentals of object orientation from the perspective of a Zope developer.
-
-  Objects
-
-    In Zope, as in other object-oriented systems, your application is designed around *objects*, or self-contained "bundles" of data and logic.  It is easiest to describe these bundles by comparing them to other programming concepts.
-
-    In a typical, non-object-oriented application, you will have two things:
-
-      - Code.  For example, a typical CGI-based web application may have a bit of logic in the form of a Perl script, which retrieves employee data from a database and displays tabular data to a user.
-
-      - Data.  For example, you may have employee data stored in a database, such as MySQL or Oracle, on which some code performs read or change operations.  This data exists almost solely for the purpose of the code that operates upon it; without this code, the data holds little to no value.
-
-    In a typical object-oriented application, however, you will have one thing, and one thing only:
-
-      - Objects.  Simply stated, these objects are collections of code and data wrapped up together.  For example, you may have an "Employee" object that represents an employee.  It will contain data about the employee, such as a phone number, name, and address, much like the information that would be stored in a database.  However, the object will also contain "logic," or  code, that can manipulate and display its data.
-
-    In a non-object-oriented application, your data is kept separate from your code.  But in an object-oriented application, both your data and your code are stored in one or more objects, each of which represents a particular "thing".  These objects can represent just about anything.  In Zope, the *Control_Panel* is an object, Folders that you create are objects, and even the Zope "root folder" is an object.  When you use the Zope "add list" to create a new item in the Zope Management Interface, you are creating an object.  People who extend Zope by creating *Products* define their own types of objects, which are then entered in to the Zope "add list" so that  you can create objects based on them.  A Product author might define a "Form" object or a "Weblog" object.  Basically, anything that can be defined  using a noun can be modelled as a Zope object.
-
-    As a programming methodology, object orientation allows software developers to design and create programs in terms of "real-world" things, such as  Folders, Control_Panels, Forms, and Employees, instead of designing programs based around more "computerish" concepts like bits, streams, and integers.  Instead of teaching the computer about our problem by descending to its basic vocabulary (bits and bytes), we use an abstraction to teach the computer about the problem in terms of a vocabulary that is more natural to humans.  The core purpose of object orientation is to allow developers to create, to the largest extent possible, a system based on abstractions of the natural language of a computer (bits and bytes) into the real-world objects, like Employees and Forms, that we can understand more readily and quickly.
-
-    The concept of abstraction also encourages programmers to break up a larger problem by addressing the problem as smaller, more independent "sub-problems," which allows developers to define and address solutions in much smaller, more feasible terms.  When you design an application in terms of objects, they become the pieces that eventually define the solution to all the "sub-problems" of a particular "big" problem.
-
-  Attributes
-
-    An object's data is defined by its *attributes*, or pieces of data that describe aspects of the object.  For example, an attribute of an Employee object might be called "phone_number," which might contain a series of characters that represent the employee's phone number.  Other attributes of an Employee object might be "first_name," "last_name", and "job_title," all of which give additional, detailed information about each Employee.
-
-    It may help to think of the set of attributes belonging to an object as a sort of "mini-database" that contains information representing the "real-world thing" that the object is attempting to describe.  The complete collection of attributes assigned to an object defines that object's *state*.  When one or more of an object's attributes are modified, the object is said to have *changed its state*.
-
-    Special kinds of web-editable object attributes in Zope are sometimes referred to as *Properties*.
-
-  Methods
-
-    The set of actions that an object may perform is defined by its *methods*.  Methods are code definitions attached to an object that perform actions based on the object's attributes.  For example, a method of an Employee object named "getFirstName" may return the value of the object's "first_name" attribute, while a method of an Employee object named "setFirstName" might *change* the value of the object's "first_name" attribute.  The "getTitle" method of an Employee object may return a value of "Vice President" or "Janitor, depending on which Employee object is being queried.
-
-    Methods are similar to *functions* in procedural languages like 'C'.  The key difference between a method and a function is that a method is "bound" to, or attached to, an object: instead of operating solely on "external" data that is passed to it via arguments, it may also operate on the attributes of the object to which it is bound.
-
-    Some objects in Zope are actually called "methods".  For example, there are *DTML Methods*, *SQL Methods*, and *External Methods*, because these objects are meant to be used in a "method-ish" way.  They are "bound" to their containing Folder object by default when called, and the logic that they contain typically makes reference to their containing Folder.  *Script (Python)* objects in Zope act similarly through their concept of "Bindings."
-
-  Messages
-
-    In an object-oriented system, to do any useful work, an object is required to communicate with other objects in the same system. For example, it wouldn't be particularly useful to have a single Employee object just sitting around in "object-land" with no way to communicate with it.  It would then just be as "dumb" as a regular old relational database row, just storing some data without the ability to do much else.  We want the capability to ask the object to do something useful, or more precisely: we want the capability for *other* objects to ask our Employee object to do something useful.  For instance, if we create an object named "EmployeeSummary," which is responsible for collecting the names of all of our employees for later display, we want the EmployeeSummary object to be able to ask a set of Employee objects for their first and last names.
-
-    When one object communicates with another, it is said to send a *message* to another object.  Messages are sent to objects by way of the object's *methods*.  For example, our EmployeeSummary object may send a message to our Employee object by way of "calling" its "getFirstName" method.  Our Employee object would receive the message and return the value of its "first_name" attribute.  Messages are sent from one object to another when a "sender" object calls a method of a "receiver" object.
-
-    When you access a URL that "points to" a Zope object, you are almost always sending that Zope object a message.  When you request a response from Zope by way of invoking a Zope URL with a web browser, the Zope "object publisher":http://www.zope.org/Documentation/ZDG/ObjectPublishing.stx receives the request from your browser.  It then sends a Zope object a message on your browser's behalf by "calling a method" on the Zope object specified in the URL.  The Zope object responds to the object publisher with a return value, and the object publisher returns the value to your browser.
-
-  Classes and Instances
-
-    A *class* defines an object's behavior and acts as a *constructor* for an object.  When we talk about a "kind" of object, like an "Employee" object, we actually mean "objects constructed using the Employee class" or, more likely, just "objects of the Employee class."  Most objects are members of a class.
-
-    It is typical to find many objects in a system that are essentially similar to one another, save for the values of their attributes.  For instance, you may have many Employee objects in your system, each with "first_name" and "last_name" attributes. The only difference between these Employee objects is the values contained within their attributes.  For example, the "first_name" of one Employee object might be "Fred" while another might be "Jim".  It is likely that each of these objects would be *members of the same class*.
-
-    A class is to an object as a set of blueprints is to a house: as many houses can be constructed using the same set of blueprints, many objects can be constructed using the same class. Objects that share a class typically behave identically to one other.  If you visit two houses that share the same set of blueprints, you will likely notice striking similaries: the layout will be the same, the light switches will be in the same places, and the fireplace will almost certainly be in the same location.  The shower curtains might be different in each house, but this is an *attribute* of each particular house that doesn't change its essential similarity with the other.  It is much the same with instances of a class: if you "visit" two instances of a class, you would interact with both instances in essentially the same way: by calling the same set of methods on each.  The data kept in the instance (by way of its attributes) might be different, but these instances *behave* in exa
 ctly the same way.
-
-    The behavior of two objects constructed from the same class is similar because they both share the same *methods*, which are not typically defined by an object itself, but are instead defined by an object's *class*.  For instance, if the Employee class defines the 'getFirstName' method, all objects that are members of the Employee class share that method definition.  The set of methods assigned to an object's class define the *behavior* of that object.
-
-    The objects constructed by a class are called *instances of the class*, or (more often) just *instances*.  For example, the Zope 'Examples' folder is an *instance of* the 'Folder' class. The 'Examples' folder has an 'id' attribute of 'Examples', while another folder may have an 'id' attribute of 'MyFolder'.  However, while they have different attribute values, since they are both instances of the same class, they both behave identically.  All the objects that can be administered using the ZMI are instances of a class.  Typically, the classes from which these objects are constructed are defined in the Zope *Products* created by Zope developers and community members.
-
-  Inheritance
-
-    It is sometimes desirable for objects to share the same essential behavior, except for small deviations.  For example, you may want to create a ContractedEmployee object that has all the behavior of a "normal" Employee object, except that you must keep track of a tax identification number on instances of the ContractedEmployee class that is irrelevant for "normal" instances of the Employee class.
-
-    *Inheritance* is the mechanism that allows you to share essential behavior between two objects, while customizing one with a slightly modified set of behaviors that differ from or extend the other.
-
-    Inheritance is specified at the *class level*.  Since *classes define behavior*, if we want to change an object's behavior, we almost always need to change its class.
-
-    If we base our new "ContractedEmployee" class on the Employee class, but add a method to it named "getTaxIdNumber" and an attribute named "tax_id_number," the ContractedEmployee class would be said to *inherit from* the Employee class.  In the jargon of object orientation, the ContractedEmployee class would be said to *subclass from* the Employee class, and the *Employee* class would be said to be a *superclass of* the ContractedEmployee class.
-
-    When a subclass inherits behavior from another class, it doesn't need to sit idly by and accept all the method definitions of its superclass if they don't suit its needs: if necessary, the subclass can *override* the method definitions of its superclass.  For instance, we may want our ContractedEmployee class to return a different "title" than instances of our Employee class.  In our ContractedEmployee class, we might cause the 'getTitle' method of the Employee class to be *overridden* by creating a method within ContractedEmployee with a different implementation.  For example, it may always return "Contractor" instead of a job-specific title.
-
-    Inheritance is used extensively in Zope objects.  For example, the Zope "Image" class inherits its behavior from the Zope "File" class, since images are really just another kind of file, and both classes share many behavior requirements.  But the "Image" class adds a bit of behavior that allows it to "render itself inline" by printing its content within HTML tags, instead of causing a file download.  It does this by *overriding* the 'index_html' method of the File class.
-
-  Object Lifetimes
-
-    Object instances have a specific *lifetime*, which is typically controlled by either a programmer or a user of the system in which the objects "live".
-
-    Instances of web-manageable objects in Zope, such as Files, Folders, and DTML Methods, span from the time the user creates them until they are deleted. You will often hear these kinds of objects described as *persistent* objects.  These objects are stored in Zope's object database (the ZODB).
-
-    Other Zope object instances have different lifetimes: some object instances last for a "programmer-controlled" period of time.  For instance, the object that represents a web request in Zope (often called REQUEST) has a well-defined lifetime, which lasts from the moment the object publisher receives the request from a remote browser, until a response is sent back to that browser, after which it is destroyed automatically.  Zope "session data" objects have another well-defined lifetime, which spans from the time  a programmer creates one on behalf of the user via code, until such time that the system (on behalf of the programmer or site administrator) deems it necessary to throw away the object in order to conserve space, or to indicate an "end" to the user's session.  This is defined by default as 20 minutes of "inactivity" by the user for whom the object was created.
-
-  Summary
-
-    Zope is an object-oriented development environment.  Understanding Zope fully requires a grasp of the basic concepts of object orientation, including attributes, methods, classes, and inheritance, before setting out on a "for-production" Zope development project.
-
-    For a more lighthearted description of what object orientation is and how it relates to Zope, see Chris McDonough's "Gain Zope Enlightenment by Grokking Object Orientation":http://www.zope.org/Members/mcdonc/HowTos/gainenlightenment. For a more comprehensive treatment on the subject of object orientation, buy and read "The Object Primer":http://www.ambysoft.com/theObjectPrimer.html by Scott Ambler.  There are also excellent object orientation tutorials available on the Internet.  See "The Essence of Objects chapter":http://www.objectcentral.com/oobook/Chapter2.html of the book "The Essence of Object Oriented Programming with Java and UML," or the extensive "Object FAQ":http://www.objectfaq.com/oofaq2/ .
\ No newline at end of file

Deleted: zope2book/trunk/OldAdvDTML.stx
===================================================================
--- zope2book/trunk/OldAdvDTML.stx	2009-02-16 18:42:26 UTC (rev 96598)
+++ zope2book/trunk/OldAdvDTML.stx	2009-02-16 18:49:35 UTC (rev 96599)
@@ -1,1781 +0,0 @@
-Chapter 8: Variables and Advanced DTML
-
-  DTML is the kind of language that "does what you mean."  That is good,
-  when it does what you actually want it to do, but when it does something
-  you don't want to do, it's bad.  This chapter tells you how to make DTML
-  do what you *really* mean.
-
-  It's no lie that DTML has a reputation for complexity.  And it's true,
-  DTML is really simple if all you want to do is simple layout,
-  like you've seen so far.  However, if you want to use DTML for more
-  advanced tasks, you have to understand where DTML variables come
-  from.
-
-  Here's a very tricky error that almost all newbies encounter.
-  Imagine you have a DTML Document called *zooName*.  This
-  document contains an HTML form like the following::
-
-    <dtml-var standard_html_header>
-
-      <dtml-if zooName>
-
-        <p><dtml-var zooName></p>
-
-      <dtml-else>
-
-        <form action="<dtml-var URL>" method="GET">
-          <input name="zooName">
-          <input type="submit" value="What is zooName?">
-        </form>
-
-      </dtml-if>  
-
-    <dtml-var standard_html_footer>
-
-    % Anonymous User - June 15, 2002 10:02 am:
-     Why wouldn't the form action code use a Zope object name instead of the URL variable? I thought that in one
-     of the previous examples form actions were more object-oriented than this.
-
-    % Anonymous User - Aug. 24, 2002 5:25 am:
-     I recieve:
-     Zope has encountered an error while publishing this resource.
-     Error Type: SystemError
-     Error Value: Excessive recursion
-     ?
-
-    % Anonymous User - Sep. 26, 2002 1:35 am:
-     :) thats the idea! Cary on reading..
-
-  This looks simple enough, the idea is, this is an HTML page that calls
-  itself.  This is because the HTML action is the *URL* variable, which
-  will become the URL of the DTML Document.  
-
-  If there is a 'zooName' variable, then the page will print it, if there
-  isn't, it shows a form that asks for it.  When you click submit, the data
-  you enter will make the "if" evaluate to true, and this code should print
-  what entered in the form.
-
-    % Anonymous User - May 24, 2002 11:26 am:
-     I think you mean: 
-     what is entered
-
-    % Anonymous User - July 18, 2002 9:52 pm:
-     ...was entered...
-     past tense
-
-  But unfortunately, this is one of those instances where DTML will not do
-  what you mean, because the name of the DTML Document that contains this
-  DTML is also named *zooName*, and it doesn't use the variable out of the
-  request, it uses itself, which causes it call itself and call itself, ad
-  infinitum, until you get an "excessive recursion" error.  So instead of
-  doing what you really meant, you got an error. This is what confuses
-  beginners.  In the next couple sections, we'll show you how to fix this
-  example to do what you mean.
-
-    % Anonymous User - Nov. 11, 2002 1:29 am:
-     Missing words:
-     "causes it call" should be "causes it to call"
-     and
-     "next couple sections" should be "next couple of sections"
-     Hope that helps.
-
-  How Variables are Looked up
-
-    There are actually two ways to fix the DTML error in the
-    *zooName* document.  The first is that you can rename the document
-    to something like *zopeNameFormOrReply* and always remember this
-    special exception and never do it; never knowing why it happens.
-    The second is to understand how names are looked up, and to be
-    explicit about where you want the name to come from in the
-    *namespace*.
-
-    The DTML namespace is a collection of objects arranged in a *stack*.  A
-    stack is a list of objects that can be manipulated by *pushing* and
-    *popping* objects on to and off of the stack. 
-
-    When a DTML Document or DTML Method is executed, Zope creates a
-    DTML namespace to resolve DTML variable names. It's important to
-    understand the workings of the DTML namespace so that you can
-    accurately predict how Zope will locate variables. Some of the
-    trickiest problems you will run into with DTML can be resolved by
-    understanding the DTML namespace.
-
-      % Anonymous User - Sep. 24, 2002 12:14 pm:
-       /is executed/called for execution/
-       The namespace is constructed upon the *event* of a call; execution itself is a *sequence of events* in time*.
-
-    When Zope looks for names in the DTML namespace stack it first looks at
-    the very top most object in the stack.  If the name can't be found
-    there, then the next item down is looked in.  Zope will work its way
-    down the stack, checking each object in turn until it finds the name
-    that it is looking for.
-
-      % Anonymous User - July 12, 2002 12:11 am:
-       topmost
-
-      % Anonymous User - Aug. 8, 2002 3:03 pm:
-       Neither "very top most" (sic) or "topmost" say anything more than a simple "top"
-
-      % Anonymous User - Sep. 24, 2002 12:37 pm:
-       Look up *in* an object: Explain:
-       Python objects have a namespace for their components ("__dict__" ?); also the name of the class the object
-       was instantiated from; the classes namespace (classes are objects, too) contains the names of its parent
-       classes.
-       All these objects nested namespaces are looked up, and in that order!
-
-    If Zope gets all the way down to the bottom of the stack and
-    can't find what it is looking for, then an error is generated.  For
-    example, try looking for the non-existent name, *unicorn*::
-
-      <dtml-var unicorn>
-
-    As long as there is no variable named *unicorn* viewing this
-    DTML will return an error, as shown in [7-1].
-
-    "DTML error message indicating that it cannot find a
-    variable.":img:7-1:Figures/7-1.png
-
-    But the DTML stack is not all there is to names because DTML
-    doesn't start with an empty stack, before you even begin executing
-    DTML in Zope there are already a number of objects pushed on the
-    namespace stack.
-
-      % Anonymous User - Sep. 24, 2002 12:41 pm:
-       paragraph superficial. 
-       BTW, the DTML namespace *is* all there ist to lookup!
-
-      % Anonymous User - Nov. 11, 2002 1:34 am:
-       The paragraph might be superficial, but it does help Newbies.
-       Chill a bit.
-       :)
-
-  DTML Namespaces
-
-    DTML namespaces are built dynamically for every request in Zope. When
-    you call a DTML Method or DTML Document through the web, the DTML
-    namespace starts with the same first two stack elements the client
-    object and the request as shown in [7-2]
-
-      % Anonymous User - July 18, 2002 9:54 pm:
-       ..first two stack elements; the client object...
-
-      % Anonymous User - July 18, 2002 9:55 pm:
-       ...the request, as shown in Figure 7-2.
-
-      % Anonymous User - Sep. 24, 2002 12:29 pm:
-       ... starts with two objects: at the bottom the *client* object and next the *REQUEST* object as show in
-       Figure 7-2.
-
-      % Anonymous User - Sep. 24, 2002 12:32 pm:
-       error, sorry, should read
-       ... at the bottom the *REQUEST* object and next the *client* object ...
-       it implies that the REQUEST is the last place where objects are looked up.
-
-    "Initial DTML namespace stack.":img:7-2:Figures/7-2.png
-
-    The client object is the first object on the top of the DTML namespace
-    stack.  What the client object is depends on whether or not you are
-    executing a DTML Method or a DTML Document.  In our example above, this
-    means that the client object is named *zooName*.  Which is why it
-    breaks.  The form input that we really wanted comes from the web
-    request, but the client is looked at first.
-
-      % Anonymous User - Sep. 24, 2002 12:45 pm:
-       The client object is the first object on the top of the DTML namespace stack.
-       Nope. 
-       The client object is topmost only as long as nothing else is pushed onto the namespace stack. The namespace
-       stack may grow and shrink during processing of a request.
-
-      % charlesz - Dec. 1, 2002 6:53 pm:
-       "whether or not you are executing a DTML Method or a DTML Document" is just a little ambiguous. Does it mean
-       "whether your are executing a DTML Metod or DTML Document"?
-
-    The request namespace is always on the bottom of the DTML namespace
-    stack, and is therefore the last namespace to be looked in for names.
-    This means that we must be explicit in our example about which
-    namespace we want.  We can do this with the DTML 'with' tag::
-
-      <dtml-var standard_html_header>
-
-        <dtml-with REQUEST only>
-          <dtml-if zooName>
-            <p><dtml-var zooName></p>
-          <dtml-else>
-            <form action="<dtml-var URL>" method="GET">
-              <input name="zooName">
-              <input type="submit" value="What is zooName?">
-            </form>
-          </dtml-if>
-        </dtml-with>
-
-      <dtml-var standard_html_footer>
-
-      % Anonymous User - July 18, 2002 9:57 pm:
-       Unfortunately, it's also going to look in just the REQUEST namespace for the URL variable. For a URL this is
-       probably ok, as it should be part of the REQUEST, but don't get tripped up.
-
-      % Anonymous User - July 24, 2002 10:47 pm:
-       How do you get items into the REQUEST namespace? And is there a complete reference for dealing exclusively
-       with this item alone?
-
-      % mcdonc - July 25, 2002 9:35 am:
-       REQUEST.set will work.  See the Zope help system API reference for the REUQUEST object.
-
-      % Anonymous User - Sep. 24, 2002 12:56 pm:
-       Well, the basic effect of <dtml-with ...> is to push another object onto the namespace, with <dtml-with
-       object only> restricting the lookup to just this object.
-       While sufficient to make the example work, this doesn't explain dtml-with (although it makes the impression).
-       Forward reference, see *Modifying the DTML Namespace*.
-
-    Here, the with tag says to look in the 'REQUEST' namespace, and *only*
-    the 'REQUEST' namespace, for the name "zooName".
-
-    DTML Client Object  
-
-      The client object in DTML depends on whether or not you are executing a
-      DTML Method or a DTML Document.  In the case of a Document, the client
-      object is always the document itself, or in other words, a DTML
-      Document is its own client object.
-
-      A DTML Method however can have different kinds of client objects
-      depending on how it is called.  For example, if you had a DTML Method
-      that displayed all of the contents of a folder then the client object
-      would be the folder that is being displayed.  This client object can
-      change depending on which folder the method in question is
-      displaying.  For example, consider the following DTML Method named
-      *list* in the root folder::
-
-        <dtml-var standard_html_header>
-
-        <ul>
-        <dtml-in objectValues>
-          <li><dtml-var title_or_id></li>
-        </dtml-in>
-        </ul>
-
-        <dtml-var standard_html_footer>
-
-      Now, what this method displays depends upon how it is used.  If
-      you apply this method to the *Reptiles* folder with the URL
-      'http://localhost:8080/Reptiles/list', then you will get
-      something that looks like [7-3].
-
-      "Applying the *list* method to the *Reptiles*
-      folder.":img:7-3:Figures/7-3.png
-
-        % Anonymous User - Sep. 24, 2002 1:12 pm:
-         picture too large for the illustrating purpose
-
-      But if you were to apply the method to the *Birds* folder with
-      the URL *http://localhost:8080/Birds/list* then you would get
-      something different, only two items in the list, *Parrot* and
-      *Raptors*.
-
-        % Anonymous User - Sep. 24, 2002 1:04 pm:
-         /, only two items in the list,/, namely/ # "only" implies we would expect more
-
-      Same DTML Method, different results. In the first example, the client
-      object of the *list* method was the *Reptiles* folder.  In the second
-      example, the client object was the *Birds* folder. When Zope looked
-      up the *objectValues* variable, in the first case it called the
-      *objectValues* method of the *Reptiles* folder, in the second case it
-      called the *objectValues* method of the *Birds* folder.
-
-      In other words, the client object is where variables such as
-      methods, and properties are looked up first.
-
-        % Anonymous User - Sep. 24, 2002 1:08 pm:
-         "first": only as long as the namespace stack doesn't grow.
-         Forward Section "Modifying the DTML Namespace" will modify above sentence also!
-
-      As you saw in Chapter 4, "Dynamic Content with DTML", if Zope
-      cannot find a variable in the client object, it searches through
-      the object's containers.  Zope uses acquisition to automatically
-      inherit variables from the client object's containers.  So when
-      Zope walks up the object hierarchy looking for variables it
-      always starts at the client object, and works its way up from
-      there.
-
-        % Anonymous User - Sep. 24, 2002 1:46 pm:
-         Since the client object is located in the ZODB, it has a location in the ZODB (denoted by its URL); it also
-         implies the object is located in a container.
-         In that case, if Zope can not find the variable *in* the client object (*context*), Zope will also look up
-         the variable in the *container* of the object.
-         ? is acquisition used exclusively for the client object only in the namespace?
-         ? when i take http://www.zopeonarope.com/Misc/chapters8-10.pdf page 199-211,
-         acquisition not only travels upwards the container hierarchy to the root, 
-         but also the PARENT hierarchy given by the URL.
-         Some aspects of acquisition are still a mystery for me. Since acquisition is so central, if it is not
-         explained proper here, where shall i look?
-         "Zope uses acquisition to ... *inherit*": Inheritance is AFAIK already used for class derivation.
-
-        % Anonymous User - Sep. 24, 2002 1:51 pm:
-         ...the PARENT hierarchy given by the URL
-         the URL which initiated the request. This url is not necessarily the url of the client object! The URL is
-         used to *place objects* for one call!
-
-    DTML Request Object
-
-      The request object is the very bottom most object on the DTML
-      namespace stack.  The request contains all of the information
-      specific to the current web request.
-
-        % Anonymous User - July 12, 2002 12:36 am:
-         bottommost
-
-        % Anonymous User - Aug. 18, 2002 7:45 am:
-         ...object on the bottom??? --RAW--
-
-        % Anonymous User - Sep. 24, 2002 1:56 pm:
-         /very // # The request object is at the bottom. Cant go below bottom.
-
-        % Anonymous User - Sep. 24, 2002 2:01 pm:
-         /the very bottom most/at the bottom / 
-         # The request object is at the bottom. Cant go below bottom (very most).
-         # also: a stack *has* a bottom, the request *is at* the bottom
-
-      Just as the client object uses acquisition to look in a number
-      of places for variables, so too the request looks up variables
-      in a number of places. When the request looks for a variable it
-      consults these sources in order:
-
-        1. The CGI environment. The "Common Gateway
-           Interface":http://www.w3.org/CGI/, or CGI interface defines
-           a standard set of environment variables to be used by
-           dynamic web scripts.  These variables are provided by Zope
-           in the REQUEST namespace.
-
-        2. Form data. If the current request is a form action, then
-           any form input data that was submitted with the request can
-           be found in the REQUEST object.
-
-        3. Cookies. If the client of the current request has any cookies
-           these can be found in the current REQUEST object.
-
-        4. Additional variables. The REQUEST namespace provides you
-           with lots of other useful information, such as the URL of
-           the current object and all of its parents.
-
-        % Anonymous User - Sep. 24, 2002 2:11 pm:
-         - neither client object nor request object do the lookup, the DTML interpreter does.
-         - the request object is *constructed* before the call to include the following sources
-         - Form data: see http://www.zope.org/Members/Zen/howto/FormVariableTypes
-           and http://www.dieter.handshake.de/pyprojects/zope/book/chap3.html
-
-      The request namespace is very useful in Zope since it is the
-      primary way that clients (in this case, web browsers)
-      communicate with Zope by providing form data, cookies and other
-      information about themselves. For more information about the
-      request object, see Appendix B.
-
-      A very simple and enlightening example is to simply print the REQUEST
-      out in an HTML page::
-
-        <dtml-var standard_html_header>
-
-        <dtml-var REQUEST>
-
-        <dtml-var standard_html_footer>
-
-        % Anonymous User - Aug. 18, 2002 7:49 am:
-         should HTML page be DTML Document ?? --RAW--
-
-        % Anonymous User - Sep. 24, 2002 2:14 pm:
-         It is also a very useful debugging technique.
-         The REQUEST objects __call__-method gives a suitable HTML representation string of itself.
-
-        % Anonymous User - Sep. 24, 2002 2:16 pm:
-         dtml-var does not print! it inserts a string. HTML output usually is not printed, but displayed by a browser.
-
-      Try this yourself, you should get something that looks like
-      [7-4].
-
-      "Displaying the request.":img:7-4:Figures/7-4.png
-
-      Since the request comes after the client object, if there are names
-      that exist in both the request and the client object, DTML will
-      always find them first in the client object. This can be a
-      problem. Next, let's look at some ways to get around this problem by
-      controlling more directly how DTML looks up variables.
-
-    Rendering Variables
-
-      When you insert a variable using the *var* tag, Zope first looks
-      up the variable using the DTML namespace, it then *renders* it
-      and inserts the results. Rendering means turning an object or
-      value into a string suitable for inserting into the output. Zope
-      renders simple variables by using Python's standard method for
-      coercing objects to strings. For complex objects such as DTML
-      Methods and SQL Methods, Zope will call the object instead of
-      just trying to turn it into a string. This allows you to insert
-      DTML Methods into other DTML Methods.
-
-      In general Zope renders variables in the way you would
-      expect. It's only when you start doing more advanced tricks that
-      you become aware of the rendering process. Later in this chapter
-      we'll look at some examples of how to control rendering using
-      the 'getitem' DTML utility function.
-
-  Modifying the DTML Namespace
-
-    Now that you have seen that the DTML namespace is a stack, you may
-    be wondering how, or even why, new objects get pushed onto it.
-
-      % Anonymous User - Sep. 24, 2002 2:24 pm:
-       /Now that you have seen that /Since [we said that]/ # aint seen yet
-
-      % Anonymous User - Sep. 24, 2002 2:26 pm:
-       Twice before there were implicit (=non obvious) references to here!
-
-    Some DTML tags modify the DTML namespace while they are executing.
-    A tag may push some object onto the namespace stack during the
-    course of execution.  These tags include the *in* tag, the *with*
-    tag, and the *let* tag.
-
-    *In* Tag Namespace Modifications
-
-      When the *in* tag iterates over a sequence it pushes the current
-      item in the sequence onto the top of the namespace stack::
-
-        <dtml-var getId> <!-- This is the id of the client object -->
-
-        <dtml-in objectValues>
-
-          <dtml-var getId> <!-- this is the id of the current item in the 
-                             objectValues sequence -->
-        </dtml-in>
-
-      You've seen this many times throughout the examples in this
-      book.  While the *in* tag is iterating over a sequence, each item
-      is pushed onto the namespace stack for the duration of the
-      contents of the in tag block.  When the block is finished
-      executing, the current item in the sequence is popped off the
-      DTML namespace stack and the next item in the sequence is pushed
-      on.
-
-        % htrd - Apr. 24, 2002 9:03 am:
-         (Re the changes from http://collector.zope.org/Zope/358 that I am about to merge) 
-         Use the optional "no_push_item" to inhibit "dtml-in" pushing each item onto the stack in this way. 
-         You may want to do this to access names that are already in the DTML namespace, without worrying 
-         about whether the same name is also provided by the objects in the sequence.
-
-        % Anonymous User - Sep. 24, 2002 2:32 pm:
-         More exactly: an iteration object is pushed. This iteration object contains the current object in the
-         iteration along with a plethora of variables describing the iteration state (sequence-index and the like).
-
-    The *With* Tag
-
-      The *with* tag pushes an object that you specify onto the top of
-      the namespace stack for the duration of the with block. This
-      allows you to specify where variables should be looked up first.
-      When the with block closes, the object is popped off the
-      namespace stack.
-
-      Consider a folder that contains a bunch of methods and
-      properties that you are interested in.  You could access those
-      names with Python expressions like this::
-
-        <dtml-var standard_html_header>
-
-        <dtml-var expr="Reptiles.getReptileInfo()">
-        <dtml-var expr="Reptiles.reptileHouseMaintainer">
-
-        <dtml-in expr="Reptiles.getReptiles()">
-          <dtml-var species>
-        </dtml-in>
-
-        <dtml-var standard_html_footer>
-
-      Notice that a lot of complexity is added to the code just to get
-      things out of the *Reptiles* folder. Using the *with* tag you can
-      make this example much easier to read::
-
-        <dtml-var standard_html_header>
-
-        <dtml-with Reptiles>
-
-          <dtml-var getReptileInfo>
-          <dtml-var reptileHouseMaintainer>
-
-          <dtml-in getReptiles>
-            <dtml-var species>
-          </dtml-in>
-
-        </dtml-with>
-
-        <dtml-var standard_html_footer>
-
-        % Anonymous User - Aug. 21, 2002 10:59 am:
-         Somehow the get()-function is not interpreted correctly. I always get the following error message:
-         Error Type: KeyError
-         Error Value: getReptiles
-         Why??
-
-        % krump - Aug. 27, 2002 1:54 pm:
-         It is not a working example. If there were a function called 'getReptileInfo()' and say a string property for
-         the Reptiles folder called 'reptileHouseMaintainer' it might work.
-
-      Another reason you might want to use the *with* tag is to put the
-      request, or some part of the request on top of the namespace
-      stack. For example suppose you have a form that includes an input
-      named *id*. If you try to process this form by looking up the
-      *id* variable like so::
-
-        <dtml-var id>
-
-      You will not get your form's id variable, but the client
-      object's id. One solution is to push the web request's form on
-      to the top of the DTML namespace stack using the *with* tag::
-
-        <dtml-with expr="REQUEST.form">
-          <dtml-var id>
-        </dtml-with>
-
-      This will ensure that you get the form's id first. See Appendix
-      B for complete API documentation of the request object.
-
-        % Anonymous User - Sep. 24, 2002 2:36 pm:
-         /for complete/for a complete/
-
-      If you submit your form without supplying a value for the *id* input,
-      the form on top of the namespace stack will do you no good, since the
-      form doesn't contain an *id* variable. You'll still get the client
-      object's id since DTML will search the client object after failing to
-      find the *id* variable in the form. The *with* tag has an attribute
-      that lets you trim the DTML namespace to only include the object you
-      specify::
-
-        <dtml-with expr="REQUEST.form" only>
-          <dtml-if id>
-            <dtml-var id>
-          <dtml-else>
-            <p>The form didn't contain an "id" variable.</p>
-          </dtml-if>
-        </dtml-with>
-
-      Using the *only* attribute allows you to be sure about where
-      your variables are being looked up.
-
-        % Anonymous User - Sep. 24, 2002 2:41 pm:
-         ... restricts the lookup to just the object pushed.
-         # i dont use *only* for my private feelings, but for its effect in name loookup
-
-    The *Let* Tag
-
-      The *let* tag lets you push a new namespace onto the namespace stack.
-      This namespace is defined by the tag attributes to the *let* tag::
-
-        <dtml-let person="'Bob'" relation="'uncle'">
-          <p><dtml-var person>'s your <dtml-var relation>.</p>
-        </dtml-let>
-
-      This would display::
-
-        <p>Bob's your uncle.</p>
-
-      The *let* tag accomplishes much of the same goals as the *with*
-      tag. The main advantage of the let tag is that you can use it to
-      define multiple variables to be used in a block. The *let* tag
-      creates one or more new variables and their values and pushes a
-      namespace object containing those variables and their values on
-      to the top of the DTML namespace stack. In general the *with*
-      tag is more useful to push existing objects onto the namespace
-      stack, while the *let* tag is better suited for defining new
-      variables for a block.
-
-        % Anonymous User - Sep. 24, 2002 2:50 pm:
-         /creates one or more new variables and their values/creates one or more new variables from the name=value
-         pairs given/
-         /and their values//
-         # A variable is a pair (name, value)
-
-      When you find yourself writing complex DTML that requires things
-      like new variables, there's a good chance that you could do the
-      same thing better with Python or Perl. Advanced scripting is
-      covered in Chapter 10, "Advanced Zope Scripting".
-
-      The DTML namespace is a complex place, and this complexity evolved
-      over a lot of time.  Although it helps to understand where names come
-      from, it is much more helpful to always be specific about where you
-      are looking for a name.  The 'with' and 'let' tags let you control
-      the namespace to look exactly in the right place for the name you are
-      looking for.
-
-        % Anonymous User - Sep. 24, 2002 2:54 pm:
-         /the namespace/the DTML interpreter/
-         # the namespace doesnt (actively) look up, it is (passively) looked up
-
-  DTML Namespace Utility Functions 
-
-    Like all things in Zope, the DTML namespace is an object, and it can
-    can be accessed directly in DTML with the *_* (underscore) object.  The
-    *_* namespace is often referred to as as "the under namespace".
-
-      % Anonymous User - July 23, 2002 4:28 am:
-       can can
-
-      % Anonymous User - July 24, 2002 3:32 pm:
-       as as
-
-      % Anonymous User - Sep. 24, 2002 3:03 pm:
-       # As i understand it, '_' is the name for the _-object.
-       # Then better:
-       Like all things in Zope, the DTML namespace is an object. It has the special name of "_" (underscore) and it
-       can be accessed directly in DTML by this name to look up other names. The _ namespace is often referred to as
-       as "the under namespace".
-
-    The under namespace provides you with many useful methods for certain
-    programming tasks.  Let's look at a few of them.
-
-    Say you wanted to print your name three times.  This can be done
-    with the *in* tag, but how do you explicitly tell the *in* tag to
-    loop three times?  Just pass it a sequence with three items::
-
-      <dtml-var standard_html_header>
-
-      <ul>
-      <dtml-in expr="_.range(3)">
-        <li><dtml-var sequence-item>: My name is Bob.</li>
-      </dtml-in>
-      </ul>
-
-      <dtml-var standard_html_footer>
-
-    The '_.range(3)' Python expression will return a sequence of the
-    first three integers, 0, 1, and 2.  The *range* function is a
-    *standard Python built-in* and many of Python's built-in functions
-    can be accessed through the *_* namespace, including:
-
-      'range([start,], stop, [step])' -- Returns a list of integers
-      from 'start' to 'stop' counting 'step' integers at a
-      time. 'start' defaults to 0 and 'step' defaults to 1.  For example::
-
-        '_.range(3,9,2)' -- gives '[3,5,7,9]'.
-
-        'len(sequence)' -- 'len' returns the size of *sequence* as an integer.
-
-    Many of these names come from the Python language, which contains a set
-    of special functions called 'built-ins'.  The Python philosophy is to
-    have a small, set number of built-in names.  The Zope philosphy can be
-    thought of as having a large, complex array of built-in names.
-
-      % Anonymous User - Apr. 17, 2002 3:34 am:
-       mispelling. should be: philosophy
-
-      % Anonymous User - June 27, 2002 7:40 pm:
-       '_.len(sequence)' instead of 'len(sequence)' -VS
-
-      % Anonymous User - Sep. 24, 2002 4:05 pm:
-       /small, set number/ # typo? do you mean /small, fixed number/?
-
-      % Anonymous User - Nov. 28, 2002 6:15 pm:
-       Or just "small number"  its neither fixed nor set for all time the philosophy is just to keep it small.
-
-    The under namespace can also be used to explicitly control variable
-    look up.  There is a very common usage of this syntax.  You've seen
-    that the in tag defines a number of special variables, like
-    *sequence-item* and *sequence-key* that you can use inside a loop to
-    help you display and control it.  What if you wanted to use one of
-    these variables inside a Python expression?::
-
-      <dtml-var standard_html_header>
-
-      <h1>The squares of the first three integers:</h1>
-      <ul>
-      <dtml-in expr="_.range(3)">
-        <li>The square of <dtml-var sequence-item> is: 
-          <dtml-var expr="sequence-item * sequence-item">
-        </li>
-      </dtml-in>  
-      </ul>  
-
-      <dtml-var standard_html_footer>
-
-    Try this, does it work?  No!  Why not?  The problem lies in this
-    var tag::
-
-      <dtml-var expr="sequence-item * sequence-item">
-
-    Remember, everything inside a Python expression attribute must be
-    a *valid Python expression*.  In DTML, *sequence-item* is the name
-    of a variable, but in Python this means "The object *sequence*
-    minus the object *item*".  This is not what you want.
-
-      % Anonymous User - Sep. 24, 2002 4:20 pm:
-       To make a long explanation short:
-       Python names have the familiar structure excluding special characters, 
-       ("start with letter, follow with letter or digit where '_' counts as letter")
-       while DTML names may contain any character, including the hyphen which in python is the minus-operator.
-
-    What you really want is to look up the variable *sequence-item*.
-    One way to solve this problem is to use the *in* tag *prefix*
-    attribute. For example::
-
-      <dtml-var standard_html_header>
-
-      <h1>The squares of the first three integers:</h1>
-      <ul>
-      <dtml-in prefix="loop" expr="_.range(3)">
-        <li>The square of <dtml-var loop_item> is: 
-          <dtml-var expr="loop_item * loop_item">
-        </li>
-      </dtml-in>  
-      </ul>  
-
-      <dtml-var standard_html_footer>   
-
-    The *prefix* attribute causes *in* tag variables to be renamed
-    using the specified prefix and underscores, rather than using
-    "sequence" and dashes. So in this example, "sequence-item" becomes
-    "loop_item". See Appendix A for more information on the *prefix*
-    attribute.
-
-    Another way to look up the variable *sequence-item* in a DTML
-    expression is to use the *getitem* utility function to explicitly
-    look up a variable::
-
-      The square of <dtml-var sequence-item> is:
-      <dtml-var expr="_.getitem('sequence-item') * 
-                      _.getitem('sequence-item')">
-
-      % Anonymous User - Sep. 24, 2002 4:29 pm:
-       What abt the often seen
-       <dtml-var expr="_['sequence-item']">
-
-    The *getitem* function takes the name to look up as its first
-    argument. Now, the DTML Method will correctly display the sum of the
-    first three integers.  The *getitem* method takes an optional second
-    argument which specifies whether or not to render the variable. Recall
-    that rendering a DTML variable means turning it into a string. By
-    default the *getitem* function does not render a variable.
-
-      % Anonymous User - Aug. 22, 2002 5:10 am:
-       It's not the sum but rather the square of the first three integers.
-
-    Here's how to insert a rendered variable named *myDoc*::
-
-      <dtml-var expr="_.getitem('myDoc', 1)">
-
-    This example is in some ways rather pointless, since it's the
-    functional equivalent to::
-
-      <dtml-var myDoc>
-
-    However, suppose you had a form in which a user got to select
-    which document they wanted to see from a list of choices. Suppose
-    the form had an input named *selectedDoc* which contained the name
-    of the document. You could then display the rendered document like
-    so::
-
-      <dtml-var expr="_.getitem(selectedDoc, 1)">
-
-      % Anonymous User - Aug. 22, 2002 7:04 am:
-       Does this work for subFOLDERS as well?
-
-    Notice in the above example that *selectedDoc* is not in
-    quotes. We don't want to insert the variable named *selectedDoc*
-    we want to insert the variable *named by* *selectedDoc*. For
-    example, the value of *selectedDoc* might be *chapterOne*. Using
-    indirect variable insertion you can insert the *chapterOne*
-    variable. This way you can insert a variable whose name you don't
-    know when you are authoring the DTML. 
-
-    If you a python programmer and you begin using the more complex
-    aspects of DTML, consider doing a lot of your work in Python
-    scripts that you call *from* DTML.  This is explained more in
-    Chapter 10, "Advanced Zope Scripting".  Using Python sidesteps
-    many of the issues in DTML.
-
-      % Anonymous User - Apr. 28, 2002 8:48 pm:
-       If I be a ...
-
-  DTML Security
-
-    Zope can be used by many different kinds of users.  For example, the
-    Zope site, "Zope.org":http://www.zope.org/, has over 11,000 community
-    members at the time of this writing.  Each member can log into Zope,
-    add objects and news items, and manage their own personal area.
-
-    Because DTML is a scripting language, it is very flexible about
-    working with objects and their properties.  If there were no security
-    system that constrained DTML then a user could potentially create
-    malicious or privacy-invading DTML code.
-
-    DTML is restricted by standard Zope security settings. So if you
-    don't have permission to access an object by going to its URL you
-    also don't have permission to access it via DTML. You can't use
-    DTML to trick the Zope security system.
-
-    For example, suppose you have a DTML Document named *Diary* which
-    is private. Anonymous users can't access your diary via the
-    web. If an anonymous user views DTML that tries to access your
-    diary they will be denied::
-
-      <dtml-var Diary>
-
-    DTML verifies that the current user is authorized to access all
-    DTML variables.  If the user does not have authorization, than the
-    security system will raise an *Unauthorized* error and the user
-    will be asked to present more privileged authentication
-    credentials.
-
-      % Anonymous User - July 5, 2002 12:50 pm:
-       "If the user ..., than" should be "If the user ..., then"
-       "than" is a comparison (this is greater than that)
-       "then" is temporal (if this happens then this other thing happens next)
-
-    In Chapter 7, "Users and Security" you read about security rules
-    for executable content. There are ways to tailor the roles of a
-    DTML Document or Method to allow it to access restricted variables
-    regardless of the viewer's roles.
-
-   Safe Scripting Limits
-
-      DTML will not let you gobble up memory or execute infinite loops
-      and recursions.  Because the restrictions on looping and memory
-      use are relatively tight, DTML is not the right language for
-      complex, expensive programming logic.  For example, you cannot
-      create huge lists with the *_.range* utility function. You also
-      have no way to access the filesystem directly in DTML.
-
-        % Anonymous User - Sep. 24, 2002 4:43 pm:
-         The _*_.range*_ function is a restricted version of the (python) range function.
-
-      Keep in mind however that these safety limits are simple and can be
-      outsmarted by a determined user.  It's generally not a good idea to
-      let anyone you don't trust write DTML code on your site.
-
-  Advanced DTML Tags
-
-    In the rest of this chapter we'll look at the many advanced DTML
-    tags. These tags are summarized in Appendix A.  DTML has a set of
-    built-in tags, as documented in this book, which can be counted on
-    to be present in all Zope installations and perform the most
-    common kinds of things. However, it is also possible to add new
-    tags to a Zope installation. Instructions for doing this are
-    provided at the Zope.org website, along with an interesting set
-    of contributed DTML tags.
-
-      % Anonymous User - Sep. 24, 2002 5:02 pm:
-       Although it goes a little deeper than previous chapters still stays in shallow waters. Dont waste time, goto
-       Appendix A. As to expanding zope with new tags,
-       at least some hrefs would be ok here, if you dont want to burden readers of this "Advanced" chapter w
-       advanced knowledge.
-
-    This section covers what could be referred to as Zope
-    *miscellaneous* tags.  These tags don't really fit into any broad
-    categories except for one group of tags, the *exception handling*
-    DTML tags which are discussed at the end of this chapter.
-
-  The *Call* Tag
-
-    The *var* tag can call methods, but it also inserts the return
-    value. Using the *call* tag you can call methods without inserting
-    their return value into the output.  This is useful if you are
-    more interested in the effect of calling a method rather than its
-    return value.
-
-      % Anonymous User - Sep. 24, 2002 5:05 pm:
-       The *side effect*
-
-    For example, when you want to change the value of a property,
-    *animalName*, you are more interested in the effect of calling the
-    *manage_changeProperties* method than the return value the method
-    gives you.  Here's an example::
-
-      <dtml-if expr="REQUEST.has_key('animalName')">
-        <dtml-call expr="manage_changeProperties(animalName=REQUEST['animalName'])">
-        <h1>The property 'animalName' has changed</h1>
-      <dtml-else>
-        <h1>No properties were changed</h1>
-      </dtml-if>
-
-    In this example, the page will change a property depending on whether
-    a certain name exists.  The result of the *manage_changeProperties*
-    method is not important and does not need to be shown to the user.
-
-    Another common usage of the *call* tag is calling methods that affect
-    client behavior, like the 'RESPONSE.redirect' method.  In this
-    example, you make the client redirect to a different page, to
-    change the page that gets redirected, change the value for the
-    "target" variable defined in the *let* tag::
-
-      <dtml-var standard_html_header>
-
-      <dtml-let target="'http://example.com/new_location.html'">
-
-        <h1>This page has moved, you will now be redirected to the
-        correct location.  If your browser does not redirect, click <a
-        href="<dtml-var target>"><dtml-var target></a>.</h1>
-
-        <dtml-call expr="RESPONSE.redirect(target)">
-
-      </dtml-let>
-
-      <dtml-var standard_html_footer>  
-
-    In short, the *call* tag works exactly like the *var* tag with the
-    exception that it doesn't insert the results of calling the
-    variable.
-
-      % Anonymous User - Aug. 10, 2002 1:58 am:
-       How would you use &lt;dtml-call&gt; to call a ZSQL Method and pass it some input?
-
-      % Anonymous User - Sep. 24, 2002 5:12 pm:
-       Or call a Python Script to preprocess a REQUEST 
-       (say, setting defaults, checking previous form values)?
-       So far in this book i have not seen a complete discussion of calling callables including parameter passing.
-
-  The *Comment* Tag
-
-    DTML can be documented with comments using the *comment* tag::
-
-      <dtml-var standard_html_header>
-
-      <dtml-comment>
-
-        This is a DTML comment and will be removed from the DTML code
-        before it is returned to the client.  This is useful for
-        documenting DTML code.  Unlike HTML comments, DTML comments
-        are NEVER sent to the client.
-
-      </dtml-comment>
-
-      <!-- 
-
-        This is an HTML comment, this is NOT DTML and will be treated
-        as HTML and like any other HTML code will get sent to the
-        client.  Although it is customary for an HTML browser to hide
-        these comments from the end user, they still get sent to the
-        client and can be easily seen by 'Viewing the Source' of a
-        document.
-
-      -->
-
-      <dtml-var standard_html_footer>        
-
-      % Anonymous User - Apr. 29, 2002 1:57 pm:
-       It doesnt render the HTML, but Zope does validate the code, so commenting on partial DTML *produces errors*
-       even though it is commented out. Zope tries to validate all the code, even though it does not render it. This
-       is counter-intuitive and cripples good documentation practices.
-       Zope collector Issue 370
-       http://collector.zope.org/Zope/370
-
-    The *comment* block is removed from DTML output.
-
-    In addition to documenting DTML you can use the *comment* tag to
-    temporarily comment out other DTML tags. Later you can remove the
-    *comment* tags to re-enable the DTML.
-
-      % gl03 - Apr. 26, 2002 9:31 am:
-       commented dtml is still parsed to the effect that you cannot save bad dtml even if it's commented out!
-       (wouldn't mind seeing this changed...)
-
-      % Anonymous User - July 19, 2002 4:01 am:
-       Especially as progressively commenting less and less of a document is a well understood and oft-used method
-       for debugging
-
-      % Anonymous User - Sep. 24, 2002 5:16 pm:
-       Hint: since browsers hide <...> when they dont see a tag, 
-       commenting out single dtml tags just put an x before "dtml" like
-       <xdtml-var blah>.
-
-  The *Tree* Tag
-
-    The *tree* tag lets you easily build dynamic trees in HTML to
-    display hierarchical data.  A *tree* is a graphical representation
-    of data that starts with a "root" object that has objects
-    underneath it often referred to as "branches".  Branches can have
-    their own branches, just like a real tree.  This concept should be
-    familiar to anyone who has used a file manager program like
-    Microsoft Windows Explorer to navigate a file system.  And, in
-    fact, the left hand "navigation" view of the Zope management
-    interface is created using the tree tag.
-
-    For example here's a tree that represents a collection of folders
-    and sub-folders.
-
-    "HTML tree generated by the tree tag.":img:7-5:Figures/7-5.png
-
-    Here's the DTML that generated this tree display::
-
-      <dtml-var standard_html_header>
-
-      <dtml-tree>
-
-        <dtml-var getId>
-
-      </dtml-tree>
-
-      <dtml-var standard_html_footer>
-
-    The *tree* tag queries objects to find their sub-objects and takes
-    care of displaying the results as a tree. The *tree* tag block works
-    as a template to display nodes of the tree.
-
-    Now, since the basic protocol of the web, HTTP, is stateless, you
-    need to somehow remember what state the tree is in every time you
-    look at a page.  To do this, Zope stores the state of the tree in
-    a *cookie*.  Because this tree state is stored in a cookie, only
-    one tree can appear on a web page at a time, otherwise they will
-    confusingly use the same cookie.
-
-    You can tailor the behavior of the *tree* tag quite a bit with *tree*
-    tag attributes and special variables. Here is a sampling of *tree*
-    tag attributes.
-
-      branches -- The name of the method used to find sub-objects. This
-      defaults to *tpValues*, which is a method defined by a number of
-      standard Zope objects.
-
-      leaves -- The name of a method used to display objects that do
-      not have sub-object branches.
-
-      nowrap -- Either 0 or 1. If 0, then branch text will wrap to fit in
-      available space, otherwise, text may be truncated. The default
-      value is 0.
-
-      sort -- Sort branches before text insertion is performed. The
-      attribute value is the name of the attribute that items should be
-      sorted on.
-
-      assume_children -- Either 0 or 1. If 1, then all objects are
-      assumed to have sub-objects, and will therefore always have a
-      plus sign in front of them when they are collapsed. Only when an
-      item is expanded will sub-objects be looked for. This could be a
-      good option when the retrieval of sub-objects is a costly
-      process.  The defalt value is 0.
-
-      single -- Either 0 or 1. If 1, then only one branch of the tree can
-      be expanded. Any expanded branches will collapse when a new branch
-      is expanded.  The default value is 0.
-
-      skip_unauthorized -- Either 0 or 1. If 1, then no errors will be
-      raised trying to display sub-objects for which the user does not
-      have sufficient access. The protected sub-objects are not
-      displayed.  The default value is 0.
-
-    Suppose you want to use the *tree* tag to create a dynamic site
-    map. You don't want every page to show up in the site map. Let's
-    say that you put a property on folders and documents that you want
-    to show up in the site map.
-
-    Let's first define a Script with the id of *publicObjects*
-    that returns public objects::
-
-      ## Script (Python) "publicObjects"
-      ##
-      """
-      Returns sub-folders and DTML documents that have a
-      true 'siteMap' property.
-      """
-      results=[]
-      for object in context.objectValues(['Folder', 'DTML Document']):
-          if object.hasProperty('siteMap') and object.siteMap:
-              results.append(object)
-      return results
-
-    Now we can create a DTML Method that uses the *tree* tag and our
-    Scripts to draw a site map::
-
-      <dtml-var standard_html_header>
-
-      <h1>Site Map</h1>
-
-      <p><a href="&dtml-URL0;?expand_all=1">Expand All</a> |
-         <a href="&dtml-URL0;?collapse_all=1">Collapse All</a>
-      </p>
-
-      <dtml-tree branches="publicObjects" skip_unauthorized="1">
-        <a href="&dtml-absolute_url;"><dtml-var title_or_id></a>
-      </dtml-tree>
-
-      <dtml-var standard_html_footer>
-
-      % Anonymous User - Sep. 21, 2002 4:32 am:
-       <dtml-with AnyRootFolder>
-         <dtml-tree branches="getSubFolders">
-           <a href="&dtml-absolute_url;"><dtml-var title_or_id></a>
-         </dtml-tree>
-       </dtml-with>
-       The tree is rooted in current Folder, but not in AnyRootFolder.
-       Why ???
-
-      % Anonymous User - Sep. 26, 2002 5:32 am:
-       (Zope 2.5.1 (source release, python 2.1, linux2), python 2.1.3, linux2)
-       i needed:
-       <dtml-tree branches_expr="publicObjects()" skip_unauthorized="1">
-       to make it work.
-
-      % Saman - Nov. 17, 2002 7:31 am:
-       this dose not work..I can't figre it out
-       the only thin I get is:
-       Site Map
-       Expand All  Collapse All
-       it seems that the script is never called????
-
-    This DTML Method draws a link to all public resources and displays
-    them in a tree. Here's what the resulting site map looks like.
-
-    "Dynamic site map using the tree tag.":img:7-6:Figures/7-6.png
-
-    For a summary of the *tree* tag arguments and special variables see
-    Appendix A.
-
-  The *Return* Tag
-
-    In general DTML creates textual output. You can however, make DTML
-    return other values besides text. Using the *return* tag you can
-    make a DTML Method return an arbitrary value just like a Python or
-    Perl-based Script.
-
-    Here's an example::
-
-      <p>This text is ignored.</p>
-
-      <dtml-return expr="42">
-
-    This DTML Method returns the number 42.
-
-    Another upshot of using the *return* tag is that DTML execution
-    will stop after the *return* tag.
-
-      % Anonymous User - Sep. 24, 2002 4:51 pm:
-       This allows to avoid expensive computations after RESPONSE.redirect like
-       <dtml-call "RERSPONSE.redirect( some_url )">
-       <dtml-return>
-
-    If you find yourself using the *return* tag, you almost certainly
-    should be using a Script instead. The *return* tag was developed
-    before Scripts, and is largely useless now that you can easily
-    write scripts in Python and Perl.
-
-  The *Sendmail* Tag
-
-    The *sendmail* tag formats and sends a mail messages. You can use
-    the *sendmail* tag to connect to an existing Mail Host, or you can
-    manually specify your SMTP host.
-
-      % Anonymous User - Aug. 26, 2002 1:18 pm:
-       Yes, but how do you specify which existing mail host - or how do you specify SMTP manually???
-
-    Here's an example of how to send an email message with the
-    *sendmail* tag::
-
-      <dtml-sendmail>
-      To: <dtml-var recipient>
-      Subject: Make Money Fast!!!!
-
-      Take advantage of our exciting offer now! Using our exclusive method
-      you can build unimaginable wealth very quickly. Act now!
-      </dtml-sendmail>
-
-      % Anonymous User - May 13, 2002 4:49 pm:
-       I guess there is a missing 'From:' prompt after 'To:'.
-
-      % Anonymous User - July 19, 2002 4:09 am:
-       From: is probably not necessary
-       in most cases (I don't know whether this is the case with zope, but it would make sense) from defaults to the
-       user which the webserver runs as (e.g. nobody/httpd/apache/whatever)
-
-    Notice that there is an extra blank line separating the mail
-    headers from the body of the message.
-
-    A common use of the *sendmail* tag is to send an email message
-    generated by a feedback form. The *sendmail* tag can contain any
-    DTML tags you wish, so it's easy to tailor your message with form
-    data.
-
-  The *Mime* Tag
-
-    The *mime* tag allows you to format data using MIME (Multipurpose
-    Internet Mail Extensions). MIME is an Internet standard for
-    encoding data in email message. Using the *mime* tag you can use
-    Zope to send emails with attachments.
-
-    Suppose you'd like to upload your resume to Zope and then have Zope
-    email this file to a list of potential employers.
-
-    Here's the upload form::
-
-      <dtml-var standard_html_header>
-
-      <p>Send you resume to potential employers</p>
-
-      <form method=post action="sendresume" ENCTYPE="multipart/form-data">
-      <p>Resume file: <input type="file" name="resume_file"></p>
-      <p>Send to:</p>
-      <p>
-      <input type="checkbox" name="send_to:list" value="jobs at yahoo.com">
-        Yahoo<br>
-
-      <input type="checkbox" name="send_to:list" value="jobs at microsoft.com">
-        Microsoft<br>
-
-      <input type="checkbox" name="send_to:list" value="jobs at mcdonalds.com">
-        McDonalds</p>
-
-      <input type=submit value="Send Resume">
-      </form>
-
-      <dtml-var standard_html_footer>
-
-      % Anonymous User - Oct. 16, 2002 8:53 pm:
-       Why does the name field of the checkbox contain the ":list" part? What does that do?
-
-    Create another DTML Method called *sendresume* to process the form
-    and send the resume file::
-
-      <dtml-var standard_html_header>
-
-      <dtml-if send_to>
-
-        <dtml-in send_to> 
-
-          <dtml-sendmail smtphost="my.mailserver.com">
-          To: <dtml-var sequence-item>
-          Subject: Resume
-          <dtml-mime type=text/plain encode=7bit>
-
-          Hi, please take a look at my resume.
-
-          <dtml-boundary type=application/octet-stream disposition=attachment 
-          encode=base64><dtml-var expr="resume_file.read()"></dtml-mime>
-          </dtml-sendmail>
-
-        </dtml-in>
-
-        <p>Your resume was sent.</p>
-
-      <dtml-else>
-
-        <p>You didn't select any recipients.</p>
-
-      </dtml-if>
-
-      <dtml-var standard_html_footer>    
-
-      % Anonymous User - June 27, 2002 8:13 am:
-       I've experencied problem without 'From:' prompt. Without it, the error was :
-       "Error Type: TypeError
-       Error Value: len() of unsized object"
-
-      % m2ic - June 27, 2002 10:45 am:
-       Be care also with trailing spaces
-
-    This method iterates over the *sendto* variable and sends one
-    email for each item.
-
-    Notice that there is no blank line between the 'To:' header and
-    the starting *mime* tag.  If a blank line is inserted between them
-    then the message will not be interpreted as a *multipart* message
-    by the receiving mail reader.
-
-    Also notice that there is no newline between the *boundary* tag
-    and the *var* tag, or the end of the *var* tag and the closing
-    *mime* tag.  This is important, if you break the tags up with
-    newlines then they will be encoded and included in the MIME part,
-    which is probably not what you're after.
-
-    As per the MIME spec, *mime* tags may be nested within *mime* tags
-    arbitrarily.
-
-      % Anonymous User - Nov. 26, 2002 9:07 am:
-       How is this done for multiple file attachments? Looping over the boundary tag seems not to be allowed. Looping
-       inside the boundary tag causes all attachments to be placed in a single file. Looping over the mime or
-       sendmail tags causes separate messages to be sent. Also, how do you specify the filenames of the attachments
-       - they are given internally generated names by default.
-
-  The *Unless* Tag
-
-    The *unless* tag executes a block of code unless the given condition is
-    true. The *unless* tag is the opposite of the *if* tag.  The DTML
-    code::
-
-      <dtml-if expr="not butter">
-        I can't believe it's not butter.
-      </dtml-if>
-
-    is equivalent to::
-
-      <dtml-unless expr="butter">
-        I can't believe it's not butter.
-      </dtml-unless>
-
-    What is the purpose of the *unless* tag? It is simply a convenience
-    tag. The *unless* tag is more limited than the *if* tag, since it
-    cannot contain an *else* or *elif* tag.
-
-    Like the *if* tag, calling the *unless* tag by name does existence
-    checking, so::
-
-      <dtml-unless the_easter_bunny>
-        The Easter Bunny does not exist or is not true.
-      </dtml-unless>
-
-      % Anonymous User - Sep. 24, 2002 5:28 pm:
-       This comes nice to provide the REQUEST with default variables
-       (if they were not set in a previous html form) like
-       <dtml-unless "REQUEST.has_key('the_easter_bunny')">
-         <dtml-call "REQUEST.set('the_easter_bunny', 0)">
-       </dtml-unless>
-
-    Checks for the existence of *the_easter_bunny* as well as its
-    truth. While this example only checks for the truth of
-    *the_easter_bunny*::
-
-      <dtml-unless expr="the_easter_bunny">
-        The Easter Bunny is not true.
-      </dtml-unless>
-
-    This example will raise an exception if *the_easter_bunny* does not
-    exist.
-
-      % Anonymous User - Sep. 24, 2002 5:40 pm:
-       The differentiation between dtml name attributes and expr attributes
-       is smeared over chapter 4:
-       http://www.zope.org/Documentation/Books/ZopeBook/current/DTML.stx
-
-    Anything that can be done by the *unless* tag can be done by the
-    *if* tag.  Thus, its use is totally optional and a matter of
-    style.
-
-      % Anonymous User - Sep. 24, 2002 5:43 pm:
-       /totally optional and// # totalitarian options, and freedom is slavery
-
-  Batch Processing With The *In* Tag
-
-    Often you want to present a large list of information but only
-    show it to the user one screen at a time.  For example, if a
-    user queried your database and got 120 results, you will probably
-    only want to show them to the user a small batch, say 10 or 20
-    results per page.  Breaking up large lists into parts is called
-    *batching*. Batching has a number of benefits.
-
-      o The user only needs to download a reasonably sized document
-      rather than a potentially huge document. This makes pages load
-      faster since they are smaller.
-
-      o Because smaller batches of results are being used, often less
-      memory is consumed by Zope.
-
-      o *Next* and *Previous* navigation interfaces makes scanning
-      large batches relatively easy.
-
-    The *in* tag provides several variables to facilitate batch
-    processing.  Let's look at a complete example that shows how to
-    display 100 items in batches of 10 at a time::
-
-      <dtml-var standard_html_header>
-
-        <dtml-in expr="_.range(100)" size=10 start=query_start>
-
-          <dtml-if sequence-start>
-
-            <dtml-if previous-sequence>
-              <a href="<dtml-var URL><dtml-var sequence-query
-                 >query_start=<dtml-var previous-sequence-start-number>">
-                 (Previous <dtml-var previous-sequence-size> results)
-              </a>
-            </dtml-if>
-
-            <h1>These words are displayed at the top of a batch:</h1>
-            <ul>
-
-          </dtml-if>
-
-            <li>Iteration number: <dtml-var sequence-item></li>
-
-          <dtml-if sequence-end>
-
-            </ul>
-            <h4>These words are displayed at the bottom of a batch.</h4>
-
-            <dtml-if next-sequence>
-               <a href="<dtml-var URL><dtml-var sequence-query
-                  >query_start=<dtml-var
-                  next-sequence-start-number>">
-               (Next <dtml-var next-sequence-size> results)
-               </a>
-
-            </dtml-if>
-
-          </dtml-if>
-
-        </dtml-in>
-
-      <dtml-var standard_html_footer>
-
-      % Saman - Nov. 17, 2002 8:17 am:
-       this must be a DTNL document in order to function,If you shoose to implemented as Method it will not
-       function?
-       Why is That????
-
-    Let's take a look at the DTML to get an idea of what's going
-    on. First we have an *in* tag that iterates over 100 numbers that
-    are generated by the *range* utility function. The *size*
-    attribute tells the *in* tag to display only 10 items at a
-    time. The *start* attribute tells the *in* tag which item number
-    to display first.
-
-    Inside the *in* tag there are two main *if* tags. The first one
-    tests special variable 'sequence-start'. This variable is only
-    true on the first pass through the in block. So the contents of
-    this if tag will only be executed once at the beginning of the
-    loop. The second *if* tag tests for the special variable
-    'sequence-end'. This variable is only true on the last pass
-    through the *in* tag. So the second *if* block will only be
-    executed once at the end.  The paragraph between the *if* tags is
-    executed each time through the loop.
-
-      % Anonymous User - Apr. 28, 2002 7:15 pm:
-       This is a HORRIBLE example for usablity and should never be implemented.
-       Instead, this should show how-to present <Previous and Next> links at the top and bottom of the batch. Then
-       the example would need to show NOT to use <dtml-if previous-sequence> or <dtml-if next-sequence> because they
-       dont work.
-       Using <dtml-if previous-sequence-start-number>
-       and <dtml-if next-sequence-start-number> is much more flexible and can be placed in any of the if-blocks at
-       the top or bottom of the batch.
-       And then it is still missing an explanantion on how to do batch navigation using the accepted standard of
-       "Page" results. Page: 1 2 3 4 Next>
-
-      % kaleissin - May 16, 2002 3:31 pm:
-       One way is to use *two* dtml-ins... One for the header, one for the actual listing of the results. Which
-       means everything is accessed/done twice. Then maybe you'd like to add the "<Previous 1 2 *3* 4 Next>" blurb
-       *after* the results also, and you use a *third* dtml-in etc... nice excuse to buy a bigger server/faster cpu
-       in the end, and lots of money going to your therapist ;)
-
-      % Anonymous User - Sep. 11, 2002 12:40 pm:
-       Here is an example how to do batch navigation using the 
-       page 1 2 3 4 ...   Method
-       I'm a Zope newbie, so it could possibly done more elegant.
-       <dtml-call "REQUEST.set('save_url',_['absolute_url'])">     
-       <dtml-in sqlMethod size=10 start=start>
-         <dtml-if sequence-start>
-           <p>Pages: 
-           <dtml-call "REQUEST.set('actual_page',1)">
-           <dtml-in previous-batches mapping>   
-             <a href="<dtml-var save_url><dtml-var sequence-query>
-                      start=<dtml-var "_['batch-start-index']+1">">
-                      <dtml-var sequence-number></a>&nbsp;
-             <dtml-call "REQUEST.set('actual_page',_['sequence-number']+1)">     
-           </dtml-in>
-           <b><dtml-var "_['actual_page']"></b>  
-         </dtml-if>
-         <dtml-if sequence-end>
-           <dtml-in next-batches mapping>&nbsp;
-              <a href="<dtml-var save_url><dtml-var sequence-query>
-                     start=<dtml-var "_['batch-start-index']+1">">
-                     <dtml-var "_['sequence-number']+_['actual_page']"></a>
-            </dtml-in>
-         </dtml-if>
-        </dtml-in>
-
-    Inside each *if* tag there is another *if* tag that check for the
-    special variables 'previous-sequence' and 'next-sequence'. The
-    variables are true when the current batch has previous or further
-    batches respectively. In other words 'previous-sequence' is true
-    for all batches except the first, and 'next-sequence' is true for
-    all batches except the last. So the DTML tests to see if there are
-    additional batches available, and if so it draws navigation links.
-
-      % Anonymous User - Apr. 28, 2002 7:26 pm:
-       These nested if's dont work if you use ...
-       <dtml-if sequence-start>
-                   <dtml-if next-sequence>
-       or 
-       <dtml-if sequence-end>
-                   <dtml-if previous-sequence>
-       Therefore the above paragraph is a bad reccomendation and is very limiting in capability.
-
-    The batch navigation consists of links back to the document with a
-    *query_start* variable set which indicates where the *in* tag should
-    start when displaying the batch. To better get a feel for how this
-    works, click the previous and next links a few times and watch how
-    the URLs for the navigation links change.
-
-    Finally some statistics about the previous and next batches are
-    displayed using the 'next-sequence-size' and
-    'previous-sequence-size' special variables.  All of this ends up
-    generating the following HTML code::
-
-      <html><head><title>Zope</title></head><body bgcolor="#FFFFFF">
-
-        <h1>These words are displayed at the top of a batch:</h1>
-        <ul>
-          <li>Iteration number: 0</li>
-          <li>Iteration number: 1</li>
-          <li>Iteration number: 2</li>
-          <li>Iteration number: 3</li>
-          <li>Iteration number: 4</li>
-          <li>Iteration number: 5</li>
-          <li>Iteration number: 6</li>
-          <li>Iteration number: 7</li>
-          <li>Iteration number: 8</li>
-          <li>Iteration number: 9</li>
-        </ul>
-        <h4>These words are displayed at the bottom of a batch.</h4>
-
-           <a href="http://pdx:8090/batch?query_start=11">
-             (Next 10 results)
-           </a>
-
-      </body></html>
-
-    Batch processing can be complex. A good way to work with batches
-    is to use the Searchable Interface object to create a batching
-    search report for you. You can then modify the DTML to fit your
-    needs.  This is explained more in Chapter 11, "Searching and
-    Categorizing Content".
-
-      % Anonymous User - Apr. 28, 2002 7:22 pm:
-       This reference to Chapter 11 is misleading, because it never gets into "batch navigation". The question on
-       how to present standard search results that include Page numbers is never answered and never again addressed.
-       Example:  
-       Search Results
-       Page: 1 2 3 4 5    Next 10 Results>
-
-  Exception Handling Tags
-
-    Zope has extensive exception handling facilities. You can get
-    access to these facilities with the *raise* and *try* tags. For more
-    information on exceptions and how they are raised and handled see
-    a book on Python or you can read the online "Python
-    Tutorial":http://www.python.org/doc/current/tut/node10.html.
-
-    The *Raise* Tag
-
-      You can raise exceptions with the *raise* tag. One reason to raise
-      exceptions is to signal an error. For example you could check
-      for a problem with the *if* tag, and in case there was something
-      wrong you could report the error with the *raise* tag.
-
-      The *raise* tag has a type attribute for specifying an error type.
-      The error type is a short descriptive name for the error. In
-      addition, there are some standard error types, like
-      *Unauthorized* and *Redirect* that are returned as HTTP
-      errors. *Unauthorized* errors cause a log-in prompt to be
-      displayed on the user's browser. You can raise HTTP errors to
-      make Zope send an HTTP error. For example::
-
-        <dtml-raise type="404">Not Found</dtml-raise>
-
-      This raises an HTTP 404 (Not Found) error. Zope responds by
-      sending the HTTP 404 error back to the client's browser.
-
-      The *raise* tag is a block tag. The block enclosed by the
-      *raise* tag is rendered to create an error message. If the
-      rendered text contains any HTML markup, then Zope will display
-      the text as an error message on the browser, otherwise a generic
-      error message is displayed.
-
-      Here is a *raise* tag example::
-
-        <dtml-if expr="balance >= debit_amount">
-
-          <dtml-call expr="debitAccount(account, debit_amount)">
-
-          <p><dtml-var debit_amount> has been deducted from your
-          account <dtml-var account>.</p>
-
-        <dtml-else>
-
-          <dtml-raise type="Insufficient funds">
-
-            <p>There is not enough money in account <dtml-account> 
-            to cover the requested debit amount.</p>
-
-          </dtml-raise>
-
-        </dtml-if>
-
-      There is an important side effect to raising an exception,
-      exceptions cause the current transaction to be rolled back. This
-      means any changes made by a web request to be ignored. So in
-      addition to reporting errors, exceptions allow you to back out
-      changes if a problem crops up.
-
-        % Anonymous User - Sep. 24, 2002 5:50 pm:
-         /to be/are/
-         /back out/back out of/ # not sure
-
-    The *Try* Tag
-
-      If an exception is raised either manually with the *raise* tag, or
-      as the result of some error that Zope encounters, you can catch
-      it with the *try* tag.
-
-      Exceptions are unexpected errors that Zope encounters during the
-      execution of a DTML document or method. Once an exception is
-      detected, the normal execution of the DTML stops. Consider the
-      following example::
-
-        Cost per unit: <dtml-var
-                             expr="_.float(total_cost/total_units)" 
-                             fmt=dollars-and-cents>
-
-      This DTML works fine if *total_units* is not zero. However, if
-      *total_units* is zero, a *ZeroDivisionError* exception is raised
-      indicating an illegal operation. So rather than rendering the
-      DTML, an error message will be returned.
-
-      You can use the *try* tag to handle these kind of problems. With
-      the *try* tag you can anticipate and handle errors yourself,
-      rather than getting a Zope error message whenever an exception
-      occurs.
-
-      The *try* tag has two functions. First, if an exception is raised,
-      the *try* tag gains control of execution and handles the exception
-      appropriately, and thus avoids returning a Zope error
-      message. Second, the *try* tag allows the rendering of any
-      subsequent DTML to continue.
-
-      Within the *try* tag are one or more *except* tags that identify and
-      handle different exceptions. When an exception is raised, each
-      *except* tag is checked in turn to see if it matches the
-      exception's type. The first *except* tag to match handles the
-      exception. If no exceptions are given in an *except* tag, then the
-      *except* tag will match all exceptions.
-
-      Here's how to use the *try* tag to avoid errors that could occur
-      in the last example::
-
-        <dtml-try>
-
-          Cost per unit: <dtml-var 
-                               expr="_.float(total_cost/total_units)"
-                               fmt="dollars-and-cents">
-
-        <dtml-except ZeroDivisionError> 
-
-          Cost per unit: N/A 
-
-        </dtml-try> 
-
-        % Saman - Nov. 17, 2002 8:39 am:
-         dont you need to close the except tag: <dtml-except  since you refer to it as a block???
-
-      If a *ZeroDivisionError* is raised, control goes to the *except*
-      tag, and "Cost per unit: N/A" is rendered. Once the except tag
-      block finishes, execution of DTML continues after the *try* block.
-
-      DTML's *except* tags work with Python's class-based
-      exceptions. In addition to matching exceptions by name, the
-      except tag will match any subclass of the named exception. For
-      example, if *ArithmeticError* is named in a *except* tag, the
-      tag can handle all *ArithmeticError* subclasses including,
-      *ZeroDivisionError*. See a Python reference such as the online
-      "Python Library
-      Reference":http://www.python.org/doc/current/lib/module-exceptions.html
-      for a list of Python exceptions and their subclasses.  An
-      *except* tag can catch multiple exceptions by listing them all
-      in the same tag.
-
-        % Anonymous User - Nov. 23, 2002 11:43 am:
-         You gave a link to the python exceptions, but what's about the Zope's Built-in Exceptions? (ie: The one that
-         comes with the authorized errors)
-
-      Inside the body of an *except* tag you can access information
-      about the handled exception through several special
-      variables.
-
-        *error_type* -- The type of the handled exception. 
-
-        *error_value* --  The value of the handled exception.
-
-        *error_tb* --  The traceback of the handled exception.
-
-      You can use these variables to provide error messages to users
-      or to take different actions such as sending email to the
-      webmaster or logging errors depending on the type of error.
-
-      The *Try* Tag Optional *Else* Block
-
-        The *try* tag has an optional *else* block that is rendered if an
-        exception didn't occur.  Here's an example of how to use the
-        *else* tag within the try tag::
-
-          <dtml-try> 
-
-            <dtml-call feedAlligators>
-
-          <dtml-except NotEnoughFood WrongKindOfFood>
-
-            <p>Make sure you have enough alligator food first.</p>
-
-          <dtml-except NotHungry> 
-
-            <p>The alligators aren't hungry yet.</p>
-
-          <dtml-except> 
-
-            <p>There was some problem trying to feed the alligators.<p>
-            <p>Error type: <dtml-var error_type></p>
-            <p>Error value: <dtml-var error_value></p>
-
-          <dtml-else> 
-
-            <p>The alligator were successfully fed.</p>
-
-          </dtml-try> 
-
-        The first *except* block to match the type of error raised is
-        rendered. If an *except* block has no name, then it matches all
-        raised errors. The optional *else* block is rendered when no
-        exception occurs in the *try* block. Exceptions in the *else*
-        block are not handled by the preceding *except* blocks.
-
-      The *Try* Tag Optional *Finally* Block
-
-        You can also use the *try* tag in a slightly different
-        way. Instead of handling exceptions, the *try* tag can be used
-        not to trap exceptions, but to clean up after them.
-
-        The *finally* tag inside the *try* tag specifies a cleanup block
-        to be rendered even when an exception occurs.
-
-        The *finally* block is only useful if you need to clean up
-        something that will not be cleaned up by the transaction abort
-        code. The *finally* block will always be called, whether there
-        is an exception or not and whether a *return* tag is used or
-        not. If you use a *return* tag in the try block, any output of
-        the *finally* block is discarded. Here's an example of how you
-        might use the *finally* tag::
-
-          <dtml-call acquireLock>  
-          <dtml-try>
-              <dtml-call useLockedResource>
-          <dtml-finally>
-              <!-- this always gets done even if an exception is raised -->
-              <dtml-call releaseLock>
-          </dtml-try>
-
-        In this example you first acquire a lock on a resource, then
-        try to perform some action on the locked resource. If an
-        exception is raised, you don't handle it, but you make sure to
-        release the lock before passing control off to an exception
-        handler. If all goes well and no exception is raised, you
-        still release the lock at the end of the *try* block by
-        executing the *finally* block.
-
-        The *try/finally* form of the *try* tag is seldom used in
-        Zope. This kind of complex programming control is often better
-        done in Python or Perl.
-
-          % Anonymous User - July 4, 2002 5:10 am:
-           Could you be clear please: does the use of try/except/finally *cancel* the rollback effect mentioned above,
-           where the changes made by a request that generates exceptions are cancelled?
-           For example: if my page executes an SQL query, but then further down, throws an exception of some sort, my
-           query might be rolled back. If I encase the exception-generating code in a try block, and it throws an
-           exception, does this mean that my SQL query will *not* be rolled back?
-
-  Conclusion
-
-    DTML provides some very powerful functionality for designing web
-    applications.  In this chapter, we looked at the more advanced
-    DTML tags and some of their options.  A more complete reference
-    can be found in Appendix A.
-
-    The next chapter teaches you how to become a Page Template
-    wizard. While DTML is a powerful tool, Page Templates provide a
-    more elegant solution to HTML generation.



More information about the Checkins mailing list