[Zope-Checkins] CVS: Releases/Zope/lib/python/Products/Sessions/help - Sessions.stx:1.3 browser-add.stx:1.4 browser-change.stx:1.3 session-add.stx:1.4 session-change.stx:1.3 sessionapi-prog.stx:1.3 session-admin.stx:NONE

Matthew T. Kromer matt@zope.com
Wed, 14 Nov 2001 17:09:04 -0500


Update of /cvs-repository/Releases/Zope/lib/python/Products/Sessions/help
In directory cvs.zope.org:/tmp/cvs-serv11360

Modified Files:
	Sessions.stx browser-add.stx browser-change.stx 
	session-add.stx session-change.stx sessionapi-prog.stx 
Removed Files:
	session-admin.stx 
Log Message:
Update session docs; merge two into one (elimininating separate
session-admin doc)


=== Releases/Zope/lib/python/Products/Sessions/help/Sessions.stx 1.2 => 1.3 ===
+Session Administration
 
   Overview
 
@@ -25,23 +25,197 @@
     To facilitate sessions on systems without ZEO, you may wish to create
     a *Temporary Folder* to store your Transient Objects.
 
-  Usage
+    The session data manager will begin automatically adding a SESSION
+    object to the REQUEST in the default configuration. 
 
-    The simplest way to use sessions is to activate the "Automatic Session"
-    feature in the Session Data Manager object.  This will cause a session
-    object to be fetched or created if necessary and stored in the 'REQUEST'
-    object under the name 'SESSION'.
+  Session Data Object Expiration
 
-    This 'SESSION' object behaves as a dictionary, so the following python
-    script would demonstrate incrementing a counter in the session::
-
-    	request = context.REQUEST
-	session = request.SESSION
-
-	counter = session.get('counter',0) + 1
-	session['counter'] = counter
-
-    For more advanced programming details, see the *Session API* documentation.
+    Session data objects expire after the period between their last
+    access and "now" exceeds the timeout value provided to the
+    transient object container which hold them.  No special action need
+    be taken to expire session data objects.![1]
+
+      ![1] See "Session Data Object Expiration Considerations" in the
+      Concepts and Caveats section below for details on session data
+      expiration.
+
+  Importing And Exporting Session Data Objects
+
+    In some circumstances, it is useful to be able to "export" all
+    the session data from a specific transient object container in order
+    to "import" it to another.  This may be necessary when migrating
+    data between containers or when upgrading the session tracking
+    implementation to a more recent version.
+
+    You can export data from a transient object container by visiting
+    its "Advanced" tab, and choosing "Export Session Data".  A file
+    will be written to the hard disk of the Zope server you're
+    talking to in the 'var' directory of the Zope instance named
+    "sessiondata.zexp".
+
+    To import exported session data, choose "Import Session Data"
+    from the Advanced tab of the transient object container you're
+    migrating to.  The "sessiondata.zexp" file containing the
+    exported session data will be read from disk and placed into the
+    transient object container.
+
+    The contents of RAM-based (internal) transient object containers
+    cannot be exported, and you may not import session data into an
+    internal transient object container.
+
+Concepts and Caveats
+
+  Session Id (Non-)Expiration
+
+    Unlike many other sessioning implementations, core session
+    tracking session tokens (ids) do not actually themselves expire.
+    They persist for as long as their conveyance mechanism allows.
+    For example, a session token will last for as long as the session
+    token cookie persists on the client, or for as long as someone
+    uses a bookmarked URL with a session token in it.  The same id
+    will be obtained by a browser id manager on every visit by that
+    client to a site - potentially indefinitely depending on which
+    conveyance mechanisms you use and your configuration for cookie
+    persistence.  It may be useful to think of a Zope browser id as
+    a "browser id" for this reason.
+
+    In lieu of exipry of browser ids, the transient object container
+    which holds session data objects implements a policy for data
+    object expiration.  If asked for a session data object related
+    to a particular browser id which has been expired by a transient
+    object container, a session data manager will a return a new
+    session data object.
+
+  Session Data Object Expiration Considerations
+
+    Because Zope has no scheduling facility, the sessioning
+    machinery depends on the continual exercising of itself to
+    expire session data objects.  If the sessioning machinery is not
+    exercised continually, it's possible that session data
+    objects will stick around longer than the time specified by
+    their transient object container timeout value.  For example:
+
+      - User A exercises application machinery that generates a
+      session data object.  It is inserted into a transient object
+      container which advertises a 20-minute timeout.
+
+      - User A "leaves" the site.
+
+      - 40 minutes go by with no visitors to the site.
+
+      - User B visits 60 minutes after User A first generated his
+      session data object, and exercises app code which hands out
+      session data objects.  *User A's session is expired at this
+      point, 40 minutes "late".*
+
+  Sessioning and Transactions
+
+    The existing transient object container implementations interact
+    with Zope's transaction system.  If a transaction is aborted,
+    the changes made to session data objects during the transaction
+    will be rolled back.
+
+  Acquisition-Wrapped Objects
+
+    The sessioning machinery unwraps acquisition-wrapped objects
+    before storing them during a session_data_object.set or
+    session_data_object.__setitem__ operation.  Practically, this
+    means you can safely pass acquisition-wrapped objects in to the
+    sessioning machinery (for example, a DTML Document obtained via
+    traversal) as values within a session data object.  The stored
+    reference will be to the bare unwrapped object. (new in 0.9)
+
+  Mutable Data Stored Within Session Data Objects
+
+    If you mutate an object stored as a value within a session data
+    object, you'll need to notify the sessioning machinery that the
+    object has changed by calling 'set' or '__setitem__' on the
+    session data object with the new object value.  For example::
+
+       session = self.session_data_manager.getSessionData()
+       foo = {}
+       foo['before'] = 1
+       session.set('foo', foo)
+
+	 # mutate the dictionary
+
+       foo['after'] = 1
+
+	 # performing session.get('foo') 10 minutes from now will likely
+       # return a dict with only 'before' within!
+
+    You'll need to treat mutable objects immutably, instead.  Here's
+    an example that makes the intent of the last example work by
+    doing so::
+
+       session = self.session_data_manager.getSessionData()
+       foo = {}
+       foo['before'] = 1
+       session.set('foo', foo)
+
+	 # mutate the dictionary
+       foo['after'] = 1
+
+	 # tickle the persistence machinery
+	 session.set('foo', foo)
+
+    An easy-to-remember rule for manipulating data objects in
+    session storage: always explicitly place an object back into
+    session storage whenever you change it.  For further reference,
+    see the "Persistent Components" chapter of the Zope Developer's
+    Guide at http://www.zope.org/Documentation/ZDG.
+
+  Session Data Object Keys
+
+    A session data object has essentially the same restrictions as a
+    Python dictionary.  Keys within a session data object must be
+    hashable (strings, tuples, and other immutable basic Python
+    types; or instances which have a __hash__ method).  This is a
+    requirement of all Python objects that are to be used as keys to
+    a dictionary.  For more information, see the associated Python
+    documentation at
+    http://www.python.org/doc/current/ref/types.html (Mappings ->
+    Dictionaries).
+
+  In-Memory Session Data Container RAM Utilization
+
+    Each session data object which is added to an "internal"
+    (RAM-based) transient object container will consume at least 2K of
+    RAM.
+
+  Mounted Database-Based Session Data Container/Internal Session
+  Data Container Caveats
+
+    Persistent objects which have references to other persistent
+    objects in the same database cannot be committed into a mounted
+    database because the ZODB does not currently handle
+    cross-database references.
+
+    "Internal" (RAM-based) transient object containers are currently
+    implemented as objects within (automatically) mounted ZODB
+    databases.  For this reason, they are equivalent in operation to
+    external transient object containers which are placed in a manually
+    mounted database.
+
+    If you use an internal transient object container or an external
+    transient object container that is accessed via a "mounted"
+    database, you cannot store persistent object instances which
+    have already been stored in the "main" database as keys or
+    values in a session data object.  If you try to do so, it is
+    likely that an 'InvalidObjectReference' exception will be raised
+    by the ZODB when the transaction involving the object attempts
+    to commit.  As a result, the transaction will fail and the
+    session data object (and other objects touched in the same
+    transaction) will fail to be committed to storage.
+
+    If your "main" ZODB database is backed by a nonundoing storage,
+    you can avoid this condition by storing session data objects in
+    an external data container instantiated within the "main" ZODB
+    database.  If this is not an option, you should ensure that
+    objects you store as values or keys in a session data object
+    held in a mounted transient object container are instantiated "from
+    scratch" (via their constructors), as opposed to being "pulled
+    out" of the main ZODB.
 
   Networking with ZEO
 
@@ -52,6 +226,62 @@
     thus any session data stored in a Temporary Folder will not be
     distributed to other ZEO clients.
 
+  Conflict Errors
+
+    This session tracking software stores all session state in
+    Zope's ZODB.  The ZODB uses an optimistic concurrency strategy
+    to maintain transactional integrity for simultaneous writes.
+    This means that if two objects in the ZODB are changed at the
+    same time by two different connections (site visitors) that a
+    "ConflictError" will be raised.  Zope retries requests that
+    raise a ConflictError at most 3 times.  If your site is
+    extremely busy, you may notice ConflictErrors in the Zope debug
+    log (or they may be printed to the console from which you run
+    Zope).  An example of one of these errors is as follows::
+
+     2001-01-16T04:26:58 INFO(0) Z2 CONFLICT Competing writes at, /getData
+     Traceback (innermost last):
+     File /zope/lib/python/ZPublisher/Publish.py, line 175, in publish
+     File /zope/lib/python/Zope/__init__.py, line 235, in commit
+     File /zope/lib/python/ZODB/Transaction.py, line 251, in commit
+     File /zope/lib/python/ZODB/Connection.py, line 268, in commit
+     ConflictError: '\000\000\000\000\000\000\002/'
+
+    Errors like this in your debug log (or console if you've not
+    redirected debug logging to a file) are normal to an extent.  If
+    your site is undergoing heavy load, you can expect to see a
+    ConflictError perhaps every 20 to 30 seconds.  The requests
+    which experience conflict errors will be retried automatically
+    by Zope, and the end user should *never* see one.  Generally,
+    session data objects attempt to provide application-level
+    conflict resolution to reduce the limitations imposed by
+    conflict errors NOTE: to take advantage of this feature, you
+    must be running Zope 2.3.1 or better, and you must be using it
+    with a storage such as FileStorage or SessionStorage which
+    supports application-level conflict resolution.
+
+Zope Versions and Sessioning
+
+    Zope Versions are not particularly useful in combination with
+    sessioning.  Particularly, if you change the properties of a
+    session data manager or browser id manager while working in a
+    Version on a "production" site, it may cause the sessioning
+    machinery to stop working for unversioned visitors to the site
+    due to the "locking" nature of versions.  To work around this
+    problem, do not lock any sessioning-related objects while in a
+    Version.  Alternately, do not use Versions.
+
+Extending The Session Tracking Product
+
+  Implementing Alternate Session Data Managers and Data Containers
+
+    Alternate session data managers and data containers (perhaps
+    using a SQL database as a persistence mechanism) may be
+    implemented if they adhere to the interfaces outlined in the
+    SessioningInterfaces.py documentation which ships with this
+    software.
+
+
   See Also
 
     - "Transient Objects":../../Transience/Help/Transience.stx
@@ -61,5 +291,3 @@
     - "Session API":SessionInterfaces.py
 
     - "Session API Programming":sessionapi-prog.stx
-
-    - "Session Administration":session-admin.stx


=== Releases/Zope/lib/python/Products/Sessions/help/browser-add.stx 1.3 => 1.4 ===
   - "Session Tracking":Sessions.stx
 
-  - "Session Administration":session-admin.stx
-


=== Releases/Zope/lib/python/Products/Sessions/help/browser-change.stx 1.2 => 1.3 ===
   - "Session Tracking":Sessions.stx
 
-  - "Session Administration":session-admin.stx


=== Releases/Zope/lib/python/Products/Sessions/help/session-add.stx 1.3 => 1.4 ===
   - "Session Tracking":Sessions.stx
 
-  - "Session Administration":session-admin.stx


=== Releases/Zope/lib/python/Products/Sessions/help/session-change.stx 1.2 => 1.3 ===
   - "Session Tracking":Sessions.stx
 
-  - "Session Administration":session-admin.stx


=== Releases/Zope/lib/python/Products/Sessions/help/sessionapi-prog.stx 1.2 => 1.3 ===
 
+
   Overview
 
-    Developers generally interact with a Session Data Manager
-    instance in order to make use of sessioning in Zope.  Methods
-    named in this section are those of session data managers unless
-    otherwise specified.
-
-    All of the methods implemented by Session Data Managers, Session
-    Id Managers and Session Data objects are fully documented in the
-    "SessioningInterfaces.py" file accompanying this software.
-    This section of the documentation will concentrate on explaining
-    common operations having to do with session-tracking and why
-    they might be important to you.
-
-  Terminology
-
-    Here's a mini-glossary of terminology used by the session
-    tracking product:
-
-      token (aka 'token value') -- the string or integer used to
-      represent a single anonymous visitor to the part of the Zope
-      site managed by a single session id manager.
-      E.g. "12083789728".
-
-      token key namespaces -- the session token key/value pair will
-      be found in one of these namespaces.  They refer to namespaces
-      codified in the Zope REQUEST object.  E.g. "cookies" or
-      "form".
-
-      token key -- the key which is looked for in the REQUEST
-      namespaces enumerated by the token key namespaces configured.
-      This references the token as its value.  E.g. "_ZopeId".
-
-      session data object -- an instance of the session data object
-      class that is found by asking a transient object container for the
-      item with a key that is a token value.
-
-  Obtaining the Token Value
-
-    You can obtain the token value associated with the current
-    request from a session data manager::
-
-      <dtml-var "sessiondatamanager.getToken()">
-
-    This snippet will print the token value to the remote browser.
-    If no token exists for the current request, a new token is
-    created implicitly and returned.
-
-    If you wish to obtain the current token value without implicitly
-    creating a new token for the current request, you can use the
-    'create' argument to the 'getToken()' method to suppress this
-    behavior::
-
-      <dtml-var "sessiondatamanager.getToken(create=0)">
-
-    This snippet will print a representation of the None value if
-    there isn't a session token associated with the current request,
-    or it will print the token value if there is one associated with
-    the current request.  Using 'create=0' is useful if you do not
-    wish to cause the sessioning machinery to attach a new session
-    token to the current request, perhaps if you do not wish a
-    session cookie to be set.
-
-    The token value *is not* the session data.  The token value
-    represents the key by which the 'getSessionData' method obtains
-    a session data object representing the visitor marked by the
-    token.  The token value is either a string or an integer and has
-    no business meaning.  In your code, you should not rely on the
-    session token composition, length, or type as a result, as it is
-    subject to change.
-
-  Determining Which Token Key Namespace Holds The Session Token
-
-    For some applications, it is advantageous to know from which
-    token key namespace (currently either 'cookies' or 'form') the
-    token has been gathered.  There are two methods of session data
-    managers which allow you to accomplish this,
-    'isTokenFromCookie()', and 'isTokenFromForm()'::
-
-      <dtml-if "sessiondatamanager.isTokenFromCookie()">
-        The token came from a cookie.
-      </dtml-if>
-
-      <dtml-if "sessiondatamanager.isTokenFromForm()">
-        The token came from a form.
-      </dtml-if>
-
-    The 'isTokenFromCookie()' method will return true if the token
-    in the current request comes from the 'REQUEST.cookies'
-    namespace.  This is true if the token was sent to the Zope
-    server as a cookie.
-
-    The 'isTokenFromForm()' method will return true if the token in
-    the current request comes from the 'REQUEST.form' namespace.
-    This is true if the token key/value pair was sent to the Zope
-    server encoded in a URL or as part of a form element.
-
-    If a token doesn't actually exist in the current request when
-    one of these methods is called, an error will be raised.
-
-    During typical operations, you shouldn't need to use these
-    methods, as you shouldn't care from which REQUEST namespace the
-    token key/value pair was obtained.  However, for highly
-    customized applications, this pair of methods may be useful.
-
-  Obtaining the Token Key/Value Pair and Embedding It Into A Form
-
-    You can obtain the "token key" from a session data manager
-    instance.  The token key is the name which is looked for in
-    token key namespaces by a session id manager.  We've already
-    determined how to obtain the token value.  It is useful to
-    obtain the token key/value pair if you wish to embed a session
-    token key/value pair as a hidden form field for use in POST
-    requests::
-
-      <html>
-      <body>
-      <form action="thenextmethod">
-      <input type=submit name="submit" value=" GO ">
-      <input type=hidden name="<dtml-var "sessiondatamanager.getTokenKey()">"
-       value="<dtml-var "sessiondatamanager.getToken()">">
-      </form>
-      </body>
-      </html>
-
-  Determining Whether A Session Token is "New"
-
-    A session token is "new" if it has been set in the current
-    request but has not yet been acknowledged by the client --
-    meaning it has not been sent back by the client in a request.
-    This is the case when a new session token is created by the
-    sessioning machinery due to a call to 'getSessionData()' or
-    similar as opposed to being received by the sessioning machinery
-    in a token key namespace.  You can use the 'isTokenNew()' method
-    of session data managers to determine whether the session is
-    new::
-
-      <dtml-if "sessiondatamanager.isTokenNew()">
-        Token is new.
-      <dtml-else>
-        Token is not new.
-      </dtml-if>
-
-    This method may be useful in cases where applications wish to
-    prevent or detect the regeneration of new tokens when the same
-    client visits repeatedly without sending back a token in the
-    request (such as may be the case when a visitor has cookies
-    "turned off" in their browser and the session id manager only
-    uses cookies).
-
-    If there is no session token associated with the current
-    request, this method will raise an error.
-
-    You shouldn't need to use this method during typical operations,
-    but it may be useful in advanced applications.
-
-  Determining Whether A Session Data Object Exists For The Token Associated
-    With This Request
-
-    If you wish to determine whether a session data object with a
-    key that is the current request's token exists in the data
-    manager's associated transient object container, you can use the
-    'hasSessionData()' method of the session data manager.  This
-    method returns true if there is session data associated with the
-    current session token::
-
-      <dtml-if "sessiondatamanager.hasSessionData()">
-         The sessiondatamanager object has session data for the token
-         associated with this request.
-      <dtml-else>
-         The sessiondatamanager object does not have session data for
-         the token associated with this request.
-      </dtml-if>
-
-    The 'hasSessionData()' method is useful in highly customized
-    applications, but is probably less useful otherwise.  It is
-    recommended that you use 'getSessionData()' instead, allowing
-    the session data manager to determine whether or not to create a
-    new data object for the current request.
-
-  Embedding A Session Token Into An HTML Link
-
-    You can embed the token key/value pair into an HTML link for use
-    during HTTP GET requests.  When a user clicks on a link with a
-    URL encoded with the session token, the token will be passed
-    back to the server in the REQUEST.form namespace.  If you wish
-    to use formvar-based session tracking, you will need to encode
-    all of your "public" HTML links this way.  You can use the
-    'encodeUrl()' method of session data managers in order to
-    perform this encoding::
-
-      <html>
-      <body>
-      <a href="<dtml-var "sessiondatamgr.encodeUrl('/amethod')">">Here</a>
-       is a link.
-      </body>
-      </html>
-
-    The above dtml snippet will encode the URL "/amethod" (the
-    target of the word "Here") with the session token key/value pair
-    appended as a query string.  You can additionally pass URLs
-    which already contain query strings to the 'encodeUrl()' method
-    successfully.
-
-  Obtaining A Session Data Object
-
-    Use the 'getSessionData()' method of session data managers to
-    obtain the session data object associated with the session token
-    in the current request::
-
-      <dtml-let data="sessiondatamanager.getSessionData()">
-        The 'data' name now refers to a new or existing session data object.
-      </dtml-let>
-
-    The 'getSessionData()' method implicitly creates a new session
-    token and data object if either does not exist in the current
-    request.  To inhibit this behavior, use the create=0 flag to the
-    'getSessionData()' method::
- 
-      <dtml-let data="sessiondatamanager.getSessionData(create=0)">
-         The 'data' name now refers to an existing session data object or
-         None if there was no existing token or session data object.
-      </dtml-let>
-
-    The 'getSessionData()' method is a highly used method.  It is
-    probably the most-commonly used method of session data managers.
- 
-  Modifying A Session Data Object
-
-    Once you've used 'getSessionData()' to obtain a session data
-    object, you can set key/value pairs of the returned session data
-    object.  These key/value pairs are where you store information
-    related to a particular anonymous visitor.  You can use the
-    'set', 'get', and 'has_key' methods of session data objects to
-    perform actions related to it::
-
-      <dtml-let data="sessiondatamanager.getSessionData()">
-        <dtml-call "data.set('foo', 'bar')">
-        <dtml-comment>Set 'foo' key to 'bar' value.</dtml-comment>
-        <dtml-var "data.get('foo')">
-        <dtml-comment>Will print 'bar'</dtml-comment>
-        <dtml-if "data.has_key('foo')">
-          This will be printed.
-        <dtml-else>
-          This will not be printed.
-        </dtml-if>
-      </dtml-let>
-
-    An essentially arbtrary set of key/value pairs can be placed
-    into a session data object.  Keys and values can be any kinds of
-    Python objects (note: see Concepts and Caveats section for
-    exceptions to this rule).  The transient object container which
-    houses the session data object determines its expiration policy.
-    Session data objects will be available across client requests
-    for as long as they are not expired.
-
-   Manually Invalidating A Session Data Object
-
-    Developers can manually invalidate a session data object.  When
-    a session data object is invalidated, it will be flushed from
-    the system, and will not be returned on subsequent requests to
-    'getSessionData()'.  The 'invalidate()' method of a session data
-    object causes this to happen::
-
-      <dtml-let data="sessiondatamanager.getSessionData()">
-        <dtml-call "data.invalidate()">
-      </dtml-let>
-
-    Subsequent calls to 'getSessionData()' in this same request will
-    return a new session data object.  Manual invalidation of
-    session data is useful in cases where you know the session data
-    is stale and you wish to flush it from the data manager.
-
-  Manually Invalidating A Session Token Cookie
-
-    Developers may manually invalidate the cookie associated with
-    the session token, if any.  To do so, they can use the
-    'flushTokenCookie()' method of a session data manager.  For
-    example::
-
-      <dtml-call "sessiondatamanager.flushTokenCookie()">
-
-    If the 'cookies' namespace isn't a valid token key namespace
-    when this call is performed, an exception will be raised.
-
-  An Example Of Using Session Data from DTML
-
-    An example of obtaining a session data object from a session
-    data manager named 'sessiondatamgr' and setting one of its
-    key-value pairs in DTML follows::
-
-      <dtml-with sessiondatamgr>
-        <dtml-let a=getSessionData>
-          Before change: <dtml-var a><br>
-          <dtml-call "a.set('zopetime', ZopeTime())">
-          <dtml-comment>
-          'zopetime' will be set to a datetime object for the current
-          session
-          </dtml-comment>
-          After change:  <dtml-var a><br>
-        </dtml-let>
-      </dtml-with>
- 
-    The first time you run this method, the "before change"
-    representation of the session data object will be that of an
-    empty dictionary, and the "after change" representation will
-    show a key/value pair of 'zopetime' associated with a DateTime
-    object.  Assuming you've configured your session id manager with
-    cookies and they're working on your browser properly, the second
-    and subsequent times you view this method, the "before change"
-    representation of the session data object will have a datetime
-    object in it that was the same as the last call's "after change"
-    representation of the same session data object.  This
-    demonstrates the very basics of session management, because it
-    demonstrates that we are able to associate an object (the
-    session data object obtained via getSessionData) with an
-    anonymous visitor between HTTP requests.
-
-    NOTE: To use this method in conjunction with formvar-based
-    sessioning, you'd need to encode a link to its URL with the
-    session token by using the session data manager's 'encodeUrl()'
-    method.
-
-    Using the 'mapping' Keyword With A Session Data Object in a 'dtml-with'
-
-      DTML has the facility to treat a session data object as a
-      mapping, making it easier to spell some of the more common
-      methods of access to session data objects.  The 'mapping'
-      keyword to dtml-with means "treat name lookups that follow
-      this section as queries to my contents by name."  For
-      example::
-
-        <dtml-let a="sm.getSessionData()">
-            <dtml-call "a.set('zopetime', ZopeTime())">
-            <dtml-comment>
-              'zopetime' will be set to a datetime object for the current
-              session... the "set" it calls is the set method of the
-              session data object.
-            </dtml-comment>
-        </dtml-let>
-
-        <dtml-with "sm.getSessionData()" mapping>
-            <dtml-var zopetime>
-            <dtml-comment>
-              'dtml-var zopetime' will print the DateTime object just set
-              because we've used the mapping keyword to map name lookups
-              into the current session data object.
-            </dtml-comment>
+    Developers generally *not* interact directly with a Session Data
+    Manager instance in order to make use of sessioning in Zope. 
+
+    All of the methods implemented by Session Data Managers, and
+    Browser Id Managers are fully documented in the
+    Session API in the "See Also" section below.
+
+  Common Programming
+
+    Generally, instead of directly interacting with the session data
+    manager, you use it's built in traversal feature to put a SESSION
+    object in the REQUEST.  This is simple, and fairly intuitive.
+    For example, in DTML you might::
+
+    	<dtml-with SESSION mapping>
+	   <dtml-var cart missing="You have no cart">
         </dtml-with>
 
-  Using Session Data From Python
+    or even more simply::
+
+        <dtml-var SESSION>
+
+    This would print the cart object in the session, or the entire SESSION
+    object.  You could set an
+    object in the session similarly to how you set it in the REQUEST::
+
+        <dtml-call expr="SESSION.set('cart','this is really more of a wagon')">
+
+    You adjust the name of the SESSION object in the management screens
+    for the session data object.  You can do more complex operations on
+    SESSION data with python scripts, e.g.::
+
+   	session = context.REQUEST.SESSION
+
+	cart = session.get('cart',())	# Get our cart or an empty list
+	cart.append(('my line item',100.00))
+
+	session['cart'] = cart		# force a save back to the session
+
+
+    In general, it is better to put manipulation of data in the session in
+    a python script than it is to do it via DTML or a page template; while
+    the latter is possible, it would be far better to simply place a session
+    management call at the top of any page which requires manipulation of
+    session data.
+
+  Tips
 
-    Here's an example of using a session data manager and session
-    data object from a set of Python external methods::
+    Keep in mind that SESSION objects (Which are really Transient Objects)
+    are basically dictionaries; if you wish to iterate through them in the
+    context of a DTML-IN expression, you should use something like::
 
-      import time
-      def setCurrentTime(self):
-          sessiondatamgr = self.sessiondatamgr
-          a = sessiondatamgr.getSessionData()
-          a.set('thetime', time.time())
-
-      def getLastTime(self):
-          sessiondatamgr = self.sessiondatamgr
-          a = sessiondatamgr.getSessionData()
-          return a.get('thetime')
+       <dtml-in expr="SESSION.items()">
+          <dtml-var sequence-key>:  <dtml-var sequence-item>
+       </dtml-in>
 
 See Also
 
@@ -372,4 +65,4 @@
 
   - "Session Tracking":Sessions.stx
 
-  - "Session Administration":session-admin.stx
+  - "Transient Object API":../../Transience/Help/TransienceInterfaces.py

=== Removed File Releases/Zope/lib/python/Products/Sessions/help/session-admin.stx ===