Re: [Zope] - How to register an object?
At 04:57 PM 1/13/99 -0500, Peter J Ulintz wrote:
Hi. Could you take a minute and help me out?
Sure, but I'm taking the liberty of ccing the Zope list so that hopefully others will profit. I hope you don't mind.
So I'm trying to publish an object in the Zope framework. Here's the object
person.py: ----------------------------------------------------------- import DocumentTemplate
class Person: "A simple person" def __init__(self, name): self.name = name
index_html=DocumentTemplate.HTMLFile("my_template.dtml") ------------------------------------------------------------
The "my_template.dtml" file is exactly the same as in the "Techical Introduction to Object Publishing" document. Now, I want to publish the object in the Zope heirarchy using an External Method. I used...
import_person.py: ----------------------------------------------------------- import person
def add_person(self, name = 'John Doe'): """This method is called by a folder to add a person""" person=person.Person(name) if not hasattr(self, name): setattr(self, name, person) return "Person added to folder" -----------------------------------------------------------
In general what you are doing is right--creating an objects and installing it in the object hierarchy. Unfortunately, there is a subtle problems with this. The problem is that your person object cannot be stored in the object database since the External Method machinery makes the Person class hard to unpickle. If you were creating Zope objects, or if the Person class existed somewhere else, like in the Shared module, this approach would work. I believe this limitation is mentioned in the External Method documentation.
So, I create an External Method-- ID: addPerson Title: Add Person Function Name: add_person Python module file: import_person This creates an external method object in my Zope folder called "addPerson". If I now go to the browser and type(I'm using the ZopeHTTPServer)...
OK, here's another problem. No need for quotes around Geddy. In fact those quotes are going to cause you problems.
...I get the response, "Person added to folder". But I'm not sure what's SUPPOSED to happen here. Is the object supposed to magically appear in the folder? What am I doing wrong? Just typing: http://141.214.57.234:9673/addPerson works, but typing http://141.214.57.234:9673/addPerson?data="bullocks" gives the same "Person added to folder" message.
OK, Zope is doing exactly what you are telling it to do. It is creating an object, installing it in a folder and returning a message. I'm not sure what else you want ;-) If you want a Zope object to appear in the management interface after this, you need to install a Zope object, not just a random object. For an object to be manageable through the web with Zope's interface it must support the Zope Product API. Also installing a Zope Product in a Folder should in general be accomplished with the '_setObject' method, not a plain old 'setattr'.
How do I publish an actual "Geddy" person object, that I can call the index_html attribute on? Oh, following your suggestion (and the one in the External Methods documentation on the site), creating a file
OK, the essential functioning of the Zope ORB is to allow you to use URLs to traverse the object hierarchy. So if you call myFolder/addperson?data=duke Then your External Method will add an attribute named 'duke' to 'myFolder'. Therefore you should now be able to access this attribute like so myFolder/duke Make sense? To publish an object you point your browser at its URL.
import_person2.py: --------------------------------------------------------------
import person
def addPerson(self, name='Dufus'): "return person" return person.Person(name) -------------------------------------------------------------
Trying the same thing gives a "Sorry, th requested document does not exist" error. The page source doesn't really tell me much there.
Ouch! My bad! This method does not *publish* a Person instance, it *returns* a Person instance as a response. So Zope tries to understand the instance as a string and decides that it is not a valid response. (Actually viewing the source of the error page should give you some information about what went wrong. That's how I discovered my mistake.) To actually publish an object, it must be part of the object hierarchy so that Zope can traverse it. Let me give a good example here: The first thing we'll do is create a module to hold our publishable classes. Lets create our own package inside the Shared package. Create a directory inside lib/python/Shared named PeeWee (or use your own name). Next create an empty file __init__.py inside the PeeWee directory. This lets Python know that PeeWee is a package. Now let's create a Python file, PlayHouse.py inside the PeeWee directory. class PlayHouse: "Play house" def index_html(self,game='tag'): "publish the playhouse" return "In the play house we play %s." % game OK, now we have a publishable class that is Zope accessible. Now we need to get an instance of that class into the object hierarchy. Let's use an external method. Create a Python file in Extensions named peewee_utils.py from Shared.PeeWee.PlayHouse import PlayHouse def addPlayHouse(self,id): "Add a playhouse to the current folder" if not hasattr(self,id): setattr(self,id,PlayHouse()) return "playhouse added with id %s" % id else: return "id %s already in use" % id Now create an External Method object to give us access to the addPlayHouse method. Suppose we give our External Method the id 'addPlayHouse', and tell it to use the 'addPlayHouse' method of the 'peewee_utils' module. OK, now we can call our method and install a publishable object in the Zope object hierarchy. myFolder/addPlayHouse?id=myHouse This should return "playhouse added with id myHouse". What the method did was create a PlayHouse instance and make it an attribute of the myFolder object. Now we can access the PlayHouse like this: myFolder/myHouse?game=hide+and+seek Which should return "In the play house we play hide and seek." Note that you will not see any PlayHouse object in the management screen. This is because it is not a Zope Product. However, you can indirectly sense that it is there--if you try to create a Document with id 'myHouse' you will be told that 'myHouse' is already in use. I hope this helps. (I'll update the docs on the Zope site.)
Lastly, trying your External Objects product, and importing the "Person" object from the person.py, creates on External Object in the Zope folder. Directing my browser to that brings up the folder's index_html page, no matter what I put as an arguement. How do I use that?
The External Object Product is a container for externally defined publishable objects. You need to tell the External Objects Product the names of the objects you want to publish and the module they reside in. So for example if you define an object 'person' in a module 'Person' in the Extensions directory you need to let External Objects know these facts. Once you have configured your External Object object, access the external objects as sub-objects of the External Objects object like so: myExternalObjects/myObject Note: your published objects may contain further sub-objects. Hope this helps. Object publishing takes a little while to grasp. Don't give up! -Amos P.S. A final note of advice. If you are just learning object publishing--I would advise not trying to plug your objects into the Zope framework right away. Try publishing your own modules with ZopeHTTPServer.py. Get a feel for how to composite objects and how they map to URLs. Then figuring out how to get your objects to play in the Zope framework will make more sense.
I'm playing around with Zope 1.9 final, and am trying to create a Product just for the heck of it. I created a product folder in Control_Panel/Products, but where do you go from there? Obviously, a "Principia Factory" object is required, but what should it be called? What should the method it calls do? I'm a little lost here, and I haven't found any documentation on this. Pointers, anyone?
participants (2)
-
Amos Latteier -
Phillip J. Eby