Write to Byte
Editorial Calendar

Categories
Previous Editions
Columns
Features
Audio



Resources
BYTE Forums
WebTools
Java Resources
Downloads
History Of Byte

BYTE Humor
Ian Shoales' Page

Print Archives
By Issue   By Topic

About Us
Byte Editorial Staff
Sales Staff
Privacy Policy




Search DDJ

DDJ Links

ARTICLES
SOURCE CODE
DEVSEARCHER
TECHNETCAST
BOOK REVIEWS
OP-EDS
COMMUNITY UNIVERSITY
MICROPROCESSOR RESOURCES
MACINTOSH DEVELOPER
HISTORY OF COMPUTING
MAILINGLISTS




Tangled in the Threads

BYTE Magazine > Tangled in the Threads > 2001 > June

Examples Of Acquisition

(Nature vs. Nurture:  Page 2 of 3 )

In This Article
Nature vs. Nurture

Examples Of Acquisition

A Glimpse Of The Deep Magic
Some simple examples of acquisition can been seen in an application I wrote to help a team of editors collaborate on the production of a magazine. The application uses ZODB (Zope's object database) to store a tree of contents that looks like this:

2001-08
	article_1
		draft_1
		draft_2
		image_A
		image_B
	article_2
2001-07
	article_1
	article_2

The bolded items are Folders. There's a Folder for each month's issue and, within that, a Folder for each article in the issue, containing one or more Files or Images. The user interface of the application is based on Zope's tree tag. Here's a simplified view of the DTML logic that expresses the containment hierarchy in HTML:

<dtml-tree branches_expr="objectValues(['Folder', 
'File','Image'])" reverse sort=id>

<dtml-if "meta_type=='Folder'">

<dtml-if "isIssueFolder(_['title_or_id'])==0"> [<a href="<dtml-var tree-item-url> /addFile">add file</a>] [<a href="<dtml-var tree-item-url> /addImage">add image</a>] </dtml-if>

</dtml-if>

</dtml-tree>

The isIssueFolder() method is called once for each Folder in the containment hierarchy, and passed an argument that picks out the title_or_id property of the current object. The convention here is that when that property doesn't match the regular expression 20\d\d\-\d\d (which is the test implemented by isIssueFolder), the Folder represents an article. In these cases, the DTML logic decorates the emitted HTML node with links used to add files, or images, to that folder, like so:

2001-08
	article_1 [add file] [add image]
		draft_1
		draft_2
		image_A
		image_B
	article_2 [add file] [add image]
2001-07
	article_1 [add file] [add image]
	article_2 [add file] [add image]

The addresses of these links are formed by means of the expression <dtml-var tree-item-url>, which yields URLs like these:

2001-08/article_1/addFile

2001-07/article_2/addImage

addFile and addImage are DTML Documents that present HTML forms used to upload files or images. Here, for example, is the preamble to addFile:

<p>Add a file to 
<dtml-var "PARENTS[1].title_or_id()">/<
dtml-var "PARENTS[0].title_or_id()">
<FORM ACTION="addFileToArticleFolder" 
METHOD="POST" ENCTYPE="multipart/form-data">

When you call the URL 2001-08/article_1/addFile, PARENTS[0] is the Folder article_1 and PARENTS[1] is the Folder 2001-08. But this Folder hierarchy does not, in fact, contain the DTML Document addFile. Let's expand the scope to show more of the Folder hierarchy:

Production
	addFile
	addImage
	2001-08
		article_1
			draft_1
			draft_2
			image_A
			image_B
		article_2
2001-07
	article_1
	article_2

So, while addFile is contained within Production, it is acquired by all of Production's subfolders. When called from such contexts, the PARENTS are acquired in a context-sensitive way.

The External Method addFileToArticleFolder, which is wired to the ACTION attribute of the form, exhibits similar context sensitivity. Here's the essence of that method:

def addFileToArticleFolder(self,REQUEST):
self.manage_addFile
	(REQUEST.file.filename,REQUEST.file.read(),'')
return REQUEST.RESPONSE.redirect(REQUEST['BASE2'])

When this method is called from a context like 2001-08/article_1/addFile, the self object is the Folder article_1, and so the file is added to that Folder.


 Page 2 of 3 

BYTE Forums
Want to talk about this article?

 Tangled in the Threads
 


CMPnet


 

 

www4