Re: [Zope3-Users] Specialized URL traversal.. Best way?
On Thu, Dec 29, 2005 at 11:22:28PM -0700, Jeff Shell wrote: > Again, this is to have URLs like: > > myapp/@@tags/zope/viewlet > > And turn that into a catalog search for anyof {'zope', 'viewlet'} > > def publishTraverse(self, request, name): > namestack = request.getTraversalStack() > if name not in namestack: > namestack.append(name) > namestack.reverse() > tags = tuple(namestack) > request.setTraversalStack([]) > > results = TaggedArticleFinder(self.__name__,self.__parent__,tags) > results.prepareSearch(request) > return results > > The 'TaggedArticleFinder' then provides an interface that a view can > be found for that displays the results. So I've got it all working > now... My coworker Albertas recently implemented something like this in SchoolTool (I've CCed him). Unfortunately it turned out to have some unforeseen consequences, for example, request.URL does not contain the path elements you "eat" manually, breaking self-posting forms (those that use ) and our login mechanism. > I was wondering - is this the best way to do this? Is there a better > recipe floating around out there? I would also like to know that. Marius Gedminas -- Any sufficiently advanced Operating System is indistinguishable from Linux. -- Jim Dennis signature.asc Description: Digital signature ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Container Constraints
Hi! I want to have container, witch should contain links and others containers of his own type! What I did is this in my interface-definition: class ILinkContainer(IContainer): """Basic folder, containing only links and other link folders.""" def __setitem__(name, object): """ Add an ITodo object. """ __setitem__.precondition = ItemTypePrecondition(ILink, ILinkContainer) But zope tells me: NameError: name 'ILinkContainer' is not defined I'm shure, he is right! It's a little bit of recursion at this place. But what to do? Creating a marker interface? Something like: class IMarker(IContainer): """ ... """ class ILinkContainer(IMarker): """Basic folder, containing only links and other link folders.""" def __setitem__(name, object): """ Add an ITodo object. """ __setitem__.precondition = ItemTypePrecondition(ILink, IMarker) Should work, but why creating a Interface "for nothing"? Must be a better way! And last but not least: Happy new Year! Bye Marcus Ertl ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Confused by ITraversable
I guess I don't understand traversal at all. I am trying to come up with the simplest possible class to exercise the ITraversable interface. Here's what I have: ### from zope.interface import implements from zope.app.traversing.interfaces import ITraversable class TravTestFlag(Exception): """Raise this flag when traverse() method gets called""" class TravTest(object): implements(ITraversable) def traverse(self, name, furtherPath): raise TravTestFlag("traverse got called in TravTest with name %s, furtherPath %s" % (name, furtherPath)) ### I hook it up to the ZMI with this configure.zcml: http://namespaces.zope.org/zope"; xmlns:browser="http://namespaces.zope.org/browser"; i18n_domain="travtest" > I create a TravTest object in my root folder with ID 'tt'. Then I browse http://localhost:8080/tt/1/2/3. I get a stock 404 error, which I guess means that TraversalError is getting raised someplace besides inside my traverse() method. I really expected to see a TravTestFlag. Any hints appreciated. -- Wade Leftwich Ithaca, NY ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: Get classes implementing Interface
Am Freitag, 30. Dezember 2005 20:57 schrieb Jeff Shell: > On 12/30/05, Florian Lindner <[EMAIL PROTECTED]> wrote: > > Am Freitag, 30. Dezember 2005 17:45 schrieb Jim Fulton: > > > Philipp von Weitershausen wrote: > > > > So, what you want is not a list of classes but a list of factories > > > > that can create IContainers. This is possible by using > > > > zapi.getUtilitiesFor(IFactory) and then checking each factory's > > > > getInterfaces() method whether IContainer is a part of the returned > > > > result. I would probably base an implementation of all on the > > > > UtilityVocabulary. > > > > > > I'll also note that the use case is also directly addressed through > > > containment constraints. You can say that a container > > > should only contain objects of some given types and you will get > > > just those types in the add list. > > > > But the HomeFolderManager is not a container itself it's just a utility > > that creates container upon requests. And I want to make choosable which > > container to create. Or do I misunderstand you? > > Well first (and I apologize if this has been mentioned before), > 'containers' are a more abstract notion while 'folders' are more > concrete. A message or document that allows comments might be a > container, but it's not something that you'd see in the ZMI or any > content management type interface as a folder. You'd see it as an > article. > > Something that's "Folderish" (to drag up an old term) will probably > have a folder icon, will probably (but not necessarily) will have > sub-folders, will have a view to manage its contents, and so on. [...] Basically the HomeFolderManager (HFM) only creates an 1:1 relation between a principal and an object. It can also auto-create these objects if the relation is being read for the first time. In this case the object to be created is hardcoded to be a zope.app.folder.Folder. The HFM does not care what is being done with the objects it just returns them. In my project I've another folderish object that I want to have created, therefore I forked the HFM and modified the code to create the object I want. Of course, the common use case would be to create a folderish object, but any other kind of objects would make sense to. A principal could have a home page (just one site) which is not folderish neither a IContainer which could the HFM return. Or a project which can contain comments, which is not folderis either but is an IContainer implemention. I think that the HFM should allow creation of ANY objects, regardless of being folderish or IContainer implemenations. Of course, the name HomeFOLDERManager would not make sense anymore in this case. What do you think? Florian I've included zope-dev in the recipients. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: Get classes implementing Interface
Does anyone got this mail? I've not received a copy from the mailinglists neither it shows up in the archives... Am Freitag, 30. Dezember 2005 20:57 schrieb Jeff Shell: > On 12/30/05, Florian Lindner <[EMAIL PROTECTED]> wrote: > > Am Freitag, 30. Dezember 2005 17:45 schrieb Jim Fulton: > > > Philipp von Weitershausen wrote: > > > > So, what you want is not a list of classes but a list of factories > > > > that can create IContainers. This is possible by using > > > > zapi.getUtilitiesFor(IFactory) and then checking each factory's > > > > getInterfaces() method whether IContainer is a part of the returned > > > > result. I would probably base an implementation of all on the > > > > UtilityVocabulary. > > > > > > I'll also note that the use case is also directly addressed through > > > containment constraints. You can say that a container > > > should only contain objects of some given types and you will get > > > just those types in the add list. > > > > But the HomeFolderManager is not a container itself it's just a utility > > that creates container upon requests. And I want to make choosable which > > container to create. Or do I misunderstand you? > > Well first (and I apologize if this has been mentioned before), > 'containers' are a more abstract notion while 'folders' are more > concrete. A message or document that allows comments might be a > container, but it's not something that you'd see in the ZMI or any > content management type interface as a folder. You'd see it as an > article. > > Something that's "Folderish" (to drag up an old term) will probably > have a folder icon, will probably (but not necessarily) will have > sub-folders, will have a view to manage its contents, and so on. [...] Basically the HomeFolderManager (HFM) only creates an 1:1 relation between a principal and an object. It can also auto-create these objects if the relation is being read for the first time. In this case the object to be created is hardcoded to be a zope.app.folder.Folder. The HFM does not care what is being done with the objects it just returns them. In my project I've another folderish object that I want to have created, therefore I forked the HFM and modified the code to create the object I want. Of course, the common use case would be to create a folderish object, but any other kind of objects would make sense to. A principal could have a home page (just one site) which is not folderish neither a IContainer which could the HFM return. Or a project which can contain comments, which is not folderis either but is an IContainer implemention. I think that the HFM should allow creation of ANY objects, regardless of being folderish or IContainer implemenations. Of course, the name HomeFOLDERManager would not make sense anymore in this case. What do you think? Florian I've included zope-dev in the recipients. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Specialized URL traversal.. Best way?
On 12/31/05, Marius Gedminas <[EMAIL PROTECTED]> wrote: > On Thu, Dec 29, 2005 at 11:22:28PM -0700, Jeff Shell wrote: > > Again, this is to have URLs like: > > > > myapp/@@tags/zope/viewlet > > > > And turn that into a catalog search for anyof {'zope', 'viewlet'} > > > > def publishTraverse(self, request, name): > > namestack = request.getTraversalStack() > > if name not in namestack: > > namestack.append(name) > > namestack.reverse() > > tags = tuple(namestack) > > request.setTraversalStack([]) > > > > results = TaggedArticleFinder(self.__name__,self.__parent__,tags) > > results.prepareSearch(request) > > return results > > My coworker Albertas recently implemented something like this in > SchoolTool (I've CCed him). Unfortunately it turned out to have some > unforeseen consequences, for example, request.URL does not contain the > path elements you "eat" manually, breaking self-posting forms (those > that use ) and our login > mechanism. Yeah, I know of that problem. Looking back, it looks like there have been a couple of ways of doing this. In Zope 2, there are a couple of prominent "cool path tricks" in the core content objects. Python Scripts allow you to get at the rest of the path. But the resulting affect is like you describe: the traversal stack is chopped off, and all URLs are relative to the script. We did a pretty cool ECommerce store in all Python Scripts and SQL Methods that did this to have URLs to products and categories, building up queries along the way. We quickly discovered that relative URLs didn't work in that scenario, so "./product/${product_id}" wouldn't work. I can see why it does this though - you didn't actually traverse to an object at that point in the path, so the request.parents attribute can't really have [, , , , , ] in it, when just takes the rest of the path and turns it into various script/object calls and queries. Zope 2 SQL Methods, on the other hand, allowed you do to direct traversal and turn a URL into a query. This may have even existed in the pre-principia version of Aqueduct. So for a two-category classified system you can do URLs like: /categorylist/category1_id/34/category2_id/12/list_ads.dtml What it does is actually create non-persistent traversable objects that implement the __bobo_traverse__ method. It accumulates the parts of the URL and somewhere along the way does the search. Acquisition binding and all of that still worked since the result was ultimately an object that was bound to the right parent. The code (In Zope 2: Shared/DC/ZRDB/DA.py, class Traverse) is rather old and cryptic, but it does provide an example of the other way of doing custom maps - traverse each name individually and create new objects along the way. This way, request.URL is not affected. If you were trying to make a custom traverser like date based archive searching and where at 2005/12/ in the url, you could then just have to go to the date. Both situations have their uses. They also have their consequences and side effects. Playing with the traversalStack seems fine when you don't need to do anything relative [per say] to the current URL. I almost always use URL generators, either absolute URL or in the case of the tags view I made I construct the joined URL in the view, so this hasn't affected me too much yet. But I'd certainly like to have the second option. The underlying tools are there, but knowing which traversal interface / adapter to apply isn't easy right now... Is __getitem__ enough? No one seems to have a good answer. IPublishTraverse? ITraversable? It seems like IPublishTraverse is the best one since it's from zope.publisher and not zope.app, and is specific to object / URL publishing. But that comes back to my dilemma: Is it cool to play with the traversal stack in publishTraverse? Why isn't 'furtherPath' part of the publishTraverse interface, but part of zope.app.traversing.interfaces.ITraversable's traverse? Why doesn't browser traversal seem to use zope.app...ITraversable? Oh man. Here it is, New Years Eve, I've got errands to run for my dog that I was going to go do an hour ago, yet here I sit consumed by an idea that I'd love to try but should put off to some other time. Basically it would be nice to specify a map... somehow.. for long URLs that are used to construct queries. A view object could use this map to match a URL piece by piece by traversing it one by one and making "proper" objects along the way that are locatable. When it gets to the end of the match, it could call a provided factory for that particular Map and pass in the matched URL since the start of the view as a list or mapping. This suite of tools could provide some map constructors that allow one to specify repeating path parts. The rest of the URL would still be in place, and maybe that final object could have more traversal happen after it, such as view getting. A quick example of what I'm thinking:
Re: [Zope3-Users] Container Constraints
First - you can use ``from zope.app.container.constraints import contains``. It's a bit easier to write. Anyways, in Python you can't reference the class you're in because that name, 'ILinkContainer' does not exist **until the end of the class statement** (after all of the things indented within the class). A common thing to do in Zope 3 to deal with this is to separate the container / containment constraints into separate interfaces. This gets around the issue stated above. It's also nice to use 'IContained' to say an object is contained (IContained defines the fields __parent__ and __name__), but if you use that as a base interface for something with a schema you're likely to see extra fields when using edit forms. So the container / containment constraints are usually put in a separate interface. It's a bit of a separate policy. For your situation, you may want to separate that into a separate marker interface that is then implemented by both Link and LinkContainer objects. from zope.app.container.interfaces import IContainer, IContained from zope.app.container.constraints import contains class ILinkContainerContainable(IContained): """ Declare support for this to be stored in an ILinkContainer """ class ILinkContainer(IContainer): """ A container that can contain LinkContainerContainable objects, like links and other link containers. """ # this does the same as the __setitem__.precondition stuff. contains(ILinkContainerContainable) And then in implementation: from zope.app.container.contained import Contained from interfaces import ILinkContainer, ILinkContainerContainable, ILink class Link(Persistent, Contained): implements(ILink, ILinkContainerContainable) class LinkContainer(WhateverYourContainerRootMightBe): implements(ILinkContainer, ILinkContainerContainable) Having this one interface, 'ILinkContainerContainable' (or whatever you choose) then allows you to add other objects in the future that could be contained, or you can have a RootLinkContainer that's a special class that is an ILinkContainer but not containable so you can't add it below the root: class RootLinkContainer(AgainWithTheRootClass): # Picks up the link container constraints, but since it doesn't add # ILinkContainerContainable, it can't be added to other link containers. implements(ILinkContainer) But just remember - without special tricks, you can't refer to a class while you're inside of it. class Foo: any statement at this level can't access Foo but this level can. On 12/31/05, Marcus J. Ertl <[EMAIL PROTECTED]> wrote: > Hi! > > I want to have container, witch should contain links and others > containers of his own type! What I did is this in my interface-definition: > > class ILinkContainer(IContainer): > """Basic folder, containing only links and other link folders.""" > > def __setitem__(name, object): > """ Add an ITodo object. """ > > __setitem__.precondition = ItemTypePrecondition(ILink, ILinkContainer) > > But zope tells me: > > NameError: name 'ILinkContainer' is not defined > > I'm shure, he is right! It's a little bit of recursion at this place. > But what to do? > > Creating a marker interface? Something like: > > class IMarker(IContainer): > """ ... """ > > class ILinkContainer(IMarker): > """Basic folder, containing only links and other link folders.""" > > def __setitem__(name, object): > """ Add an ITodo object. """ > > __setitem__.precondition = ItemTypePrecondition(ILink, IMarker) > > > Should work, but why creating a Interface "for nothing"? Must be a > better way! > > And last but not least: Happy new Year! > > Bye >Marcus Ertl > ___ > Zope3-users mailing list > Zope3-users@zope.org > http://mail.zope.org/mailman/listinfo/zope3-users > ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] problem Z3+cpsskins
Hi friends, i have a problem actually use cpsskins of svn.z3lab.org and the zope3 of svn (svn.zope.org), whenever I want to create a subject shows the following error: AttributeError: 'NoneType' object has no attribute 'newIdentifier' after looking for, the error occurs in this file http://svn.z3lab.org/z3lab/cpsskins/trunk/elements/__init__.py exactly here: == ... class Element(Contained): """An element""" implements(IElement) def __init__(self): from cpsskins.thememanager import getThemeManager tmutil = getThemeManager() #< self._identifier = tmutil.newIdentifier() #< ... == after proving I realize that this not giving back swum getThemeManager() only giving back a None, this not giving back a class, some idea? the cpsskins for zope3, with as version of zope3 it works? with the versión of svn? ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users