FAQ - Programming

Return to FAQ index

2   Is API documentation available online?

The Zope3 documentation infrastructure is powerful in that the html content is generated on the fly. This makes it somewhat slow while browsing on older machines.

A cached (and therefore fast) version of the docs are available online at: http://apidoc.zope.org/++apidoc++/

3   How do I check out a project/package from Zope subversion repository?

Ref: SettingUpAZope?3Sandbox

You can browse available projects here: http://svn.zope.org (in the package names, "zc" stands for "Zope Corporation", "z3c" stands for "Zope 3 Community")

Then, to check out Zope3 trunk anonymously:

svn co svn://svn.zope.org/repos/main/Zope3/trunk Zope3

Stable branches are available from : http://svn.zope.org/Zope3/branches (online) . And release tags from: http://svn.zope.org/Zope3/tags (online)

To check out Zope 3.3 stable branch:

svn co svn://svn.zope.org/repos/main/Zope3/branches/3.3 Zope33

4   How do I upgrade from one minor release to another?

Ref: http://mail.zope.org/pipermail/zope3-users/2006-August/004025.html

You can have more than one Zope 3 installed, e.g. you can install Zope 3.2.1 in parallel to 3.2.0 and switch your instance over to 3.2.1 (by editing the start scripts in $INSTANCE/bin). You can also install Zope 3.2.1 into the place where 3.2.0 was installed; your instance should continue to work. Such a thing isn't recommended when upgrading between major versions, though (3.2 to 3.3).

Note: this is even easier if you use an egg based infrastructure. However, learning how to use eggs in a realistic way, is a significant leap.

5   Must I always restart the zope server, when I modify my code?

Ref: http://mail.zope.org/pipermail/zope3-users/2006-September/004531.html

  • Yes, you have to restart the server, though we recommend writing unit tests that take a lot less time than starting Zope)
  • This probably isn't going to be implemented (it's very much non-trivial)
  • Significantly, you don't have to restart for changes in resources or Page Templates.

In the beginning, this seems like a huge annoyance - however, getting in the habit of writing unit and functional tests as you develop code will greatly alleviate this issue.

6   How do I automatically create some needed object at application startup?

http://mail.zope.org/pipermail/zope-dev/2007-December/030562.html

Do it by subscribing to IDatabaseOpenedWithRootEvent? (from zope.app.appsetup)

Example code:

from zope.app.appsetup.interfaces import IDatabaseOpenedWithRootEvent
from zope.app.appsetup.bootstrap import getInformationFromEvent
import transaction

@adapter(IDatabaseOpenedWithRootEvent)
def create_my_container(event):
    db, connection, root, root_folder = getInformationFromEvent(event)
    if 'mycontainer' not in root_folder:
        root_folder['mycontainer'] = MyContainer()
    transaction.commit()
    connection.close()

Then register this subscriber in your configure.zcml:

<subscriber handler="myapp.create_my_container" />

7   How do I validate two or more fields simultaneously?

Consider a simple example: there is a person object. A person object has name, email and phone attributes. How do we implement a validation rule that says either email or phone have to exist, but not necessarily both.

First we have to make a callable object - either a simple function or callable instance of a class:

>>> def contacts_invariant(obj):
...     if not (obj.email or obj.phone):
...         raise Exception("At least one contact info is required")

Then, we define the person object's interface like this. Use the interface.invariant function to set the invariant:

>>> class IPerson(interface.Interface):
...
...     name = interface.Attribute("Name")
...     email = interface.Attribute("Email Address")
...     phone = interface.Attribute("Phone Number")
...
...     interface.invariant(contacts_invariant)

Now use validateInvariants method of the interface to validate:

>>> class Person(object):
...     interface.implements(IPerson)
...
...     name = None
...     email = None
...     phone = None
>>> jack = Person()
>>> jack.email = u"jack@some.address.com"
>>> IPerson.validateInvariants(jack)
>>> jill = Person()
>>> IPerson.validateInvariants(jill)
Traceback (most recent call last):
...
Exception: At least one contact info is rquired

8   How do I get the parent of location?

To get the parent of an object use zope.traversing.api.getParent(obj). To get a list of the parents above an object use zope.traversing.api.getParents(obj).

9   How do I set content type header for a HTTP request?

From IRC (http://zope3.pov.lt/irclogs/%23zope3-dev.2006-06-20.log.html):

Is there any way using the browser:page directive, that I can
specify that the Type of a page rendered is not "text/html" but
rather "application/vnd.mozilla.xul+xml"?

Use request.response.setHeader('content-type', ...)

10   How do I give unique names to objects added to a container?

First:

from zope.app.container.interfaces import INameChooser

Name will be assigned from 'create' or 'createAndAdd' methods, here is an eg:

def create(self, data):
    mycontainer = MyObject()
    mycontainer.value1 = data['value1']
    anotherobj = AnotherObject()
    anotherobj.anothervalue1 = data['anothervalue1']
    namechooser = INameChooser(mycontainer)
    name = chooser.chooseName('AnotherObj', anotherobj)
    mycontainer[name] = anotherobj
    return mycontainer

11   How do I add a catalog programmatically?

Ref: http://zopetic.googlecode.com/svn/trunk/src/browser/collectorform.py

see this eg:

from zopetic.interfaces import ITicket
from zopetic.interfaces import ICollector
from zopetic.ticketcollector import Collector
from zope.app.intid.interfaces import IIntIds
from zope.app.intid import IntIds
from zope.component import getSiteManager
from zope.app.catalog.interfaces import ICatalog
from zope.app.catalog.catalog import Catalog
from zope.security.proxy import removeSecurityProxy
from zope.app.catalog.text import TextIndex

...

    def create(self, data):
        collector = Collector()
        collector.description = data['description']
        return collector

    def add(self, object):
        ob = self.context.add(object)
        sm = getSiteManager(ob)
        rootfolder = ob.__parent__
        cat = Catalog()
        rootfolder['cat'] = cat
        if sm.queryUtility(IIntIds) is None:
            uid = IntIds()
            rootfolder['uid'] = uid
            sm.registerUtility(removeSecurityProxy(uid), IIntIds, '')
            pass
        sm.registerUtility(removeSecurityProxy(cat), ICatalog, 'cat')
        cat['description'] = TextIndex('description', ITicket)
        self._finished_add = True
        return ob

12   Is there a function with which I can get the url of a zope object?

Ref: http://zope3.pov.lt/irclogs/%23zope3-dev.2006-09-25.log.html

Use:

zope.component.getMultiAdapter((the_object, the_request),
                                name='absolute_url')

or:

zope.traversing.browser.absoluteURL

13   How do I sort BTreeContainer objects?

Q:Is there a way to sort the objects returned by values() from a zope.app.container.btree.BTreeContainer instance?

Ref: http://zope3.pov.lt/irclogs/%23zope3-dev.2006-09-25.log.html

Use sorted builtin function (available from Python 2.4 onwards)

sorted(my_btree.values())

14   How do I extract request parameters in a view method?

Ref: http://mail.zope.org/pipermail/zope3-users/2006-July/003876.html

class MyPageView(BrowserView):

   def __call__(self):
      if 'myOperation' in self.request.form:
         param1 = self.request.form['param1']
         param2 = self.request.form['param2']
         do_something(param1, param2)

MyPageView? has to be either the default view associated to the 'mypage' object or a view called 'mypage' associated to the RootFolder? object.

Alternately, you could use:

class MyPageView(BrowserView):

   def __call__(self, param1, param2="DEFAULT"):
      if 'myOperation' in self.request.form:
         do_something(param1, param2)

15   How do I use Reportlab threadsafely?

Ref: http://mail.zope.org/pipermail/zope3-users/2006-September/004583.html

Use a mutex (a recursive lock makes things easier too):

lock = threading.RLock()
lock.acquire()
try:
   ...
finally:
   lock.release()

16   Why isn't my object getting added to the catalog?

Ref: http://mail.zope.org/pipermail/zope3-users/2006-May/003392.html

Is it adaptable to IKeyReference?? If you're using the ZODB, deriving from Persistent is enough.

17   How do I add custom interfaces to pre-existing components/classes?

Ref: http://mail.zope.org/pipermail/zope3-users/2006-November/004918.html

You can do so with a little zcml:

<class class="zope.app.file.Image">
    <implements interface=".interfaces.IBloggable" />
</class>

18   How do I get IRequest object in event handler ?

Q:How I can get IRequest in my event handler (I have only context)?

Ref: http://mail.zope.org/pipermail/zope3-users/2007-April/006051.html

import zope.security.management
import zope.security.interfaces
import zope.publisher.interfaces


def getRequest():
    i = zope.security.management.getInteraction() # raises NoInteraction

    for p in i.participations:
        if zope.publisher.interfaces.IRequest.providedBy(p):
            return p

    raise RuntimeError('Could not find current request.')

20   Where to get zope.conf syntax details ?

Refer: http://zope3.pov.lt/irclogs/%23zope3-dev.2008-04-01.log.html

Look at schema.xml inside zope.app.appsetup egg And this xml file can point you to rest of the syntax. for details about <zodb> look for component.xml in ZOBD egg



( 96 subscribers )