I’ve been working for the last year primarily on Zope3 relational applications, and have assembled various packages and practices for making them. I’ve recently begun publishing most of these packages as eggs to the cheeseshop, but I’ve had requests to give more examples of usage.
The first part of the process constructing a relational app, i engaged in was to remove the zodb. The primary reason for this was to remove zodb deployment considerations ( setting up zeo,etc) so that applications can be deployed easily via mod_wsgi, or have multiple front ends without any special setup of additional components.
The result of this was the ore.wsgiapp, originally it was just the output of a zopeproject paster template, modified to remove the ZODB startup. However, Jim Fulton refactored the zope.publisher that drives to include paste support and support for custom publications directly within it, greatly simplifying the process of setting up zope without the zodb.
Embracing WSGI
ore.wsgiapp constructs zope3 applictaions that areentirely driven by wsgi, there is no zope.conf file, only a paster config file for configuring an application and its components.
Installation
if your in a buildout just ore.wsgiapp to your eggs section.. or for the virtualenv/setuptools raw usage:
easy_install ore.wsgiapp
Constructing an application
First we need to define an object which implements IApplication, which will be the root of our published application, useful base classes for this purpose are in the ore.wsgiapp.app module:
from ore.wsgiapp import app class MyApplication( app.Application ): pass
now if we register this object as a utility it will be the root object published by zope. we’ll do this in zcml in a separate step.
Creating an application view
you will still need to do all the basics to register/provide views of this object. for the purposes of this example, we’ll add a basic view to echo hello world:
class AppView( object ): """ a simple view we register for the application """ def __init__( self,context, request): self.context = context self.request = request def __call__( self ): return "Hello World"
ZCML in Detail
so here’s a sample zcml to regiser the app as a utility, and include a basic zope3 environment.
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser"> <include package="zope.app.zcmlfiles" file="meta.zcml" /> <include package="zope.publisher" /> <include package="zope.traversing" /> <include package="zope.app.zcmlfiles" /> <!-- We override the default zope publisher request factory which expects a zodb --> <includeOverrides package="ore.wsgiapp"/> <!-- Application to publish --> <utility provides="ore.wsgiapp.interfaces.IApplication" factory="exampleapp.MyApplication" /> <!-- Default View for Test Application --> <browser:page name="index.html" for="ore.wsgiapp.interfaces.IApplication" class="exampleapp.AppView" permission="zope.Public" /> </configure>
Paste Configuration
To use with Paste, you include a configuration section like the following:
[app:zope] use = egg:ore.wsgiapp zcml = site.zcml
you can also turn on devmode here, for pdb post mortem debugging and template reloading. go ahead and save this file as debug.ini for the next step.
Running It
using a paster, its as simple as
./bin/paster debug.ini
and now we can visit our webserver to get a nice hello world
zope3 no zodb..
Application Initialization
Its often useful to defer application setup till after the application has finished loading its configuration, so that component architecture is fully configured. in order to allow for this, ore.wsgiapp generates a IWSGIApplicationCreatedEvent with the application as an attribute. we can register a subscriber for this in zcml, and it will be invoked after configuration is loaded.
As an example we’ll use an event subscriber to:
>>> from zope.app.component import site >>> from zope.app.container.sample import SampleContainer >>> >>> def appSetUp( app, eventevent ): """Initialize an application""" # setup a local site manager sm = site.LocalSiteManager( self.context ) self.context.setSiteManager( sm ) # add a folder app['news'] = SampleContainer()
Futures
using the zope.publisher.paste support added by jim fulton, currently ore.wsgiapp jumps through some hoops to use the existing wsgi support within zope.


