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... (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.) 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!) 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 Execute: updateTypes(object=self, CHANGED=CHANGED) and setattrs: "attrib1 attrib2 ..." my 'updateTypes' method is a ZSQL method that talks to the MySQL database. It has arguments: object CHANGED and a body like: UPDATE mytable SET <dtml-if "CHANGED('attrib1')"> attrib1='<dtml-var "object.attrib1" sql_quote >', </dtml-if> <dtml-if "CHANGED('attrib2')"> attrib2='<dtml-var "object.attrib2" sql_quote >', </dtml-if> . . . attribN='<dtml-var "object.attribN" sql_quote >' WHERE id='<dtml-var "object.id" sql_quote>' (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?) 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: ---------------------------------------------------------------------- import string def setObjectAttrs(self, object, attrs): attrList = [] for k in attrs.keys(): if hasattr(object, k): setattr(object, k, attrs[k]) attrList.append(k) return "Updated attributes " + string.join(attrList, ',') + "." + " Orig attrs: " + `attrs` + "." ---------------------------------------------------------------------- to set my object attributes. I then created a method called "editInstance" like this: <dtml-var standard_html_header> <center> <br> <br> <dtml-call "setObjectAttrs( this(), REQUEST.form)"> Table Info Changed.<br> <form action="&dtml-URL2;"> <input type=submit value="OK"> </form> </center> <dtml-var standard_html_footer> ---------------------------------------------------------------------- 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! Since these are 'pure ZClass' objects.. an external method seems like the easiest way to go. For my Python based objects.. I suppose it makes more sense to use a method of the object itself, but there I want to be able to have the object handle attributes that I haven't thought of yet! ;-) Anyway.. feedback appreciated. Back to the trenches for this dummy. ;-) -steve