Re: [Zope-dev] Success! Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists? Specialists?
At 09:15 PM 10/4/00 -0500, Steve Spicklemire wrote: This was also nice since in my Specialist I could do things like: dtml-call "RESPONSE.redirect(this().theRealThing.absolute_url())" After the user is finished working in my 'app area' they could get redirected back to the actual object that my Specialist was 'posing' for... I don't really recommend the above, unless it's being done by SkinScript. Otherwise, you're unnecessarily exposing an implementation attribute (theRealThing). Instead, require that your object implement a redirect() method, and define it in the class as "class_default_for_redirect". Then you can override the method in SkinScript or with a class extender (a new 0.4.3 feature). Doing it this way means your framework code will not incorporate an assumption that your whitebox specialist is always going to be wrapping someone else's objects. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] Success! Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists? Specialists?
Yes.. I see what you mean... this is a 'whitebox customization' that I used as part of the integration of my framework into the 'online catalog' system. This is not 'blackbox' code that is integral to my system In fact, I mis-spoke earlier, it's not in my specialist at all... it only appears in a method of a ZClass that I use as the 'storage class' for objects controlled by one of my specialists this is clearly whitebox territory, since this wrapper is chosen by the integrator... The first thing my docs (will) say to do.. is go through all my specialists and choose 'storage' classes for each specialist. This brings up another point If I choose 'DataSkin' as a storage class, then my code hits the security system every time a refer to any data (simple types) stored directly in the DataSkin. I can either set __allow_access_to_unprotected_subobjects=1 on each instance, or I can write accessor methods for each attribute, (yuk!, but maybe good in some ways...) or I can ask the integrator to create 'dummy' ZClass(es) even for those racks that they don't want/need to customize (which seems to 'get around' the security system.) I'm curious to know what you folks do here.. do you write accessor methods for every type stored in your DataSkins? Anyway.. thanks for the great tools! I'm having fun now. ;-) -steve "Phillip" == Phillip J Eby [EMAIL PROTECTED] writes: Phillip At 09:15 PM 10/4/00 -0500, Steve Spicklemire wrote: This was also nice since in my Specialist I could do things like: dtml-call "RESPONSE.redirect(this().theRealThing.absolute_url())" After the user is finished working in my 'app area' they could get redirected back to the actual object that my Specialist was 'posing' for... Phillip I don't really recommend the above, unless it's being Phillip done by SkinScript. Otherwise, you're unnecessarily Phillip exposing an implementation attribute (theRealThing). Phillip Instead, require that your object implement a redirect() Phillip method, and define it in the class as Phillip "class_default_for_redirect". Then you can override the Phillip method in SkinScript or with a class extender (a new Phillip 0.4.3 feature). Doing it this way means your framework Phillip code will not incorporate an assumption that your Phillip whitebox specialist is always going to be wrapping Phillip someone else's objects. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
[Zope-dev] Accessors for DataSkin attributes (was Re: [Zope-dev] Success!Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTWSpecialists? Was: Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?
At 06:57 AM 10/5/00 -0500, Steve Spicklemire wrote: This brings up another point If I choose 'DataSkin' as a storage class, then my code hits the security system every time a refer to any data (simple types) stored directly in the DataSkin. I can either set __allow_access_to_unprotected_subobjects=1 on each instance, or I can write accessor methods for each attribute, (yuk!, but maybe good in some ways...) or I can ask the integrator to create 'dummy' ZClass(es) even for those racks that they don't want/need to customize (which seems to 'get around' the security system.) I'm curious to know what you folks do here.. do you write accessor methods for every type stored in your DataSkins? We never use raw DataSkins, first off. We always create a domain-specific ZClass subclassed from DataSkin. In your case, I would suggest simply including such ZClasses with your product to provide the default implementation of your domain and presentation logic. As for set/get methods, we usually just define DataSkin property sheets in the ZClass, and use permission mappings to define the read/write permissions for each sheet. We group properties in sheets according to the domain model permissions for access. Then the domain logic methods in the ZClass call propertysheets.sheetname.manage_changeProperties() with keyword parameters to set things. Usually, we have domain specific methods that alter the values of multiple attributes at the same time, using the property sheets. We rarely have code outside of the ZClass directly manipulate attributes. In instances where we've needed to set attributes which are of types not supported by Zope propertysheets, we've had to use ExternalMethods or something similar. In the long run we expect to be able to use PropertyHandlers to do this without dropping down to Python. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?
Thanks again... it's great that you're willing to entertain my apparantly twisted use of ZPatterns. ;-) "PJE" == Phillip J Eby [EMAIL PROTECTED] writes: PJE To put it another way: design your whitebox specialist how PJE you want it. Make it complete, but of course some parts will PJE have to be changed if someone wants to use other than your PJE default implementation. If they want its data to come from PJE somewhere else, they can plug in the SkinScript or do PJE whatever else it takes. PJE So, to sum up... Stop worrying about delegated retrieval! PJE :) You're stepping into app integrator territory here. PJE ZPatterns was designed to make it easy to make reusable PJE frameworks without hardly trying. And it was *especially* PJE designed for retrofitting object frameworks over legacy PJE applications and databases. Hmm... OK I see what you mean. I guess I somehow got the idea that ZPatterns worked best when you had two ZPatterns based frameworks that you wanted to work together *after* they had both been designed. I was looking for a way to 'hook up' two 'finished' applications. I was trying to avoid creating a framework that couldn't be easily integrated, by attemting a 'fake' integration myself. How can I be sure I've got all the TTW stuff organized in a way that an integrator can change unless I actually set it up and test it that way? I'd hate to find out later that someone needs to go in and edit my Python code to make my framework useable But.. I think what I'm hearing is that working out the integration at the Rack level is much better than trying to delgate retrieval at the Specialist level. I'm not sure where I got the idea that delegating retrieval at the Specialist level was the 'right' way, maybe in the Drop Zone example? Anyway... thanks again for your reply. I'll march happily along now and see what I run into next! ;-) (I'm especially grateful for your explaination of using a virtual object (non-persistent) in a Rack. I've not seen that explained so clearly anywhere else.. and I'm going to use it! thanks! -steve ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?
Thanks so much for the response... It turns out, I tried the Python Method and it had the same basic problem as the DTML Method... however I've now moved on, using deletageRetrieve to a new thorny issue. ;-) When I get an object from of another specialist it appears that it doies not inherit from my specialist, but from *its* specialist. (e.g., my framework specialist has methods that I want the dataskins to acquire). I've currently got it wrapped like so: def retrieveItem(self, key): """ get an item""" return self.delegateRetrieve(self, None, key=key).__of__(self) I've tried several different combinations of __of__ etc, but none of them seems to allow the dataskin to acquire, for example, standard_html_header from my specialist. Is there any way to enforce acquisition at this level? thanks! -steve "pje" == Phillip J Eby [EMAIL PROTECTED] writes: pje At 08:00 AM 9/25/00 -0500, Steve Spicklemire wrote: So my retrieve item gets called. *unfortunately* it gets called without any namespace parameter... so my retrieveItem DTML method has no way to acquire a namespace so that it can delagate to something else! So... here is what I did... I defined a method in my Python subclass of Specialist.. class MarketItemManager(ZPatterns.Specialists.Specialist): """A Market Item Manager""" # Specify a name for the item type: meta_type='MarketItemManager' def retrieveItem(self, key): """ get an item""" return self.__of__(self).delegateRetrieve(self, None, key=key) Then I made a DTML method called 'delegateRetrieve' like so: dtml-return "myGreatSite.ThingManager.getItem(key)" this way, my integrator can edit 'delegateRetrieve' to point to whatever Specialist he wants to... and I have a Python implementation of retrieveItem. Does this sound OK? Am I working way too hard here? (I feel like I am! ;- ) pje Remember in the code where I have "# XXX DTML check?" That's pje because I was anticipating your problem, but since I didn't pje personally need to do what you're doing yet, I didn't pje implement it. For one thing, I was waiting to see if Zope pje core method binding would get fixed. Unfortunately, I'm not pje sure that Zope method binding is going to be available for pje anything but PythonMethods in 2.3. As of right now, however, pje you should be able to use a PythonMethod for retrieveItem, pje rather than a DTML Method, and it should work. pje In short, even now, delegateRetrieve should not be necessary. pje You should be able to implement retrieveItem using a pje PythonMethod or a DTML Document rather than a DTML Method. pje (I say *should* because I have not tried it personally.) ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?
At 03:14 PM 9/29/00 -0500, Steve Spicklemire wrote: Thanks so much for the response... It turns out, I tried the Python Method and it had the same basic problem as the DTML Method... however I've now moved on, using deletageRetrieve to a new thorny issue. ;-) When I get an object from of another specialist it appears that it doies not inherit from my specialist, but from *its* specialist. (e.g., my framework specialist has methods that I want the dataskins to acquire). I've currently got it wrapped like so: def retrieveItem(self, key): """ get an item""" return self.delegateRetrieve(self, None, key=key).__of__(self) I've tried several different combinations of __of__ etc, but none of them seems to allow the dataskin to acquire, for example, standard_html_header from my specialist. Is there any way to enforce acquisition at this level? You can use aq_base before the __of__, but I wouldn't recommend it, because you'll be forcibly ripping off security-related data. Probably aq_explicit would work better, since it would prevent default acquisition but leave security acquisitions relatively intact. I still suspect, though, that your design is not optimal. If you actually need a "bridge" specialist that lets you change the behaviors of the thing you're accessing, then you should really just build a bridge specialist and not simply do directly delegated retrieval. What you want is to set up a rack in the specialist that creates a virtual object which gets all its attributes (the ones you care about, anyway) from an object retrieved from the other specialist. SkinScript example: WITH otherSpecialist.getItem(self.id) COMPUTE theRealThing = (RESULT is None) and NOT_FOUND or RESULT WITH self.theRealThing COMPUTE myAttr1 = RESULT.theirAttr1, myAttr2 = theirAttr2, # equivalent to myAttr2 = RESULT.theirAttr2 SomeAttr, # equivalent to SomeAttr = RESULT.SomeAttr myAttr5 = theirAttr1 * theirAttr6 # Shorthand way of copying attributes with the same names WITH self.theRealThing COMPUTE foo,bar,baz You would put this in a script inside a rack in your "bridge" specialist. You would set up the rack to be "non-persistent" and use "theRealThing" as the existence attribute. Now, when you access the rack, it will create a dummy object and try to look at its "theRealThing" attribute. This will cause the SkinScript to call the other Specialist and attempt retrieval. If it succeeds, theRealThing will equal the object and the Rack will consider the object to exist in the bridge specialist. If it fails, theRealThing will be a non-existent attribute and the Rack's getItem will return None. Let's say it has succeeded. You now have an object with no attributes loaded other than 'id' and 'theRealThing'. You attempt to access attribute SomeAttr. The second SkinScript declaration fires, and computes the values of myAttr1, myAttr2, SomeAttr, and myAttr5, caching them in the DataSkin. Voila. You now have a completely transformed object, in the context of *your* specialist, with *your* attribute names. It has no leftover acquisition context, but of course you had to have permission to access all those attributes on the object and to the specialist you retrieved it from. But here's the real kicker... You determine in *your* rack the precise ZClass it will be implemented as. In effect, you have rewrapped an object's data into another class. Okay, so that works for reads. What about writes? That's a little more complex, as you'll need to write something like: STORE foo,bar USING self.theRealThing.manage_changeProperties(foo=self.foo,bar=self.bar) For whatever combinations of properties are applicable. If the properties are on a sheet, the USING expression gets more complicated. Note, too, that we could have done transformations on the 'id' to look something up, and that we could also have multiple racks, each doing transformations from different Specialists. Now, you may be asking yourself, "This all looks incredibly flexible, but is it efficient?" Hell no, of course not. You are much better off, if you have the option, of specifying to your framework's user the requirements you have for objects in that part of your system. Then, when they are designing their system, they can get the names and features right, and you call *their* specialist for what you need. If they didn't do it the easy way, then it's again *their* responsibility to re-cast your whitebox as a bridge. (Note, by the way, that if the end-user's raw data is coming from something like an SQL database in the first place, then all they have to do is map from SkinScript to SQL, and this is *much* more efficient than mapping Specialist-Rack-Specialist-Rack-SQL, which involves many more layers of object creation, method calls, and security checks.) To put it another way: design your whitebox specialist how you want it. Make it complete, but of course some parts will have to be changed if someone wants to
[Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?
Hello ZPatterns Folk. I'm trying to implement 'delagation' with a custom Specialist. The idea, (I think this is one of the goals of ZPatterns... to allow delegation of responsibility after the Framework is built...) I have: a) MarketItemManager (Python subclass of Specialist) Some of methods, both DTML Methods, and plain old Python Methods, are *meant* to be acquire by the objects (DataSkins) he manages. b) ThingManager (ZClass subclass of Specialist). This is really just a test class that is supposed to represent some later developer integrating my ZPattern based EMarket into their application, (e.g., inventory or whatever...) in MarketItemManager I've defined a 'retrieveItem' (this would really be done by the integrator...) that does something like this: dtml-return "myGreatSite.ThingSpecialist.getItem(key)" with the hope that when the Specialist class gets traversed it will execute: def __bobo_traverse__(self, REQUEST, name): ob = getattr(self, name, _marker) if ob is _marker: ob = self.getItem(name) --- traversal invokes getItem if ob is not None: return ob raise 'NotFound' return ob def getItem(self, key): """Get an item""" if hasattr(self.aq_base,'retrieveItem'): --- getItem invokes retrieveItem return self.retrieveItem(key=key) # XXX need DTML check? for rack in self.rackList: item = rack.__of__(self).getItem(key) if item is not None: return item So my retrieve item gets called. *unfortunately* it gets called without any namespace parameter... so my retrieveItem DTML method has no way to acquire a namespace so that it can delagate to something else! So... here is what I did... I defined a method in my Python subclass of Specialist.. class MarketItemManager(ZPatterns.Specialists.Specialist): """A Market Item Manager""" # Specify a name for the item type: meta_type='MarketItemManager' def retrieveItem(self, key): """ get an item""" return self.__of__(self).delegateRetrieve(self, None, key=key) Then I made a DTML method called 'delegateRetrieve' like so: dtml-return "myGreatSite.ThingManager.getItem(key)" this way, my integrator can edit 'delegateRetrieve' to point to whatever Specialist he wants to... and I have a Python implementation of retrieveItem. Does this sound OK? Am I working way too hard here? (I feel like I am! ;- ) thanks, -steve ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How is 'retrieveItem intended to work with TTW Specialists?
At 08:00 AM 9/25/00 -0500, Steve Spicklemire wrote: So my retrieve item gets called. *unfortunately* it gets called without any namespace parameter... so my retrieveItem DTML method has no way to acquire a namespace so that it can delagate to something else! So... here is what I did... I defined a method in my Python subclass of Specialist.. class MarketItemManager(ZPatterns.Specialists.Specialist): """A Market Item Manager""" # Specify a name for the item type: meta_type='MarketItemManager' def retrieveItem(self, key): """ get an item""" return self.__of__(self).delegateRetrieve(self, None, key=key) Then I made a DTML method called 'delegateRetrieve' like so: dtml-return "myGreatSite.ThingManager.getItem(key)" this way, my integrator can edit 'delegateRetrieve' to point to whatever Specialist he wants to... and I have a Python implementation of retrieveItem. Does this sound OK? Am I working way too hard here? (I feel like I am! ;- ) Remember in the code where I have "# XXX DTML check?" That's because I was anticipating your problem, but since I didn't personally need to do what you're doing yet, I didn't implement it. For one thing, I was waiting to see if Zope core method binding would get fixed. Unfortunately, I'm not sure that Zope method binding is going to be available for anything but PythonMethods in 2.3. As of right now, however, you should be able to use a PythonMethod for retrieveItem, rather than a DTML Method, and it should work. In short, even now, delegateRetrieve should not be necessary. You should be able to implement retrieveItem using a PythonMethod or a DTML Document rather than a DTML Method. (I say *should* because I have not tried it personally.) ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )