[Zope-PTK] PTK II
Mon, 31 Jul 2000 10:41:18 -0400
Shane Hathaway wrote:
> Basically, where PTKBase currently uses subclassing to achieve
> membership (as opposed to simple users), workflow, and discussability,
> we should instead use singleton objects that add capabilities without
> subclassing (although the initial implementation will make use of
> existing subclasses.) I think this is exactly what Phillip's vision is
> for ZPatterns.
Let me first clarify what I was saying here. In order for PTK to store
membership information such as a user's e-mail address and preferences,
PTK essentially subclasses the User class. To store workflow data as
well as discussion information, PTK subclasses many types of content
This policy does not seem ideal to me. What if we want to authenticate
users from outside the portal (as someone suggested)? Although I
recently applied some fixes that made this scenario possible, the only
way to make use of it is to either subclass PortalObject or edit the
source. What if workflow status should be derived from context or from
a joined database table? You would have to edit the source. What if
you want to change the discussion subsystem so that replies are stored
in a different way than is done now? Good luck!
Instead of relying on subclassing, we could rely on singleton "tools"
at the base of the portal. Any access to membership information goes
through the membership tool, access to workflow goes through the
workflow tool, and access to discussions goes through the discussion
tool. The default implementation of each of these tools would mimic
the current behavior.
I have chosen these tools specifically because AFAICT these are the
only things PTK achieves through subclassing. There is *not* a need
IMHO at this point to add any more functionality than this; we only
need to refine the existing model to make it scalable, customizable,
and easy to understand.
Now, I didn't tell you guys everything about this refactoring. There's
a kink. Zope's architecture currently doesn't support singletons very
well. As a matter of fact I have been trying to solve this problem
ever since I started using Zope. Maybe (I *hope*) someone can shed
The problem is simple: how do you keep the tool from being overridden?
Say we create a tool called "membership" at the base of the portal, and
set up all DTML to route membership requests through that object (i.e.
"membership.getAuthenticatedMember()") What if someone accidentally
creates an object somewhere in the portal called "membership"? What if
it's created deliberately? DTML that was looking for the membership
tool would access something else entirely. There's also the problem of
DTML keyword arguments, which override *anything*. (Consider <dtml-var
expr="logged_in(_.None, _, getPortal=securityHack)"> ... grumble ...)
There are several possible solutions, but they're all unreliable.
1) The way it's currently solved is through the getPortal() method.
Every type of content has this method. Zope's _checkId() method
doesn't allow anyone to create an object with an ID that's being used
by a method of the container, so for the most part this works. It's
difficult to create a getPortal object by accident, but not impossible
to create deliberately.
2) Watch the id's that users enter and disallow a specific set of
id's. The fix would not apply to the management interface and would
require a registration system where tools register with the portal. And
we'd still need the getPortal() method, making this solution
meaningless (since we could just call "getPortal().membership".)
3) Modify Zope's _checkId() method so that if an object by the same ID
already exists in the hierarchy and has the "__singleton__" class
attribute set, the addition is disallowed. This might solve the
problem for more than just PTK. But it would have to go through the
In addition to any of the above, it may make sense to also provide a
new checkbox for DTML methods that causes them to ignore keyword
arguments. This probably belongs in the fishbowl also.
Thank you very much for the comments so far.