[Zope] Tree Tag Options

Amos Latteier amos@aracnet.com
Tue, 02 Feb 1999 13:01:32 -0800


At 11:29 AM 2/2/99 -0800, Michael Bernstein wrote:
>I am looking for a list of available methods for the 'tree' tag,
>particularly those for the branches attribute.
>
>The DTML guide lists two: 'tpValues' as the default, 'and objectValues'
>in the example.
>
>Are there any others?

Sure, but let me take the long route to answering this question.

The tree tag is a generic device to display hierarchical data. You can use
the tree tag to display arbitrary Python objects. Folders and Documents are
only two choices of things to display.

The DTML Guide gives a good explanation of the tree tag:

http://www.zope.org/Documentation/Guides/DTML/

Here's the URL of the relevant section of the DTML guide:

http://www.zope.org/Documentation/Guides/DTML/DTML-HTML/DTML.html#pgfId-1011
006

As it says, the branches attribute can be used to call different methods to
determine the object's sub-objects. The default method for this is 'tpValues'.

To work with the tree tag, the Python objects must adhere to the tree
protocol. From lib/python/TreeDisplay/TreeItem.py here's the basic tree
protocol:

class TreeProtocol:

    def tpValues(self):
        """Return the immediate
        subobjects of the current object that should be
        shown in the tree.
        """

    def tpId(self):
        """Return a value to be used as an id in tree state."""
        

    def tpURL(self):
        """Return string to be used as URL relative to parent.
        The tree tag accumulates the tpURL of objects as it
        traverses the tree. At any given point during dtml
        rendering within the tree tag, you can use::
        <!--#var tree-item-url-->
        to get the url up to the point of the current object
        being rendered.
        """

Since we can specify alternates to 'tpValues' in the tree tag, your Python
objects only really need to support the 'tpId' and 'tpURL' methods, you can
name your sub-object generating method something besides 'tpValues', if you
want.

So to get back to your original question, depending on what sort of objects
you are displaying with the tree tag, you can specify any appropriate
method of the objects as the 'branches' method, so long as it returns a
list of sub-objects. In the case of folderish Zope objects, 'objectValues'
is probably the most appropriate method, since it returns a list of Zope
sub-objects. The 'tpValues' method of Zope Folders return a list of
sub-Folders, which is used to generate the familiar tree in the left frame
of the management screen.

However, there is nothing stopping you from defining new methods with for
example External Methods, to return your own choice of sub-objects. For
example, here's an External Method that just returns a Folder's
sub-Documents and sub-Folders:

def subFoldersAndDocuments(self):
    "return my sub-folders and sub-documents"
    return self.objectValues(['Folder','Document'])

Say you call this External Method 'myObjectValues' and define it at the top
of your Zope object hierarchy. Now all Zope objects will acquire it, and
you can use it as a branches method:

<!--#tree branches=myObjectValues-->
<!--#var id-->
<!--#/tree-->

This will display the folders and documents in your object hierarchy as a
tree.

But the sky's the limit! It really gets interesting when Documents get
properties (coming very soon!). Then you might want to mark public
documents with a property, say 'Visible', and use a slightly different
branches method, for example:

def visibleObjects(self):
    "return my visible sub-documents and folders"
    result=[]
    for object in self.objectValues(['Document','Folder']):
        if hasattr(object,'Visible') and object.Visible:
            result.append(object)
    return result

As you can see (I hope ;-) this method returns a filtered list of
sub-documents and sub-folders.

I hope this helps. The tree tag can do some pretty powerful stuff, if you
work with it.

-Amos