[albatross-users] <al-tree> Initialisation

Dave Cole djc at object-craft.com.au
Sat Dec 21 23:21:56 EST 2002


>>>>> "John" == John Totten <john at totten.com> writes:

John> <al-tree> assumes that the user starts at the root node and
John> builds a tree as they drill down.  Is it possible to open a tree
John> with n.deapth(num) already loaded into the session variables
John> programmatically? This would allow a child in its context to be
John> displayed to the user in response to their enquiry instead of a
John> less than helpful root node.  The other parts of the tree would
John> still be automaticallly built by the user if they branch out
John> from higher nodes.

The <al-tree> tag is deliberately fairly dumb in order to avoid
placing limitations on the kind of data that you might want to format
using the tag.  Having said that we have been thinking that there
should be more support in the tag for the kind of requirement you have
mentioned.

Andrew, Ben, and I have been talking about the interface that we
should add to the LazyTreeIterator for the next release.  Nothing much
has been agreed upon yet.

One of the biggest limiting factors is that Albatross assumes very
little about the tree structured data.

For a non-lazy loaded tree Albatross only looks for a children
attribute in each node.  If the children attribute is present then the
node is a parent node and the attribute is assumed to be a sequence of
child nodes.  If the children attribute is not present the node is a
leaf node.

For lazy loaded trees Albatross requires two methods be implemented.

  load_children(ctx) is called by Albatross when it wants your program
  to load the children of a particular node.

  albatross_alias() is called to obtain a unique string which
  identifies the node.  This string is used in the LazyTreeIterator to
  record which nodes are selected and which are open.

When the LazyTreeIterator loads the children of a node (via
load_children()) it sets the children_loaded attribute of that node.

As you have mentioned "drill down" I assume you are talking about a
lazy loaded tree (non-lazy loaded trees are rendered fully expanded).

In our applications where we have used lazy loaded trees we have
written application code to partially open the tree and preselect
nodes.  For example, if you wanted to be able to remember the state of
the tree and restore it next time a user connected to the application,
you would probably have something like this:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
from myapp import utils

def page_process(ctx):
    if ctx.req_equals(...):
        utils.restore_tree(ctx)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Then in myapp.utils you would have something like this:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
from albatross import LazyTreeIterator

def restore_tree(ctx):
    # Create the tree root and fetch the previous state of the tree.
    ctx.locals.root = create_tree_root(ctx)
    open_aliases, selected_alias = previous_tree_state(ctx)

    # Create the tree iterator used in the HTML template.  We must
    # also place the iterator into the session because Albatross will
    # assume this has been done when it notices that the iterator
    # already exists.
    ctx.locals.hn = LazyTreeIterator()
    ctx.add_session_vars('hn')

    # Pre-load the children of all open tree nodes.
    walk_children(ctx, ctx.locals.root, open_aliases)

    # Place the previous state of the tree into the iterator so the
    # display will be correct.
    ctx.locals.hn.set_open_aliases(open_aliases)
    ctx.locals.hn.set_selected_aliases([selected_alias])

def walk_children(ctx, node, open_aliases):
    node.load_children(ctx)
    node.children_loaded = 1
    for child in node.children:
        if child.albatross_alias() in open_aliases:
            walk_children(ctx, child, open_aliases)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Note that the above only uses node aliases.

If you wanted to do something more sophisticated in your application
which used attributes which were specific to your application, then
your walk_children() would need to know how to locate nodes via those
attributes.  It would build up a list of node aliases which could then
be passed to the set_selected_aliases() method of the
LazyTreeIterator.

Hope this has not further confused you.

- Dave

-- 
http://www.object-craft.com.au




More information about the Albatross-users mailing list