[TransWarp] More PWT Ideas (usage, not terminology!)

Phillip J. Eby pje at telecommunity.com
Wed Jul 23 08:59:58 EDT 2003

At 08:18 AM 7/23/03 +0200, Roché Compaan wrote:
>* Phillip J. Eby <pje at telecommunity.com> [2003-07-23 02:30]:
> > These are probably only the barest beginning of what's possible with a
> > little imagination and the DOMlet framework.  I mention them here so 
> that I
> > don't lose/forget the ideas, but also in the hopes of inspiring others to
> > take a closer look at the machinery and to dream big dreams of their own,
> > or maybe even get started on some of the ideas I've mentioned.  :)
>They all sound good, actually mouth watering. Other things I can imagine
>that can become DOMlets are form widgets.

Yep.  I just don't tout that one because that's pretty much the first thing 
everybody builds with their web widget toolkits, and I didn't want people 
going, "yeah but so-and-so toolkit already does that."  :)  Also, 
ironically enough, I'm not yet sure how I want form widgets to work, even 
though I had some reasonably good ideas about the other things I mentioned.

>I don't know if you are
>familiar with Formulator at all

Only the concept.

>but the basic idea is that you build a
>form in python from a set of field classes that each have a widget
>associated with it. Formulator has widgets like TextWidget,
>PasswordWidget, FileWidget, DateTimeWidget, LinesWidget etc. These might
>be good contenders for DOMlets.

Definitely.  I assume that to be really useful, these widgets need to be 
able to be bound both to an object attribute, and to a value in the 
request, so that, for example, if I post the form and there are errors in 
my input, it can be redisplayed without losing the work I've 
typed/selected/checked/whatever so far.

>I am not sure if this fits in with what
>DOMlets are supposed to do - I must get my hands dirty with the code
>first. Have you checked in any of code for DOMlets yet?

Yes.  See 'peak.web.templates'.  I haven't done the renaming yet, so look 
for classes like TemplateLiteral (for non-element nodes) and 
TemplateElement as the base DOMlet classes.  TemplateDocument is a 
TemplateElement that can be parsed from an XML stream, and that has no 
open/close tags.  TemplateReplacement is a base for DOMlets that don't 
render their original contents (like the "list" and "text" 
DOMlets).  TemplateText and TemplateList are the initial implementations of 
the "text" and "list" DOMlets.  The whole thing, including a custom 
expat-driven parser, is about 600 lines of Python.

There will be some renaming and refactoring done soon, maybe today.  I'd 
like to simplify the 'renderTo' signature if I can do so without 
introducing other kinds of overhead.  There could also probably be better 
error handling.  And of course, the code is still using model/view/pattern, 
rather than domlet/define.

> > Probably, those concerns are derived from the fact that we don't currently
> > have any application-specific location adapters, so everything is generic
> > and the URL paths are based on underlying object attributes.  For example,
> > without application-specific location adapters, there's currently no 
> way to
> > derive a *canonical* URL for an object.
>Say more about location adapters. Would they not be very application

Yes, that's what I've been thinking.  I'm beginning to realize that the 
real issue is that I intended location adapters to also take the place of 
Zope 3's security proxies.  That is, location adapters do the security 
checking for the objects they adapt.  However, this doesn't really work 
that well because templates need to be able to refer to the location *and* 
the underlying object, with security in place for both.

In Zope 3, both the location adapter ("view" in Zope 3) and the domain 
object ("content object" in Z3) are wrapped in security proxies.  I'm not 
fond of this approach because it breaks 'isinstance()' (although we try not 
to use that for anything any more) and makes it pretty near impossible to 
implement sensibly-protected bidirectional relationships.  OTOH, using 
Zope's proxies would allow us to take permission checking out of the 
explicit code path for everything but filtering of sequences and 
mappings.  (That is, we would still need to check whether a user is allowed 
to know an item *exists*.)

The downside of course is another external dependency, although we are 
already depending on Zope 3 to be installed to do web apps anyway.  I 
suppose we could bundle zope.proxy and zope.security, if we wanted to be 
able to test our use of them without Zope installed.  Another downside to 
the proxies may be performance, in that every access is checked.  OTOH, 
when using templates, we are checking every access now.  If we use a 
checker-per-object proxy strategy, we could actually cache the permission 
lookups, so repeated access to the same object wouldn't need to do full 
permission checking.

On the other other hand...  :)  We could make the current location adapter 
bases cache this too, at least on a per-name basis, and maybe even make it 
so you get a security.Attempt object back from interaction.allows(), so you 
can cache the result by permission rather than just by name.  And, maybe we 
need to distinguish between objects' guards and their location 
adapters.  Now that there's a LocationPath object used for all name 
traversals anyway, perhaps we could move security checking into it.

Hmmm.  I think maybe the real problem with the current Location machinery 
is that I've effectively also overloaded it as an 
"application-specificness" protocol.  That is, 'locationProtocol' is 
expected to be application-specific, yet the actual protocol being used is 
really application neutral.

To put it another way, we should probably adapt components first to be "web 
application" or "presentation" components, and then adapt them to a 
location protocol second.  The presentation aspect would deal with putting 
a UI atop the underlying component.  The location aspect would deal with 
traversal and security checks.  (This would be a generic, rather than 
context-sensitive interface.)  While it certainly would be possible to 
implement a presentation adapter that also implemented the traversal 
interface, it would not be necessary.

The other thing that is probably needed, is to have presentation aspects be 
"decorators" rather than "adapters".  That is, we don't want to have to 
treat an object and its presentation differently when we access it in a 
template.  If we are using a contact object in a template, we want *both* 
its presentation and domain attributes/methods available, or else we will 
be continually using an extra path name to get at one or the other kind of 
attribute.  Currently, PEAK has no generic decorator type for this sort of 
thing.  However, we could create a presentation adapter base that includes 
both traversal support and can look up the name that's requested against 
both itself and the thing it's adapting.  That would suffice for templating 

Scripting methods in a presentation adapter is still a security risk at 
this point.  That is, if you don't check security when you access the 
underlying object, you might mistakenly grant access to something.  The 
only ways I see to deal with this are to use proxies, or to be careful.

At any rate, it's clearer to me now that there are *three* different things 
I'm trying to do with location adapters at present, and they need to be 
considered separately, even if we end up cramming them together 
again.  They are: access checking, traversing, and "decorating" an object 
with application-specific presentation/UI capabilities.

>I imagine that my PEAK web app will have rather shallow
>hierarchies in the form: /<DataManager>/<object id>. But I can also
>imagine wanting to make the URLs for some objects relative to other
>objects, not their DataManagers eg.:
>     /Customers/Customer_1/Contact_1.
>Is this what location adapters must provide or am I missing the point?

This is actually part of the question that's open in my mind.  Relative 
paths are easy for the current location adapters, absolute paths are 
not.  So if Contact_1 in your example *should* be an absolute URL  (e.g. 
/DM/Contact54768), the current machinery has no way to establish such a 
thing, for purposes of creating a link href.

More information about the PEAK mailing list