[Zope-dev] More comments on ZPatterns

Phillip J. Eby pje@telecommunity.com
Mon, 10 Jul 2000 12:00:44 -0500


At 04:40 PM 7/9/00 -0500, Steve Spicklemire wrote:
>
>Wow.. alright. I think I need "ZPatterns for Dummies" or maybe there
>needs to be a disclaimer "ZPatterns are NOT for Dummies." ;-)
>
>I've pretty much given up on Sheets for now. Nothing I've tried
>has actually worked. I thought maybe I needed to switch to 2.2,
>but then all the code that *was working* stopped working... 

It's possible that something *is* broken.  Ty and I are not yet using
ZPatterns-based propertysheets for production work, and anything we don't
use yet for production work isn't as thoroughly tested.


>(e.g., I would get permission errors when I tried things
>like "ni=newItem('foo')"... "ni.propertysheets.get('Basic')"
>'get' is disallowed... in 2.2 somehow.. "Basic" is a propertysheet
>defined in the ZClass for my instances.)

This appears to be a Zope bug; OFS.PropertySheets.PropertySheets does not
define roles/permissions for the "get" method.  This should probably be put
in the Collector.


>Maybe someone could just say, in a plain, step-by-stepish sort of way,
>how to add/delete/etc sheet providers for a pure ZClass based object
>at any time at all. (I would be happy to start over, if I felt I knew
>what I was doing!)

I'm not sure what you're asking for here; I thought you previously quoted
from an explanation of how to do that.



>Anyway... I went back to 2.1.6 and finally got triggers working.  I
>thought I would share a minor success and ask the ZPatterns gurus if
>this is 'right' so that I might not go too far down the 'wrong' road!
>
>I defined a Generic Trigger in my defaultRack's Data Plugins
>that managed the same attributes that I have defined in
>my "Generic Attribute Provider" in the same Rack, for the 
>same instances. The only persistan attribute is the id of 
>the object, which turns out to be the primary key of a single table
>in MySQL that I use for my SQL based attributes. My Generic Trigger
>has 

You don't need "id" to be persistent, if all it's for is to map to the SQL
database.  Just make sure your GAP returns NOT_FOUND (if the record doesn't
exist) for some attribute you can then use as your "load attribute" on the
Storage Settings tab of the Rack.  (If you were keeping "id" persistent so
that you could use the getPersistentItemIds() method, note that you can use
an SQL method for that purpose instead.)


>(I had to make the last attribute unconditionally set
>since otherwise the extra comma created an SQL syntax
>error if it was excluded... could sqlgroup fix this?)

No, but you could use the CHANGED_ATTRS() function instead and use an "in"
loop.  CHANGED_ATTRS() returns the list of attribute names which were set
or deleted during the transaction.  You could then use:

<dtml-unless sequence-end>,</dtml-unless>

to add the comma between SET clauses.  You would still, of course have to
do conditional code for the types of your variables.


>My only problem was that I couldn't trigger the trigger!
>In the past I've always called manage_changeProperties to
>adjust an ZClass's properties. But since only the ID is
>stored persistently... that doesn't make any sense. Instead
>I ended up creating an external method:

manage_changeProperties is an ideal way to change the attributes, actually.
 The only problem is that a "common instance property sheet" won't work, as
Ty and I found out last week when we tried to build a production app using
GAP's and GenericTriggers.

The problem is that when a default attribute is set on the ZClass,
__getattr__ doesn't get called on the instances for that attribute, so you
can never get the value from your database.  You can change the properties
all you want, and your database will be updated, but you'll still never see
the data in Zope.

So I've added a new kind of property sheet, a "DataSkin Property Sheet",
which sets default attributes as "class_default_for_X" names in the ZClass.
 DataSkins already support defaulting to class_default_for_X if an
attribute provider doesn't come up with something, so it works out quite
well.  Trick is, I haven't released this new feature yet; I only added it
Thursday evening and there are some other unfinished bits as yet.

The approach you took, with external methods, is the approach Ty took as a
workaround until I got DataSkin Property Sheets together, and is a
reasonable way to deal with it for now.


>That called the external method to actually trigger the "Generic Trigger".
>It did work... I can't help but wonder if I missed some obvious
>and much simpler way to accomplish this! 

You didn't miss it; this is a defect in ZPatterns which I discovered when
Ty began building a production app similar to yours in what it uses in
ZPatterns.  As with many things in ZPatterns, it's not so much that it's
inherently complicated as it is unfinished, undocumented, and untested.