[ZDP] Changing contexts in Zope - part 1 -draft 1

Rik Hoekstra hoekstra@fsw.LeidenUniv.nl
Wed, 10 Nov 1999 17:57:18 +0100


Hello,

This is the first part of my proposed changing context proposal, of which I
do not yet know what it will all contain. It is meant to get progressively,
but systematically more complicated.
I'd like feedback from the list on the following questions:
- is this leading somewhere?
- did I forget some important things?

Rik
=============
Changing contexts in Zope.

The sensitivity of Zope for changing contexts is probably its
most difficult part to grasp. If you read about Zope you see the
Zen of Zope mentioned quite a few times. Chances are that this
relates to Zopes changing contexts. There are many parts that
play together to make it complicated. Actually, it is complicated
because they play together. Zope ideas and/or components involved
include object publishing, factoring out, acquisition, and Zope's
security model. They all may be scripted by DTML (or indeed python, but
we will not go into that here). Don't be confused if any or all of these
terms mean nothing to you. They do not matter for the moment.
In this chapter we'll give the subject of contexts in Zope a systematic
treatment.

1. Back to basics: object publishing is representation

When you read this, you are probably aware that Zope is about publishing
(python) objects to the web. In Zope what looks like a normal website in
reality is a webbed (HTTP-HTML) representation of a number of
objects in the Zope Object Database (ZODB).[* Actually it could
be more complicated, because there sometimes are good reasons to
mix objects with real files]. The representation is made by the
Zope component ZPublisher (for representing objects in HTML) and
ZServer (for serving them over the Web) [this division is not
entirely correct; where?]. The ZPublisher-ZServer duo is not
specific for the Web, however. At the time of writing they also
represents Zope object through FTP, WebDAV and the Medusa Monitor
Server - but Zope's modularity also makes it possible to support other
publication mechanisms. For instance, there have been discussions of
publishing Zope via a filesystem. For sake of simplicity, we'll confine
ourselves to web publishing below.

The representation works via a mapping of an python object hierarchy to
a URL. For example an object hierarchy of

rootobject.object1.subobject_a.subobject_b

is represented as:

http://www.examplesite.com/object1/subobject_a/subobject_b

In DTML, however, there is not mapping to a URL, because DTML is
internal to the Zope system, and contrary to the web needs no mapping.
Because of that there _is no representation_ involved: with DTML you
script Zope objects directly. Thus, in DTML object1.subobject_a is
called like::

<dtml-var "object1.subobject_a">

*not* like:

<dtml-var "object1/subobject_a">*.

The / separator does not separate
objects in DTML (or the underlying python language)

If you are confused by this, let's make it worse. You sometimes _do_ use
URL's in DTML. This is only in the case you use the web publishing
component of Zope and do not script the objects directly.
For example:

<dtml-call "RESPONSE.redirect('http://www.examplesite.com/object1')">

where you call the RESPONSE object to make the webbrowser [??] do
something throught the web. In other words, the URL in the RESPONSE
object does _not_ involve Zope actions directly [should I write
something here about mixing object references and URLs?? Or leave that
to the proper dtml section?]

There are many flavors of Zope objects. In the terminology of object
oriented programming all objects are instances of classes. These classes
are programmed within the Zope framework. The objects live in the Zope
framework. They can either be part of the Zope internals or be Zope
products and have all sorts of different behavior. You can even define
your own through the web. Classes are made Zopish by subclassing a few
basic Zope classes (for example: SimpleItem and Acquisition). By
subclassing objects inherit the properties of the objects it subclasses
(see a standard text on object oriented programming, preferably python
programming if you want to learn more).

Zope objects can either be simple or folderish. If they are folderish
they subclass the ObjectManager class [is this true? location in the
Zope hierarchy]. If they are simple they subclass SimpleItem. The
difference between folderish and simple items is that folderish items
may contain other items and simple classes may not.

The object stuff is essential to Zope. Make sure you understand it
before you go programming anything extensive in the framework.
[link to a more extensive section]


2. factoring and compositing objects with html

Because Zope objects are are not files. They are just that, objects.
Therefore, it is also possible to cut them up in meaningful parts. This
is not unique to Zope, because most web programming environments enable
this. What makes Zope special is the ability to separate content (HTML)
and code (DTML scripts, python external methods and Zope products).
Moreover, Zope features make it possibly to do this in a very powerful
way.

A very simple example can make this clear. You have a page site with a
recurring header and a recurring footer. Moreover, you have a page
hierarchy, and the items that are higher in the hierarchy should become
accessibly through hyperlinks. A page schematically looks like this:

=====================
      header
---------------------
links:
root | level1 | level2
---------------------
    TITLE

Lots of interesting
content

---------------------
links:
root | level1 | level2
---------------------
      footer
=====================


Many web publishing mechanism have a provision to keep a site
synchronized: they use templates. For example, there is a template in
which you may only edit the title, the links and the content. You could
do something like that in Zope as well. If you were to make a DTML
Document called template.dwt, with sections as above, you could edit
it in a web management tool like Dreamweaver, using ftp access to Zope.
In this case there would be no difference between managing a normal
website or Zope... and you would also miss many of the addition features
of Zope.

The Zope way of doing things is to take out the header, the footer, and
the links section and to make these into separate DTML Methods. This is
called factoring out common elements of a site. Thus, you end up with a
Zope containing the following objects:

standard_header => DTML Method
standard_footer => DTML Method
hierarchy_links => DTML Method
content document => DTML Document (as many as you need)

the content document looks (schematically) like this:

============================
<dtml-var standard_header>
<dtml-var hierarchy_links>
TITLE

Content

<dtml-var hierarchy_links>
<dtml-var standard_footer>
============================

[* In fact we could go further by factoring out the title and
compositing the standard_header method of a default_header, a
style_sheet method, and the hierarchy_links. For demonstration purposes
this simple example will makes things clear.]

[examples follow]

Still (except for the hierarchy links [maybe introduce these later?],
this is something that's common in web application servers and one of
the main reasons to use something like a structured framework at all. But
Zope Acquisition makes this much more interesting. Acquisition [links]
is the Zope way of changing context in a many ways. It does so by
enabling objects to dynamically get (acquire) properties. Properties may
be other objects or their properties. It is like object inheritance, but
much more dynamic. Unfortunately, it's very power also makes it hard to
grasp at first, but the only way to it is to use it. So on to an
example.

Let us assume your site's pages should look mostly the same, but its
background should be blue at the top pages, purple in the first section
and green in the second section. Like so (--- is documents, color in
brackets):

root (blue)
  ---
  ---
  ---
  section1(purple)
     ---
     ---
     ---
     subsection11
       ---
       ---
  section2(green)
    ---
    ---
    ---

The methods we mentioned above are in the root.

1. We changed the header method to include a line <body bgcolor="<dtml-var
color>">.
2. In the 'properties' tab of the folders (root, section1, section2) we
add a property 'color' with the values blue, purple and green
respectively.
3. That' it.

This is is all there is to changing the background color in the sections
like we proposed. The color remains the same in the subsection, however,
because it does not have a color property of its own and acquires it
from the folder above it.