Damn, I'm loosing my faith in Zope. I'm already 3 days trying to find a solution, but I'm still at the same place as I was 3 days ago. This isn't funny anymore. You're my last resort, I hope someone can help. I'm trying to create a ZClass which updates some properties when it is added or moved. Now, people pointed me to the manage_afterAdd method. And indeed, when I use this code (as an external method) : def manage_afterAdd(self,item,container) item.myparent=container.id return it works when I don't have a class which inherits from CatalogAware Class. However, it doesn't works with a class inherited from CatalogAware Class. Probably because the manage_afterAdd method is defined in the CatalogAware Class. So I tried to modify the external method to : def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return But then I get following error when adding an instance of the new class : Zope Error Zope has encountered an error while publishing this resource. Error Type: NameError Error Value: CatalogAware Troubleshooting Suggestions This resource may be trying to reference a nonexistent object or variable CatalogAware. The URL may be incorrect. The parameters passed to this resource may be incorrect. A resource that this resource relies on may be encountering an error. Urgh, I'm really desperate. Do you know what I'm doing wrong? ps. Why does this function has to be an external method? Is it also possible with an DTML method? Regards, Tom.
Tom Deprez wrote:
Damn, I'm loosing my faith in Zope. I'm already 3 days trying to find a solution, but I'm still at the same place as I was 3 days ago. This isn't funny anymore.
You're my last resort, I hope someone can help.
I'm trying to create a ZClass which updates some properties when it is added or moved. Now, people pointed me to the manage_afterAdd method. And indeed, when I use this code (as an external method) :
def manage_afterAdd(self,item,container) item.myparent=container.id return
it works when I don't have a class which inherits from CatalogAware Class. However, it doesn't works with a class inherited from CatalogAware Class. Probably because the manage_afterAdd method is defined in the CatalogAware Class.
So I tried to modify the external method to :
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
But then I get following error when adding an instance of the new class :
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: NameError Error Value: CatalogAware
Troubleshooting Suggestions
This resource may be trying to reference a nonexistent object or variable CatalogAware. The URL may be incorrect. The parameters passed to this resource may be incorrect. A resource that this resource relies on may be encountering an error.
Urgh, I'm really desperate. Do you know what I'm doing wrong?
ps. Why does this function has to be an external method? Is it also possible with an DTML method?
Tom, I do not claim to be an expert on these items, so please bear with me. Most of my knowledge is theoretical, but since no one else steps in, a non-expert answer is better than none at all I suppose (and who knows what other responses my blundering invokes ;-) A few remarks: Your external method doesn't define a new class? It shouldn't, because I believe Zope prevents you from doing it, and if you could, it is looked upon as bad practice. A function can't (in itself) override a class method. You should override it in a subclass from CatalogAware. But we are talking python products here or python base classes for ZClasses, and I'm not sure you want that. If so, look at the Boring Product for a general introduction. Some more points: If you want to use CatalogAware from an external method, you have to import it. Did you do that in your method? (that's not clear from your posts now) You can't do this in a DTML Method, and not even in a PythonMethod, though there may be ways around this last one with XXXPythonMethods. External Methods are plain python, but with a Zope twist that prevents them from doing certain things. HTH Rik
Hi Rik, Yes, thanks for replying! Getting non-experts replies is better then getting none because otherwise it looks like you're alone on Zope world. Ok, I'll tell you something more : I've created a ZClass with as base class CatalogAware. The external method just contains what I wrote below. In the ZClass method tab, I create a new method (manage_afterAdd) which points to this external method. So when a ZClass instance is added or moved, the manage_afterAdd method should be executed.
If you want to use CatalogAware from an external method, you have to import it.
I did, but perhaps here is the mistake. Here is my full python script (and my first). import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness """ CatalogAwareness contains the CatalogAware Class """ def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return I also tried this, but it always gives the same error : def manage_afterAdd(self,item,container) import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return I'll look at the boring product. Thanks, Tom. At 10:26 07/03/2000 +0100, Rik Hoekstra wrote:
Tom Deprez wrote:
Damn, I'm loosing my faith in Zope. I'm already 3 days trying to find a solution, but I'm still at the same place as I was 3 days ago. This isn't funny anymore.
You're my last resort, I hope someone can help.
I'm trying to create a ZClass which updates some properties when it is added or moved. Now, people pointed me to the manage_afterAdd method. And indeed, when I use this code (as an external method) :
def manage_afterAdd(self,item,container) item.myparent=container.id return
it works when I don't have a class which inherits from CatalogAware Class. However, it doesn't works with a class inherited from CatalogAware Class. Probably because the manage_afterAdd method is defined in the CatalogAware Class.
So I tried to modify the external method to :
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
But then I get following error when adding an instance of the new class :
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: NameError Error Value: CatalogAware
Troubleshooting Suggestions
This resource may be trying to reference a nonexistent object or variable CatalogAware. The URL may be incorrect. The parameters passed to this resource may be incorrect. A resource that this resource relies on may be encountering an error.
Urgh, I'm really desperate. Do you know what I'm doing wrong?
ps. Why does this function has to be an external method? Is it also possible with an DTML method?
Tom,
I do not claim to be an expert on these items, so please bear with me. Most of my knowledge is theoretical, but since no one else steps in, a non-expert answer is better than none at all I suppose (and who knows what other responses my blundering invokes ;-)
A few remarks: Your external method doesn't define a new class? It shouldn't, because I believe Zope prevents you from doing it, and if you could, it is looked upon as bad practice. A function can't (in itself) override a class method. You should override it in a subclass from CatalogAware. But we are talking python products here or python base classes for ZClasses, and I'm not sure you want that. If so, look at the Boring Product for a general introduction.
Some more points: If you want to use CatalogAware from an external method, you have to import it. Did you do that in your method? (that's not clear from your posts now)
You can't do this in a DTML Method, and not even in a PythonMethod, though there may be ways around this last one with XXXPythonMethods. External Methods are plain python, but with a Zope twist that prevents them from doing certain things.
HTH
Rik
Tom Deprez wrote:
Hi Rik,
Yes, thanks for replying! Getting non-experts replies is better then getting none because otherwise it looks like you're alone on Zope world.
Ok, I'll tell you something more :
I've created a ZClass with as base class CatalogAware. The external method just contains what I wrote below. In the ZClass method tab, I create a new method (manage_afterAdd) which points to this external method.
So when a ZClass instance is added or moved, the manage_afterAdd method should be executed.
If you want to use CatalogAware from an external method, you have to import it.
I did, but perhaps here is the mistake. Here is my full python script (and my first).
import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness
if you want CatalogAware that should read: from CatalogAwareness import CatalogAware or refer to CatalogAware later on as: CatalogAwareness.CatalogAware.manage_afterAdd
""" CatalogAwareness contains the CatalogAware Class """
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
I also tried this, but it always gives the same error :
def manage_afterAdd(self,item,container) import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness
item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
same problem as above. Rik
Ok, it was the import problem! Thanks to all! Q1: So, in python you've to say which class you want to import? Q2: And from test.parent.mylib means go to the directory test then parent and then use the mylib library? However, now I stumbeld on more problems. I receive an error about using an onbound method... Q3: What is an unbound method?? Thanks to another email, I could solve this 'unbound method-error' with the following line : CatalogAware.manage_afterAdd.im_func(self,item,container) Now, adding an instance works without a problem, but when a try to cut and paste the instance, I get the following message: Zope Error Zope has encountered an error while publishing this resource. Error Type: AttributeError Error Value: aq_acquire Q4: Euhm, what does this error means? Thanks, Tom.
Tom Deprez wrote:
Now, adding an instance works without a problem, but when a try to cut and paste the instance, I get the following message:
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: AttributeError Error Value: aq_acquire
Q4: Euhm, what does this error means?
This is a bug in Zope, specifically in CatalogAware.url's call of absolute_url. -- Itamar S.T. itamars@ibm.net
Tom Deprez wrote:
Now, adding an instance works without a problem, but when a try to cut and paste the instance, I get the following message:
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: AttributeError Error Value: aq_acquire
Q4: Euhm, what does this error means?
This is a bug in Zope, specifically in CatalogAware.url's call of absolute_url.
Oops, is their a work-around? Tom.
Tom Deprez wrote:
Ok, it was the import problem! Thanks to all!
Q1: So, in python you've to say which class you want to import?
Q2: And from test.parent.mylib means go to the directory test then parent and then use the mylib library?
However, now I stumbeld on more problems. I receive an error about using an onbound method...
Q3: What is an unbound method??
A method that is not bound to a class instance. This is really a pretty strictly python question. I recommend you read the python language reference for a better description of this. I think you should not use an external method, but rather create a Python class that subclasses whatever you want to subclass and then defines a new manage_afterAdd that implements your behavior. I don't think external methods are ideal at all for this kind of development. This requires either reverse engineering existing Zope products or culling the list for this wisdom, there really isn't any formal recipie for this kind of thing. This isn't necessarily a documetation issue, for altough we can document interfaces and product conventions (which we are working on), we cannot entirely document every issue concerning engineering software in python.
Thanks to another email, I could solve this 'unbound method-error' with the following line :
CatalogAware.manage_afterAdd.im_func(self,item,container)
Off the top of my head, I don't know why you have to do this. Whether this is an artifact of developing with ZClasses and External Methods I couldn't tell you either. But I do know that when developing a pure python class this does not need to happen and is probably a bad idea to get into the habit.
Now, adding an instance works without a problem, but when a try to cut and paste the instance, I get the following message:
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: AttributeError Error Value: aq_acquire
This is probably a known bug in 2.1.4, but without a traceback I cannot tell you definatly. You should allways post traceback when you are trying to get an explanation of a development error. If this is the same bug, it is fixed in CVS and you should get the latest version of lib/python/Products/ZCatalog/CatalogAwareness.py from the public CVS server. -Michel
I think you should not use an external method, but rather create a Python class that subclasses whatever you want to subclass and then defines a new manage_afterAdd that implements your behavior. I don't think external methods are ideal at all for this kind of development. This requires either reverse engineering existing Zope products or culling the list for this wisdom, there really isn't any formal recipie for this kind of thing. This isn't necessarily a documetation issue, for altough we can document interfaces and product conventions (which we are working on), we cannot entirely document every issue concerning engineering software in python.
Why can't I use a ZClass for this, like I'm doing now? I don't know anything about Python, so I really don't know how to start with a Python class that subclasses... I only want to have a ZClass which changes a property when an instance is added, but also when it's moved (cut, paste). The only reason why I'm working with an external method is because people told me about the manage_afterAdd method. What is at the moment the only way to achieve the thing I want (ie. a property that is updated when an instance is moved eg from one folder to another). Is their another way to now when a ZClass instance is updated or moved? Why I want to do this? This is what I'm trying to make: A knowledge base system which automatically cataloges itself into the catalog (so they should descent from CatalogAware). A KBItem can only exist in a KBFolder. The KBItem is cataloged on a property of the KBItem. The property will contain a string with the names of its parent KBFolder, parent-parent KBFolder, etc. This way, no special handling has to be done to create certain KB categories. The KBFolders itself are the categories. One problem to achieve this is to find a way how the 'cataloged property' of a KBItem instance can be updated when it is added and moved. In fact, in my idea, just a simple KB product, but it looks like it is hard to create.
Thanks to another email, I could solve this 'unbound method-error' with the following line :
CatalogAware.manage_afterAdd.im_func(self,item,container)
Off the top of my head, I don't know why you have to do this. Whether this is an artifact of developing with ZClasses and External Methods I couldn't tell you either. But I do know that when developing a pure python class this does not need to happen and is probably a bad idea to get into the habit.
mmm... here is the mail where I got this im_func from: Tom, I haven't done exactly what you're trying to do -- extend CatalogAware methods in a ZClass -- but I have a similar kinds of method extension in a Python product class. # Only index if nextEventTime returns something def index_object(self): if self.nextEventTime() is not None: CatalogAware.index_object.im_func(self) # see Python Reference Manual "The standard type hierarchy" # for the built-in type im_func Actually this code came from Martijn Pieters. He explained: """ im_func is a part of Python introspection. It is the pure function definition of a class, not bound to that class, so I can pass in an alternate self. I am trying to call a superclass method here, and normally CatalogAware.index_object() would suffice. But because of Extension Classes, Python gets confused as to what is a class method, and what is a regular function. It will accuse me of calling an unbound method, which of course I am not. I circumvent this by calling the unbound function, and passing in self explicitly. """ I don't know if this applies to your case. Regards, Tom.
Tom Deprez wrote:
"Quote Martijn" im_func is a part of Python introspection. It is the pure function definition of a class, not bound to that class, so I can pass in an alternate self.
Aiee! Split personality objects!
I am trying to call a superclass method here, and normally CatalogAware.index_object() would suffice. But because of Extension Classes, Python gets confused as to what is a class method, and what is a regular function. It will accuse me of calling an unbound method, which of course I am not. I circumvent this by calling the unbound function, and passing in self explicitly.
Then this sounds like a bug in ExtensionClass, shouldn't it be able to grock that CatalogAware.method(instance) is a class method bound to instance? Dammit I've seen this somewhere before... ah, this might be it, quothe the ExtensionClass documetation: Overriding methods inherited from Python base classes A problem occurs when trying to overide methods inherited from Python base classes. Consider the following example:: from ExtensionClass import Base class Spam: def __init__(self, name): self.name=name class ECSpam(Base, Spam): def __init__(self, name, favorite_color): Spam.__init__(self,name) self.favorite_color=favorite_color This implementation will fail when an 'ECSpam' object is instantiated. The problem is that 'ECSpam.__init__' calls 'Spam.__init__', and 'Spam.__init__' can only be called with a Python instance (an object of type '"instance"') as the first argument. The first argument passed to 'Spam.__init__' will be an 'ECSpam' instance (an object of type 'ECSPam'). MP> ^^^^^^^^ This sounds like your problem right here ^^^^^^^^ To overcome this problem, extension classes provide a class method 'inheritedAttribute' that can be used to obtain an inherited attribute that is suitable for calling with an extension class instance. Using the 'inheritedAttribute' method, the above example can be rewritten as:: from ExtensionClass import Base class Spam: def __init__(self, name): self.name=name class ECSpam(Base, Spam): def __init__(self, name, favorite_color): ECSpam.inheritedAttribute('__init__')(self,name) self.favorite_color=favorite_color This isn't as pretty but does provide the desired result. I don't think, however, that this can be used called from an external method. There is no access to whatever class your method is a shared attribute of ('self' in an external method could be bound to all sorts of class instances depending on how it is called). I could be completely wrong. -Michel
Grok, this was were I'm afraid for, I don't understand what you guru's are talking of :-(. I can follow partly, but not the essence. But, thanks for giving me a solution. It's better to know that you still have to learn much then just getting the answer that it isn't possible. Since I haven't asked this q'n directly here -the question which has given me already 3 days of headache-, perhaps some of you can share me your idea on how to solve this problem. (The q'ns I asked before on this list are directly descending from this q'n): How can a ZClass know when it is moved and how can you add some code to it, so this code is executed when the ZClass is moved. Tom. At 03:51 07/03/2000 -0800, Michel Pelletier wrote:
Tom Deprez wrote:
"Quote Martijn" im_func is a part of Python introspection. It is the pure function definition of a class, not bound to that class, so I can pass in an alternate self.
Aiee! Split personality objects!
I am trying to call a superclass method here, and normally CatalogAware.index_object() would suffice. But because of Extension Classes, Python gets confused as to what is a class method, and what is a regular function. It will accuse me of calling an unbound method, which of course I am not. I circumvent this by calling the unbound function, and passing in self explicitly.
Then this sounds like a bug in ExtensionClass, shouldn't it be able to grock that CatalogAware.method(instance) is a class method bound to instance?
Dammit I've seen this somewhere before... ah, this might be it, quothe the ExtensionClass documetation:
Overriding methods inherited from Python base classes
A problem occurs when trying to overide methods inherited from Python base classes. Consider the following example::
from ExtensionClass import Base
class Spam:
def __init__(self, name): self.name=name
class ECSpam(Base, Spam):
def __init__(self, name, favorite_color): Spam.__init__(self,name) self.favorite_color=favorite_color
This implementation will fail when an 'ECSpam' object is instantiated. The problem is that 'ECSpam.__init__' calls 'Spam.__init__', and 'Spam.__init__' can only be called with a Python instance (an object of type '"instance"') as the first argument. The first argument passed to 'Spam.__init__' will be an 'ECSpam' instance (an object of type 'ECSPam').
MP> ^^^^^^^^ This sounds like your problem right here ^^^^^^^^
To overcome this problem, extension classes provide a class method 'inheritedAttribute' that can be used to obtain an inherited attribute that is suitable for calling with an extension class instance. Using the 'inheritedAttribute' method, the above example can be rewritten as::
from ExtensionClass import Base
class Spam:
def __init__(self, name): self.name=name
class ECSpam(Base, Spam):
def __init__(self, name, favorite_color): ECSpam.inheritedAttribute('__init__')(self,name) self.favorite_color=favorite_color
This isn't as pretty but does provide the desired result.
I don't think, however, that this can be used called from an external method. There is no access to whatever class your method is a shared attribute of ('self' in an external method could be bound to all sorts of class instances depending on how it is called). I could be completely wrong.
-Michel
Tom Deprez wrote:
Grok, this was were I'm afraid for, I don't understand what you guru's are talking of :-(. I can follow partly, but not the essence. But, thanks for giving me a solution. It's better to know that you still have to learn much then just getting the answer that it isn't possible.
Since I haven't asked this q'n directly here -the question which has given me already 3 days of headache-, perhaps some of you can share me your idea on how to solve this problem. (The q'ns I asked before on this list are directly descending from this q'n):
How can a ZClass know when it is moved and how can you add some code to it, so this code is executed when the ZClass is moved.
As far a ZCatalog is concerned I do not know (I actually thought it did uncatalog catalog aware objects itself). Quoting from your other post: "A knowledge base system which automatically cataloges itself into the catalog (so they should descent from CatalogAware). A KBItem can only exist in a KBFolder. The KBItem is cataloged on a property of the KBItem. The property will contain a string with the names of its parent KBFolder, parent-parent KBFolder, etc. This way, no special handling has to be done to create certain KB categories. The KBFolders itself are the categories. One problem to achieve this is to find a way how the 'cataloged property' of a KBItem instance can be updated when it is added and moved." But reading this carefully: - When a KBItem already is inside a KBFolder and the KBFolder is its category, then why go into the trouble of creating/updating properties. THis is information replication, which you should avoid I would think a simple <dtml-var "<specificKBFolder>.objectValues(['KBItem'])"> will get you all the items you want for a specific category. You may need a Catalog to do more complicated things, but you will have to be more specific for us to be able to help you. Rik
But reading this carefully:
- When a KBItem already is inside a KBFolder and the KBFolder is its category, then why go into the trouble of creating/updating properties. THis is information replication, which you should avoid I would think a simple <dtml-var "<specificKBFolder>.objectValues(['KBItem'])"> will get you all the items you want for a specific category. You may need a Catalog to do more complicated things, but you will have to be more specific for us to be able to help you.
Ah yes, but I thought not to catalog KBFolders. They are merely the class which shows the KBItems in a way you want. Assume this: you've the following Knowledgebase Tree : Python Zope What is Zope? Problem 1 Python DTML What is DTML? ... Then this would be Python (KBFolder) Zope (KBFolder) What is Zope? (KBItem; Categorie: ZOPE) Problem 1 (KBItem; Categorie: ZOPE) Python (KBFolder) DTML (KBFolder) What is DTML? (KBItem; Categorie ZOPE DTML) Now: searching for DTML will return: 'What is DTML?' searching for ZOPE will return: 'What is ZOPE?', 'Problem1', 'What is DTML?' Tom.
Tom Deprez wrote:
But reading this carefully:
- When a KBItem already is inside a KBFolder and the KBFolder is its category, then why go into the trouble of creating/updating properties. THis is information replication, which you should avoid I would think a simple <dtml-var "<specificKBFolder>.objectValues(['KBItem'])"> will get you all the items you want for a specific category. You may need a Catalog to do more complicated things, but you will have to be more specific for us to be able to help you.
Ah yes, but I thought not to catalog KBFolders. They are merely the class which shows the KBItems in a way you want. Assume this: you've the following Knowledgebase Tree :
Python Zope What is Zope? Problem 1 Python DTML What is DTML? ...
Then this would be
Python (KBFolder) Zope (KBFolder) What is Zope? (KBItem; Categorie: ZOPE) Problem 1 (KBItem; Categorie: ZOPE) Python (KBFolder) DTML (KBFolder) What is DTML? (KBItem; Categorie ZOPE DTML)
Now:
searching for DTML will return: 'What is DTML?' searching for ZOPE will return: 'What is ZOPE?', 'Problem1', 'What is DTML?'
OK, this is clear. This could be (partially) resolved with my proposal: <dtml-in "ZOPE.objectValues(['KBFolder', 'KBItem])"> <dtml-if "_['sequence-item'].meta_type=='KBFolder'"> <dtml-in "_.sequence-item.objectValues(['KBItem'])> <dtml-var sequence-item> </dtml-in> <dtml-else> <dtml-var sequence-item> </dtml-if> </dtml-in> [notes: this is only to give the idea. It is not tested. 1. It would need some elaboration for more than 1 item deep (by factoring out the dtml-if, for example 2. Though I did not try this, I'm sure you could also do this with KBFolders returned from a Catalog] Rik
Ah yes, but I thought not to catalog KBFolders. They are merely the class which shows the KBItems in a way you want. Assume this: you've the following Knowledgebase Tree :
Python Zope What is Zope? Problem 1 Python DTML What is DTML? ...
Then this would be
Python (KBFolder) Zope (KBFolder) What is Zope? (KBItem; Categorie: ZOPE) Problem 1 (KBItem; Categorie: ZOPE) Python (KBFolder) DTML (KBFolder) What is DTML? (KBItem; Categorie ZOPE DTML)
Now:
searching for DTML will return: 'What is DTML?' searching for ZOPE will return: 'What is ZOPE?', 'Problem1', 'What is DTML?'
OK, this is clear. This could be (partially) resolved with my proposal:
<dtml-in "ZOPE.objectValues(['KBFolder', 'KBItem])"> <dtml-if "_['sequence-item'].meta_type=='KBFolder'"> <dtml-in "_.sequence-item.objectValues(['KBItem'])> <dtml-var sequence-item> </dtml-in> <dtml-else> <dtml-var sequence-item> </dtml-if> </dtml-in>
[notes: this is only to give the idea. It is not tested. 1. It would need some elaboration for more than 1 item deep (by factoring out the dtml-if, for example 2. Though I did not try this, I'm sure you could also do this with KBFolders returned from a Catalog]
Rik
Hi Rik, Ok, this is already the implementation of the folder. But how can we fill in the category property? eg. the KBItem 'What is DTML?' has it's category property filled with the strings 'ZOPE' and 'DTML'. These strings are the KBFolders 'ZOPE' and 'DTML'. Ok, it's no problem to get the correct strings when adding a KBItem. But what when you move the KBItem? eg. to folder 'Python'. Then the category property should contain 'ZOPE' and 'PYTHON'... Do you see the problem? Tom.
Ok, it's no problem to get the correct strings when adding a KBItem. But what when you move the KBItem? eg. to folder 'Python'. Then the category property should contain 'ZOPE' and 'PYTHON'...
Do you see the problem?
If the category property only repeats the values from the containing folder, you don't need it if you use the folders as categories (which you do, and which my proposal does). THen you would not have to search KBItems on categories directly, because the folders _are_ the categories already. That is what I was trying to expose in my previous messages. Is this clear enough? Rik
Do you see the problem?
If the category property only repeats the values from the containing folder, you don't need it if you use the folders as categories (which you do, and which my proposal does). THen you would not have to search KBItems on categories directly, because the folders _are_ the categories already. That is what I was trying to expose in my previous messages.
Is this clear enough?
I agree it's better to use the folders as search objects, but I'm not not totally sure if this solves the problem. Just tell me where I'm wrong: If we want to provide a search engine, so that the user can directly enter keywords, we've to descend our KBFolder from CatalogAware so that a ZCatalog can be used. The KBFolder name is used for searching. We get this tree Python (KBFolder; Categorie: PYTHON) Zope (KBFolder; Categorie: ZOPE) What is Zope? (KBItem) Problem 1 (KBItem) Python (KBFolder; Categorie PYTHON) !! -> Should be (ZOPE PYTHON) DTML (KBFolder; Categorie DTML) !! -> Should be (ZOPE DTML) What is DTML? (KBItem) A user wants to search for 'ZOPE' AND 'PYTHON' If we use only the name of the folder as catalog then we get no result. This is wrong, not? We've a category of Python within Zope. However it is categorised as PYTHON. It should be categorised as ZOPE PYTHON. And when we move the folder is should change it categories according to the KBFolders a top of itself. Not? Please, tell me where my braintumor is messing my clear thinking. Thanks in advance, Tom.
Rik
Tom Deprez wrote:
<snip> Just tell me where I'm wrong:
If we want to provide a search engine, so that the user can directly enter keywords, we've to descend our KBFolder from CatalogAware so that a ZCatalog can be used. The KBFolder name is used for searching. We get this tree
Python (KBFolder; Categorie: PYTHON) Zope (KBFolder; Categorie: ZOPE) What is Zope? (KBItem) Problem 1 (KBItem) Python (KBFolder; Categorie PYTHON) !! -> Should be (ZOPE PYTHON) DTML (KBFolder; Categorie DTML) !! -> Should be (ZOPE DTML) What is DTML? (KBItem)
A user wants to search for 'ZOPE' AND 'PYTHON'
If we use only the name of the folder as catalog then we get no result. This is wrong, not? We've a category of Python within Zope. However it is categorised as PYTHON. It should be categorised as ZOPE PYTHON. And when we move the folder is should change it categories according to the KBFolders a top of itself. Not?
Please, tell me where my braintumor is messing my clear thinking.
Its the idea that on your first try working with classes in python, Zope, subclassing, etc. you could get it to work :) Maybe its the idea of "a property" that is messing you up. (I'm working with the same parent-parent-etc. thing.) The idea I am using is to store (in the catalog) the result of a external method that returns the parent-parent string. This way any cut-paste-move that updates the catalog, gets the new values. something simple (I'm no python expert... change as needed, meta_type typing etc.) "parents.py": from string import split def parents(self): parentsnames = split(self.absolute_url(),'/')[3:-1] # [3:-1] removes the host info or use something different to split on.. # the -1 removes the last element, i.e. self.id return parentsnames I use something similiar to store the parents in my Zcatalogs. You may need to resolve_url to get the objects and do your checking, etc.. regards, David
Thanks in advance,
Tom.
Rik
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org 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 )
Please, tell me where my braintumor is messing my clear thinking.
Its the idea that on your first try working with classes in python, Zope, subclassing, etc. you could get it to work :)
I'm afraid you're right on this. However, this is the way I learned all the other languages. :-)
Maybe its the idea of "a property" that is messing you up. (I'm working with the same parent-parent-etc. thing.)
The idea I am using is to store (in the catalog) the result of a external method that returns the parent-parent string. This way any cut-paste-move that updates the catalog, gets the new values.
something simple (I'm no python expert... change as needed, meta_type typing etc.)
"parents.py": from string import split
def parents(self): parentsnames = split(self.absolute_url(),'/')[3:-1] # [3:-1] removes the host info or use something different to split on.. # the -1 removes the last element, i.e. self.id return parentsnames
I use something similiar to store the parents in my Zcatalogs.
You may need to resolve_url to get the objects and do your checking, etc..
aha! Looks like this is indeed another way of looking into the problem. However, I don't understand it fully. Where, when, how do you call this external method ie parents(self)? Regards, Tom.
Tom Deprez wrote:
aha! Looks like this is indeed another way of looking into the problem. However, I don't understand it fully. Where, when, how do you call this external method ie parents(self)?
In the catalog add a indexed field name with the name of the external method. regards, David
Regards, Tom.
At 09:08 07/03/2000 -0800, David Kankiewicz wrote:
Tom Deprez wrote:
aha! Looks like this is indeed another way of looking into the problem. However, I don't understand it fully. Where, when, how do you call this external method ie parents(self)?
In the catalog add a indexed field name with the name of the external method.
So,... The catalog itself will call this external method! Great! Didn't know it worked with external methods also. Where did you found this information? Tom.
Tom Deprez wrote:
So,... The catalog itself will call this external method! Great! Didn't know it worked with external methods also. Where did you found this information?
Tom.
Reading the zope list for forever. :) I'm no longer on the main list though. Am I missing anything? regards, David
How can a ZClass know when it is moved and how can you add some code to it, so this code is executed when the ZClass is moved.
Tom.
I'm just trying to learn Zope with the background I have and thus I come with these (probably) stupid ideas and questions: This is not so difficult in other languages as eg Delphi : MyClass=Class(BaseClass) (blabla) function test(...); override; (blabla) end; function MyClass.test(....); begin <do whatever you want> inherited; (now call the function from BaseClass) end; So in Zope I thought: Make a ZClass descending from CatalogAware Then give the ZClass the method manage_afterAdd and define your code in this method. In the method, refer to the manage_afterAdd method of the baseclass. The funny thing is, is that this fully works when I don't descent from CatalogAware. I just stumble to all these problems when I descent from CatalogAware. Possibly because CatalogAware itself uses the manage_afterAdd method. Tom.
Michel, please tell us what document you are reading. Somehow I've never seen it before. -- Thanks -- Loren [snip] From: Michel Pelletier <michel@digicool.com>
Dammit I've seen this somewhere before... ah, this might be it, quothe the ExtensionClass documetation:
Overriding methods inherited from Python base classes
[snip]
lib/Components/ExtensionClass/ExtensionClass.stx -Michel Loren Stafford wrote:
Michel, please tell us what document you are reading. Somehow I've never seen it before.
-- Thanks -- Loren
[snip] From: Michel Pelletier <michel@digicool.com>
Dammit I've seen this somewhere before... ah, this might be it, quothe the ExtensionClass documetation:
Overriding methods inherited from Python base classes
[snip]
Tom Deprez wrote:
Ok, it was the import problem! Thanks to all!
Following this thread with baited breath. Ah, I would've said the same as Rik did, ain't I good? (it's easy to say so in retrospect) :)
Q1: So, in python you've to say which class you want to import?
In Python, namespaces are _the_ thing. If you have a module A (called A.py in the filesystem), and it's somewhere where Python can see it (so it'll import it), and module A contains something called B (this may be a class, some global variable, a function, whatever), you can do this: import A # now this module knows about module A A.B() # do something with B in A Or you can do this: from A import B # import B into this namespace directly, from A B() # do something with B Or you can even do this: import A from A import B A.B() B() The Python tutorial at www.python.org should explain this.
Q2: And from test.parent.mylib means go to the directory test then parent and then use the mylib library?
Python has a package system. If you have a directory which contains a file (may be empty) called __init__.py, this directory becomes a package. A package may contain multiple modules (or more packages). Because you use the dot notation (.) to refer to something inside another namespace, A.B.C may mean various things. You may be referring to a function or global or class C in module B which is in package A. You may be referring to a function C in object B which is in object A, too.
However, now I stumbeld on more problems. I receive an error about using an onbound method...
Q3: What is an unbound method??
Python objects can have methods attached to them. For instance: class Foo: def mymethod(self): print "Hoi" Now if I do: m = Foo.mymethod and then: m() I'll get an unbound method error, as I'm trying to treat a method (to some class) as a function, and Python doesn't know what to do there, because it doesn't make sense (usually) to a call a method on a class directly. If you do this: foo = Foo() # create a foo object n = foo.mymethod and then: n() It'll work, though, as Python knows to which object this method is bound (foo). [snip]
Now, adding an instance works without a problem, but when a try to cut and paste the instance, I get the following message:
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: AttributeError Error Value: aq_acquire
Q4: Euhm, what does this error means?
Uh oh -- that's hard to say, as we're dealing with Zope's sometimes rather mysterious acquisition machinery here.. Zope wraps objects into 'acquisition wrappers'. These wrapper objects behave exactly like the wrapped objects, but define some extra machinery to handle acquisition. What it looks like here is your object somehow lost its wrappers, so Zope sees a wrapperless object where it expects a wrapped one. Regards, Martijn
Hi there, Something I forgot in my previous response: Tom, instead of struggling with ZClasses for whatever you want to do, it may be easier to go to Python based products completely (or at least Python base classes to ZClasses). While you may run into odd problems there too, at least you won't have the ZClasses to confuse you further. Of course, I'm speaking as someone who is already quite familiar with Python, and you're not, so this may be bad advice for you. :) Regards, Martijn
Martijn Faassen wrote:
Hi there,
Something I forgot in my previous response: Tom, instead of struggling with ZClasses for whatever you want to do, it may be easier to go to Python based products completely (or at least Python base classes to ZClasses). While you may run into odd problems there too, at least you won't have the ZClasses to confuse you further.
Of course, I'm speaking as someone who is already quite familiar with Python, and you're not, so this may be bad advice for you. :)
On the other hand, what Tom is trying to accomplish in ZClasses sounds very complicated to me. Tom, what you want to do will most probably require both ZClass and Python knowledge. There is a limit to what you can do with ZClasses, I'm afraid, and influencing the underlying python classes is beyond that limit. Rik
Tom Deprez wrote:
def manage_afterAdd(self,item,container) import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness
item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
That should be from CatalogAwareness import CatalogAware not import CatalogAwareness I think. -- Itamar S.T. itamars@ibm.net
This may be a silly question, but have you imported CatalogAware from wherever it is defined, into the file where where the external method is? If not, try doing that. James. -- Email: james@daa.com.au WWW: http://www.daa.com.au/~james/ On Tue, 7 Mar 2000, Tom Deprez wrote:
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
But then I get following error when adding an instance of the new class :
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: NameError Error Value: CatalogAware
Troubleshooting Suggestions
This resource may be trying to reference a nonexistent object or variable CatalogAware. The URL may be incorrect. The parameters passed to this resource may be incorrect. A resource that this resource relies on may be encountering an error.
Urgh, I'm really desperate. Do you know what I'm doing wrong?
ps. Why does this function has to be an external method? Is it also possible with an DTML method?
Regards, Tom.
Thanks for the reply James, I do import the ClassAwareness library, but perhaps here is the mistake. Here is my full python script (and my first). import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness """ CatalogAwareness contains the CatalogAware Class """ def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return I also tried this, but it always gives the same error : def manage_afterAdd(self,item,container) import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return Thanks, Tom. At 17:47 07/03/2000 +0800, James Henstridge wrote:
This may be a silly question, but have you imported CatalogAware from wherever it is defined, into the file where where the external method is? If not, try doing that.
James.
-- Email: james@daa.com.au WWW: http://www.daa.com.au/~james/
On Tue, 7 Mar 2000, Tom Deprez wrote:
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
But then I get following error when adding an instance of the new class :
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: NameError Error Value: CatalogAware
Troubleshooting Suggestions
This resource may be trying to reference a nonexistent object or variable CatalogAware. The URL may be incorrect. The parameters passed to this resource may be incorrect. A resource that this resource relies on may be encountering an error.
Urgh, I'm really desperate. Do you know what I'm doing wrong?
ps. Why does this function has to be an external method? Is it also possible with an DTML method?
Regards, Tom.
On Tue, 7 Mar 2000, Tom Deprez wrote:
Thanks for the reply James,
I do import the ClassAwareness library, but perhaps here is the mistake. Here is my full python script (and my first).
import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness
Either change this line to from CatalogAwareness import CatalogAware
""" CatalogAwareness contains the CatalogAware Class """
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container)
or change this line to: CatalogAwareness.CatalogAware.manage_afterAdd(...)
return
I also tried this, but it always gives the same error :
Thanks, Tom.
Either of those should fix the problem. Just remember that "import ..." imports the _module_ into the current namespace, and "from ... import ..." imports things _from_ the module into the current namespace. Which solution you choose depends on your coding style. James.
Tom, You do not import the CatalogAware class, you import the CatalogAwareness module. The CatalogAware class is contained in the CatalogAwareness module but python does not know this unless you explicitly import what you explicitly try and use. Thus, the CatalogAware class is not defined any any of your namespaces and you get a NameError. Either: from CatalogAwareness import CatalogAware Or: CatalogAwareness.Catalog.manage_afterAdd(self, item, container) -Michel Tom Deprez wrote:
Thanks for the reply James,
I do import the ClassAwareness library, but perhaps here is the mistake. Here is my full python script (and my first).
import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness """ CatalogAwareness contains the CatalogAware Class """
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
I also tried this, but it always gives the same error :
def manage_afterAdd(self,item,container) import sys sys.path.append('usr/local/zope/lib/python/Products/ZCatalog') import CatalogAwareness
item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
Thanks, Tom.
At 17:47 07/03/2000 +0800, James Henstridge wrote:
This may be a silly question, but have you imported CatalogAware from wherever it is defined, into the file where where the external method is? If not, try doing that.
James.
-- Email: james@daa.com.au WWW: http://www.daa.com.au/~james/
On Tue, 7 Mar 2000, Tom Deprez wrote:
def manage_afterAdd(self,item,container) item.myparent=container.id CatalogAware.manage_afterAdd(self,item,container) return
But then I get following error when adding an instance of the new class :
Zope Error
Zope has encountered an error while publishing this resource.
Error Type: NameError Error Value: CatalogAware
Troubleshooting Suggestions
This resource may be trying to reference a nonexistent object or variable CatalogAware. The URL may be incorrect. The parameters passed to this resource may be incorrect. A resource that this resource relies on may be encountering an error.
Urgh, I'm really desperate. Do you know what I'm doing wrong?
ps. Why does this function has to be an external method? Is it also possible with an DTML method?
Regards, Tom.
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org 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 )
participants (8)
-
David Kankiewicz -
Itamar Shtull-Trauring -
James Henstridge -
Loren Stafford -
Martijn Faassen -
Michel Pelletier -
Rik Hoekstra -
Tom Deprez