[Zope3-Users] Re: updating a zodb with a SchemaManager

2008-03-06 Thread Jürgen Kartnaller



Lorenzo Gil Sánchez wrote:

Hi,

I've been using a zope.app.generations.interfaces.ISchemaManager to keep
my database up to date with respect to the changes in the models of my
application and everything is well so far.

Now I have a tricky situation. My model had an attribute and now I
changed that attribute to be read only.

Before:
---

class IModel(Interface):

  attr1 = zope.schema.TextLine()

class Model(Persistent):
  implements(IModel)

  def __init__(self, attr1=None):
self.attr1 = attr1

After:
--

class IModel(Interface):

  attr1 = zope.schema.TextLine(readonly=True)
  attr2 = zope.schema.TextLine()

class Model(Persistent):
  implements(IModel)

  def __init__(self, attr2=None):
self.attr2 = attr2

  def _getAttr1(self):
return self.attr2.lower()
  attr1 = property(_getAttr1)

As you can see, now attr1 is a computed attribute from attr2.

When updating the old Model objects I add the 'attr2' attribute but I
can't remove the old 'attr1' attribute since is still defined in Model
but is a totally different thing.

I can forget about removing the 'attr1' attribute and things keep
working well. The problem is a waste of space in the database since that
information is still there but impossible to retrieve, right?

I have a related question: is attr1 still saved in the database in the
newer version no matter is a read only python property or does the ZODB
handle this case? As far as I know ZODB only skip those attributes
beginning with _v_ (for volatile), but don't know what it does with
python properties...

Has anyone ever reached a similar situation? Any solution?


You can do this on your instance :

 del obj.__dict__['attr1']

Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Any performance issues with the macro attribute in the z3c:template directive?

2008-03-06 Thread Jürgen Kartnaller

Andreas Johnsen wrote:

Hei all Zopers,

I find the macro parameter in the z3c:template very useful for working
with templates for viewlets and pagelets. I guess it's slower to extract
a html-snippet from within a page template file (by including a macro
parameter) then including the entire page template file (by not
including the macro parameter). 


So before implementing this technique on a large scale, I want to ask if
anyone have experienced any performance issues with this technique?


No, there is no performance issue on this. The TAL engine compiles the 
hole template into memory and caches it. Accessing a macro is just a 
dictionary lookup.

We are using this technique in large projects.

Jürgen

--
Lovely Systems, senior developer

phone: +43 5572 908060, fax: +43 5572 908060-77
Schmelzhütterstraße 26a, 6850 Dornbirn, Austria

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: How do you develop in zope 3?

2008-02-20 Thread Jürgen Kartnaller



[EMAIL PROTECTED] wrote:

Hello, *

How do you develop in zope 3?

First a few words:

After trying from time to time Zope 3 (X3, 3.0...) finally a month ago I
jumped in full time. Thanks to Philipp von Weitershausen's book, my
previous problems were solved. So I downloaded the zope 3 tar.gz and
started to practice... only to discover eggs, buildouts, paster and
friends (yes, pretty much I've been living under a programmer's rock).
Well, no problem. After reading http://pypi.python.org/pypi/zopeproject/
and http://pypi.python.org/pypi/zc.buildout I was on track again. So
basically, what I do is:

  # Create a virtual environment
  $ python2.4 bin/virtual-python.py --prefix=~/zope3/
  # install easy_setup
  $ ~/zope3/bin/python bin/ez_setup.py
  # Install zopeproject (of course, all these steps are made just once)
  $ ~/zope/bin/easy_install zopeproject
  # make the projects
  $ ~/zope/bin/zopeproject webdev

and then edit setup.py, buildout.cfg. and work in src/webdev. So long, so
fine. But here come my doubts:

*) Is it the way the experienced zope developers work? How do you set the
environment for a site or a package development?


Except for the zopeproject thing it is the way we work, edit the 
buildout.cfg and setup.py for the project needs. We also have a 
versions.cfg and nail all versions to the known working versions. Only 
update versions if really needed.



*) I'm working in more than a package. I'm developing a blog, a user
manager, etc. Should I create a new project for each package? How do I
include in my site (under development) my packages (under development)?


First of all each package should have it's full test environment to be 
able to developt the package independent of an application.


If you want to use the current develop version in you application just 
set the develop path to your local working copy of the package.



*) What recipe do you use to fetch a package via svn?


We have no need to fetch packages using svn, we only use eggs. As stated 
above if you need to use a local develop version of a package we 
temporarily add a develop path for that package.


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: how to model a 1-to-1 relation

2008-01-11 Thread Jürgen Kartnaller



john saponara wrote:
I want to allow the user to create car and driver objects in a 
limoService container.  Car objects will stand alone, but each driver 
object should contain a car object by reference (not by value) and the 
driver add form should allow the user to choose which car the new driver 
object will have.  Should IDriver's car attribute be a schema.Object or 
a schema.Choice?


Have a look at the package zc.relation and for a simple use of 
zc.relation use lovely.relation which provides relation properties for 
your objects.


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: how to model a 1-to-1 relation

2008-01-11 Thread Jürgen Kartnaller



Christophe Combelles wrote:

Jürgen Kartnaller a écrit :



john saponara wrote:
I want to allow the user to create car and driver objects in a 
limoService container.  Car objects will stand alone, but each driver 
object should contain a car object by reference (not by value) and 
the driver add form should allow the user to choose which car the new 
driver object will have.  Should IDriver's car attribute be a 
schema.Object or a schema.Choice?


Have a look at the package zc.relation and for a simple use of 
zc.relation use lovely.relation which provides relation properties for 
your objects.


What is zc.relation compared to zc.relationship?


Of course I meant zc.relationship

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: How to add additional layers to skin?

2008-01-04 Thread Jürgen Kartnaller

xin ni wrote:

Hi,  dear all,

I am using zope 3.3.1
As ZCML browser:skin is deprecated, how to add addtional  layers to an 
existing skin?


interface
interface=IYourLayerInterface
type=zope.publisher.interfaces.browser.IBrowserSkinType
name=YourSkinName
/

Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: lovely.tag behaviour

2007-12-25 Thread Jürgen Kartnaller



Maken Seteva wrote:

Hi!
I am a bit curious about the behavior of the tagcount when tagging with 
lovely.tag. Here is a snip from my doctest:



Nothing initially
 sorted(e.getCloud(users=[u'barney']))
[]

Update tags for barney
 e.update(1000, u'barney', [u'foo'])
 e.update(1000, u'barney', [u'foo', u'bar'])

Print them
 sorted(e.getCloud(items=(1000,), users=(u'barney',)))
[(u'bar', 1), (u'foo', 2)]

Update and print again:
 e.update(1000, u'barney', [u'eggs'])
 sorted(e.getCloud(items=(1000,), users=(u'barney',)))
[(u'eggs', 1)]


This is exactly the expected behaviour it is described in the engine 
interface :


class ITaggingEngine(zope.interface.Interface):
Manangement and Querying of Tags.

Tags are small stickers that are specific to an object to be tagged
and the user tagging the object.


def update(item, user, tags):
Update the tagging engine for an item and user and its tags.

The item must be an integer, the user can be a string and the
tags argument must be an iterable of tag names (strings).

This method always overwrites the old tag settings. However,
existing tags will not be readded and are just skipped.





My first thing i notice is that there is no concept of 'updating' a 
users tags on an object in the sense that first you add a tag then later 
you add another tag  with the old one being untouched (the tag count for 
the old one not being incremented every time i update!). Is there a 
special reason for this philosophy?


The way this function works is very convenience, because usually you 
have a user editing his tags. The you just take the edited list of tags 
and use update to update the tagging engine.



Regards
Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Configuring a package to use a file in buildout

2007-11-23 Thread Jürgen Kartnaller


In your buildout you do :

[instance]
recipe = zc.zope3recipes:instance
application = app
address = 8080
zope.conf =

  product-config my-config-name
storagedir ${buildout:directory}/parts/log
  /product-config


If you need the log dir precreated you do :

[extfiledir]
recipe = lovely.recipe:mkdir
path = parts/log


To access the product config from python :

from zope.app.appsetup.product import getProductConfiguration

config = getProductConfiguration('my-config-name')
if config is not None:
path = config.get('logpath')


Use your utility name as my-config-name.


Jürgen

Darryl Cousins wrote:

Hi,

I have a custom logger in a package registered with utility

zope:utility  factory=.logger.MyLogger name=logger /

In the code it sets itself a logfile to write to, up to now that has
been in a 'log' directory in the package itself.

Now I want to use a log file which is in the buildout of the
application. How could I go about finding that directory from python
code in the package?

The only route that I have come up with so far is to write a
meta:directive which I can use to register the logging utility with a
file path. Something like:

  meta:directive
  namespace=http://namespaces.zope.org/rdb;
  name=provideLogger
  schema=.zcml.IProvideLoggerDirective
  handler=.zcml.loggerhandler
  /

Which I could use like

  provideLogger component=.logger.MyLogger
 log=/path/to/log/file /

But there may be a better/easier way. Suggestions?

Regards,
Darryl


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Buildout recipe to create config file from contents in buildout.cfg?

2007-09-29 Thread Jürgen Kartnaller

Derek Richardson wrote:
 I am using hexagonit.recipe.cmmi to install pound (www.apsis.ch/pound)
 in front of zope. After I cmmi, I need to install a config file. I'd
 like to include the pound config file in buildout.cfg, like the zcml
 section in zc.zope3recipes:application. Is there a simple recipe for
 making a file out of a section in the buildout.cfg and putting it in a
 particular place? Or is there a 'best' recipe to use to get close? Or is
 this a reason to write a new recipe from scratch and contribute it? I
 see this simple functionality as having many use cases.

Hi Derek,
this is how we setup our nginx with buildout in front of zope:

[nginx]
recipe = zc.recipe.cmmi
url = http://sysoev.ru/nginx/nginx-0.5.31.tar.gz
extra_options = --with-poll_module


[nginx-ctl]
recipe = lovely.recipe:mkfile
path = ${buildout:bin-directory}/nginx
mode = 0755
content =
 #!/bin/sh
 PIDFILE=${nginx:location}/logs/nginx.pid
case $1 in
  start)
   ${nginx:location}/sbin/nginx -c 
${buildout:directory}/src/lovelybooks/nginx.conf

;;
  stop)
kill -QUIT `cat $PIDFILE`
;;
  reload)
kill -HUP `cat $PIDFILE`
  ;;
  restart|force-reload)
$0 stop
sleep 1
$0 start
;;
  *)
echo Usage: $SCRIPTNAME 
{start|stop|restart|reload|force-reload} 2

exit 1
;;
esac

Here we create a start script using lovely.recipe.mkfile .

lovely.recipe also containe mkdir to create a directory.

Hope this helps.

Jürgen




Thanks,

Derek


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Strange ZODB error - Solved: Zalchemy bug

2007-08-13 Thread Jürgen Kartnaller

I don't think the recent change to the utility is correct.

Because the engine property is now volatile it needs to be recreated any 
time the utility is garbage collected.


Maybe that's the reason for these strange things to happen.

Jürgen


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Still trying to connect to ZODB from external

2007-05-09 Thread Jürgen Kartnaller

Florian,
you should definitely have a look at the package zc.async and/or 
lovely.remotetask.
lovely.remotetask is in heavy use in our applications and contains a 
scheduler like the scheduler provided in zope.


Jürgen

Florian Lindner wrote:

Hello,
I have a function called by a scheduler. Since it operates outside of Zope 
context I need to create a connection to the ZODB in order to call a utility:


db = getUtility(ZODB.interfaces.IDatabase)
conn = db.open()
root = conn.root().data['Application']
   
zope.app.component.hooks.setSite(root[cs])

utils = getUtilitiesFor(INewsfeed)

for i in utils:
print Utility called:, i[0]
i[1].sendNotification()
   
conn.close()


This produces errors like:

Unhandled error in Deferred:
Traceback (most recent call last):
  File /home/florian/Zope3/src/twisted/internet/posixbase.py, line 220, in 
run

self.mainLoop()
  File /home/florian/Zope3/src/twisted/internet/posixbase.py, line 228, in 
mainLoop

self.runUntilCurrent()
  File /home/florian/Zope3/src/twisted/internet/base.py, line 561, in 
runUntilCurrent

call.func(*call.args, **call.kw)
  File /home/florian/Zope3/src/twisted/internet/task.py, line 108, in 
__call__

d = defer.maybeDeferred(self.f, *self.a, **self.kw)
--- exception caught here ---
  File /home/florian/Zope3/src/twisted/internet/defer.py, line 107, in 
maybeDeferred

result = f(*args, **kw)
  File /home/florian/Desktop/zope/lib/python/CS/centershock/centershock.py, 
line 34, in releaseRefreshEvent

conn.close()
  File /home/florian/Zope3/src/ZODB/Connection.py, line 268, in close
raise ConnectionStateError(Cannot close a connection joined to 
ZODB.POSException.ConnectionStateError: Cannot close a connection joined to a 
transaction


What is the right way to do it?

Thanks,

Florian


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: getting random results out of a catalogs field index

2007-05-05 Thread Jürgen Kartnaller



Dominique Lederer wrote:

Christian Theune wrote:

Am Samstag, den 05.05.2007, 17:42 +0200 schrieb Dominique Lederer:

hi

i would like to retrieve a number of *random* entries out of a catalogs field 
index.

i tried it with first getting the catalogindex-length an then accessing a
randomized list-index, but this is very slow, because of the large number of
entries in the index.

do you know any better solution?
I'm kind of guessing here. 


You say you are:

- querying the catalog
- accessing a random index from the result set
- noticing that this is slow

Does this only happen if the index is very large, e.g. you're retrieving
an element from the end of the result set?

I don't know exactly how the result sets are organized, but this
behaviour would imply that loading a later element triggers something
like loading the earlier elements too. I can't really imagine that.

I think the general problem that this is slow lies in the fact that
randomly selecting elements means 


a) you need access to the full list of things
b) applying a sort 


Sorting has a complexity of at least O(n log n) which becomes slow
enough for large sets that it's noticable.

BTW: How large is large?

Christian



hi, thanks for the reply, i just managed to improve the performance of my query
significantly:

what i wanted to do was:

- retrieve the len() of the catalog index
- retrieve a list() of the Resultset
- accessing n random results and their objects

to retrieve a random object i did:

query = catalog.apply({'myIndex':(None,None)})
length = len(query)
index_intids = list(query)
intid = all[random.randint(0,len_all-1)]
object = getObject(intid)

which was with 1 items in the index slow (i had to wait 2-3 seconds for a
view to render)

after looking into the field index implementation i changed the above lines to:

length = len(catalog['myIndex']._rev_index)


If you are using FieldIndex use

length = catalog['myIndex'].documentCount()

The FieldIndex holds a counter with the number of entries in the _rev_index.


index_intids = list(catalog['myIndex']._rev_index.keys())

which now works like a charm.

i am not an expert with BTrees so i cant really say what the problem is/was.


len on a btree is slow because it needs to iterate over all keys to 
count them!



If possible always avoid using the catalog and use the index directly, 
it is much faster!


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Zope 3 port of Zope 2 Scheduler product?

2007-04-22 Thread Jürgen Kartnaller

Hi Scott,
I added cron job-like behavior to lovely.remotetask.

I'm using it to fire events a specific times.
If I find some time I will add a generic task which allows to fire a 
configurable event.


Jürgen

Scott Deerwester wrote:

Has anyone ported the Scheduler product to Zope 3? Scheduler
(http://cvs.zope.org/Products/Scheduler) allows you to post events that
are fired at some specific time in the future. It uses the Events
product, which has been superceded by Zope 3 events. Seems like a very
useful thing to have as part of Zope 3, which makes me wonder if
somebody's already done the heavy lifting...


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: EditForm fails in SiteManager because of containment constraint

2007-04-07 Thread Jürgen Kartnaller

Christophe Combelles wrote:

Hello,

I have a regular content object which uses the formlib for its edit view.
Nothing special, just like a Recipe.
But I want this object to only reside in the Site Manager, because it 
will be used as a configurable local utility (some kind of 
LocalKitchenTools utility)


Everything is perfect, and the EditForm works well until I want to tell 
this object to be only contained in the SiteManager. So I just add this 
statement in the interface:


containers(ILocalSiteManager)
or
containers(ISiteManagementFolder)


'container' adds __parent__ as schema.Field attribute to your interface.
You need to omit __parent__ in your formlib form_fields definition.

Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: RFC 4122 UUIDs

2007-04-06 Thread Jürgen Kartnaller

Stephan Richter wrote:

On Thursday 05 April 2007 15:28, Jürgen Kartnaller wrote:

Please do not use an annotation!

This is a performance issue. Your data is very small so do not create a
new object in the database store it directly as a property on the
instance. Every object lookup is expensive, especially if you use ZEO!


Hey Juergen, come on! I know you guys are on an optimization trip at Lovely, 
but this is great information to store on an annotation. The UUID does not 
usually need to be looked up and is mainly for external world reference, such 
as feeds like Derek metioned he wanted.


The package is also an add-on. You don't need it, then do not use it. As 
further optimization, Derek mainly needs this id for a very specific set of 
content types, so I would narrow the subscriber to only give those special 
types a UUID.


I know, everything starts simple, I remember last year when we used our 
sample data with 12 users and 500 books, now we have 1200 users and 
10 books (35 objects registered in the intid utility) in the 
production system and this is just the beginning.


The simple thing is now a complex one and performance is an issue 
everywhere.


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: RFC 4122 UUIDs

2007-04-05 Thread Jürgen Kartnaller



Derek Richardson wrote:

Martin Aspeli wrote:



Derek Richardson-2 wrote:

Martin Aspeli wrote:


Stephan Richter-2 wrote:

On Wednesday 04 April 2007 13:06, Derek Richardson wrote:
I am hoping that Zope 3 assigns an RFC 4122 UUID to each content 
item.

If not, I am hoping there is a third-party product to do this.

No there is neither. We have an intid utility that guarantees
System-wide unique ids. This utility is used at several places most 
notably the

catalog.


I would like RFC 4122 UUIDs to provide standard Atom feeds of Zope
content [1].

It will be better if Zope itself assigns UUIDs, so that there is a
single source and not a possibility of multiple packages assigning
different UUIDs to the same content item.

You have to write your own utility to generate the UUID. I checked the
RFC quickly and our IntIds are certainly not of the format 
requested by RFC

4122.

Presumably, the intid implementation would be a useful reference for 
such

a
utility, and this would a good canidate for a general, re-usable 
package.


Martin

Good. I would like to write it as a general, re-usable package.

Generating RFC 4122 UUIDs is easy - there's a routine for it in the 
python 2.5 standard libraries and a python 2.3+ version here:


http://zesty.ca/python/uuid.html

What seems more difficult is how to plug the routine in so that all 
content items receive one and only one UUID upon creation. Maybe 
listen for IObjectCreatedEvent and annotate then? Or is there a 
potential race condition that means events are not the way to go?


(Unsure of the depths of Zope 3's architecture)



Look at zope.intid; it should be IObjectCreatedEvent or 
IObjectAddedEvent.


Martin



I have started coding a uuid package for Zope. zope.intid uses 
IObjectAddedEvent; I plan to as well.


However, the uuid differs from the intid in that I want to store the 
uuid on the object, rather than in a utility. This will ensure that 
uuids travel with their objects without having to modify import/export 
or other code. My initial idea is to use an annotation, but I'm not sure 
this is right. I'll have to annotate all the content classes in the 
system, which seems to be a *huge* zcml pain. Any advice for avoiding this?




Please do not use an annotation!

This is a performance issue. Your data is very small so do not create a 
new object in the database store it directly as a property on the 
instance. Every object lookup is expensive, especially if you use ZEO!


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: lovely.remotetask question

2007-04-04 Thread Jürgen Kartnaller



Maciej Wisniowski wrote:

For startup do this :

@component.adapter(IDatabaseOpenedEvent)
def startRemoteTask(event):
Start the amazon remotetask on startup.
db = event.database
connection = db.open()
root = connection.root()
root_folder = root.get(ZopePublication.root_name, None)
for site in root_folder.values():
service = component.queryUtility(
ITaskService, context=site)
if service is not None:
if not service.isProcessing():
service.startProcessing()

I assume here that the remote tasks are located in one of the site
directly contained in root.

Works for me now :)


For shutdown :

I have no solution for this right now.

So seems that now it is best to manually click on stop processing button
via
ZMI before shutting Zope down.


Or use zopectl start/stop.

Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: lovely.remotetask question

2007-04-03 Thread Jürgen Kartnaller



Maciej Wisniowski wrote:

Hi

I want to use lovely.remotetask in Z3 application.
Use case is very simple:
User views page, this causes long running function to be started
and Ajax calls from the page check every second if there is a result.

I have:
1. content object (Folderish) with instance of remotetask.TaskService()
called 'monitor_service' inside

2. mytask = remotetask.task.SimpleTask(myLongRunningFunction)

3. named utility for 'mytask'

The question is how should I start and stop remotetask jobs?
Currently, when user enters a page I call (every time):

jobid = self['monitor_service'].add(u'mytask', appdict)
self['monitor_service'].startProcessing()

Then ajax is repeadetly checking for result and when
status is Completed I call

self['monitor_service'].stopProcessing()

It works nice, but after looking into service.py code I see
it will break when I'll have few concurrent users.

Seems that I should call startProcessing() on zope startup
and stopProcessing on zope shutdown?


For startup do this :

@component.adapter(IDatabaseOpenedEvent)
def startRemoteTask(event):
Start the amazon remotetask on startup.
db = event.database
connection = db.open()
root = connection.root()
root_folder = root.get(ZopePublication.root_name, None)
for site in root_folder.values():
service = component.queryUtility(
ITaskService, context=site)
if service is not None:
if not service.isProcessing():
service.startProcessing()

I assume here that the remote tasks are located in one of the site 
directly contained in root.



For shutdown :

I have no solution for this right now.

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: ZAlchemy demos (z3c.zalchemy) - Unknown directive: engine

2007-03-06 Thread Jürgen Kartnaller



Stefan Krumbiegel (Galileo Press) wrote:
I installed Zope3 
(http://www.zope.org/Products/Zope3/3.3.1/Zope-3.3.1.tgz) and 
z3c.zalchemy from the repository (http://svn.zope.org/z3c.zalchemy/trunk/).

I followed the steps in the README.txt to try the ZAlchemy demos...

An error occured while starting the Zope3 instance:

zope.configuration.xmlconfig.ZopeXMLConfigurationError: File 
/web/zope3_instance_worldcookery/etc/site.zcml, line 7.2-7.55
ZopeXMLConfigurationError: File 
/web/zope3_instance_worldcookery/etc/package-includes/z3c.zalchemy.demo-configure.zcml, 
line 2.0-2.46
ZopeXMLConfigurationError: File 
/usr/local/lib/python2.4/site-packages/z3c.zalchemy-trunk-py2.4.egg/z3c/zalchemy/demo/demo_1/configure.zcml, 
line 8.2
ConfigurationError: ('Unknown directive', 
u'http://namespaces.zalchemy.org/alchemy', u'engine')


I'm almost 100% sure you need to add z3c.zalchemy-configure.zcml and 
z3c.zalchemy-meta.zcml to your package-includes.


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: NotYet error when creating content during container creation

2007-02-25 Thread Jürgen Kartnaller



Christophe Combelles wrote:

Hello,

I've been spending several hours on a problem which is probably trivial 
for advanced zope3ers, but it was not for me, so I'm posting the 
solution in case it's useful for someone (I've not found anything on it).




http://mail.zope.org/pipermail/zope3-users/2005-November/001494.html



The problem:
I want to create a folder, and when this folder is created, several 
subfolders should be automatically created.  And I have a IntId utility. 
(this is part of the problem).


First, I've tried to create the subfolders in the __init__ method of the 
folder being created. It does not work and fails with a NotYet error.


Then, I've tried to create the subfolders in the create method of the 
AddForm, after the folder has been eventually created. Still too early: 
NotYet error.


I've also tried to create the subfolders in a subscriber on 
IObjectCreatedEvent, but this is equivalent to the previous attempt : 
NotYet error.


What I've understood is that the transaction that manages the folder is 
not finished, and the IntId utility is not yet able to get a connection 
on the ZODB. So I've tried to create an adapter to IConnection for my 
subfolder, so that it can use the same connection as the folder. But I 
couldn't. (however it might be possible?).


'NotYet' happens if the object in not connected to a database. The 
connection to the database exists as soon as your object is added to the 
object tree in zope. It is not related to a finished transaction.




The simple solution is to create the subfolders AFTER the folder has 
been eventually ADDED with the add method. So in the AddForm, I've 
replaced the create() method with a createAndAdd method. In this method, 
I've just created my folder, called add to add it, then only I could 
create the subfolders and add them to the folder.


You can also do this using an event handler for ObjectAddedEvent on your 
Folder. In this case you do not need to touch any code in your form.


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Configure.zcml In Hello World Video On WorldCookery.Com Doesn't Work

2007-02-16 Thread Jürgen Kartnaller



Robert Hicks wrote:

Mark, Jonathan (Integic) wrote:
Here is my configure.zcml file, which is identical to the one Paul 
Everitt says to write:


configure xmlns=http://namespaces.zope.org/browser;

page
   name=hello
   template=helloworld.html
 for=zope.app.container.interfaces.Icontainer
   permission=zope.Public /

/configure



XML is case sensitive Icontainer should be IContainer...

It's not XML that is case sensitive, it is python !
You get the same error if you try to import Icontainer in python (what 
 the zcml directive is actually doing).


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Can't find MessageIDFactory

2007-02-09 Thread Jürgen Kartnaller



George Wright wrote:

Gidday zope3 users

I have been working through the Weitershausen Zope3 book (first edition) 
and came to stuff on Message IDs and translation domains. 
I can't import MessageIDFactory (page 125)!


  from zope.i18nmessageid import MessageIDFactory

maybe it should be MessageFactory

Juergen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: broken formlib - form.txt example

2007-02-06 Thread Jürgen Kartnaller

Vinny,
why not using form.Form to derive from :

class MyForm(form.Form):
form_fields = form.Fields(IOrder, omit_readonly=True)

Register this as a page and you are up and running.

Jürgen


Vinny wrote:

Hello,

Platform details:

# pkg_info | grep zope
zope-3.3.0  An object-based web application platform
# uname -a
FreeBSD the.palaceofretention.ca 6.2-RELEASE #1:
# python
Python 2.4.3 (#2, Dec 26 2006, 16:13:56)
[GCC 3.4.4 [FreeBSD] 20050518] on freebsd6

Using IDLE 1.1.3

Using instructions from:
/usr/local/www/Zope3/lib/python/zope/formlib/form.txt

With code straight out of it typed into the IDLE editor, saved
as form.py and run using the F5 command:

=== 8 
from zope import interface, schema
class IOrder(interface.Interface):
identifier = schema.Int(title=uIdentifier, readonly=True)
name = schema.TextLine(title=uName)
min_size = schema.Float(title=uMinimum size)
max_size = schema.Float(title=uMaximum size)
now = schema.Datetime(title=uNow, readonly=True)

from zope.formlib import form
class MyForm:
form_fields = form.Fields(IOrder)

#This sets up a set of form fields from the interface, IOrder.

print len(MyForm.form_fields)

print [w.__name__ for w in MyForm.form_fields]

class MyForm:
form_fields = form.Fields(IOrder, omit_readonly=True)

def __init__(self, context, request):
self.context, self.request = context, request

def __call__(self, ignore_request=False):
widgets = form.setUpWidgets(
self.form_fields, 'form', self.context, self.request,
ignore_request=ignore_request)
return '\n'.join([w() for w in widgets])

from zope.publisher.browser import TestRequest
request = TestRequest()
print MyForm(None, request)() # doctest: +NORMALIZE_WHITESPACE

Saving and running this gives: 


=== RESTART 


5
['identifier', 'name', 'min_size', 'max_size', 'now']

Traceback (most recent call last):
  File /usr/local/www/Zope3/mv/lib/python/hello/form.py, line 33, in
-toplevel-
print MyForm(None, request)() # doctest: +NORMALIZE_WHITESPACE
  File /usr/local/www/Zope3/mv/lib/python/hello/form.py, line 28, in
__call__
ignore_request=ignore_request)
  File /usr/local/www/Zope3/lib/python/zope/formlib/form.py, line
256, in setUpWidgets
IInputWidget)
  File /usr/local/www/Zope3/lib/python/zope/component/_api.py, line
103, in getMultiAdapter
raise ComponentLookupError(objects, interface, name)
ComponentLookupError: ((zope.schema._bootstrapfields.TextLine object
at 0x8cf53cc, zope.publisher.browser.TestRequest instance
URL=http://127.0.0.1), InterfaceClass
zope.app.form.interfaces.IInputWidget, u'')


Sigh.  Am I jinxed?  I've been trying to learn zope 3 for six
months now.  All I want is to be able to make a form from an
interface and display the dang thing.  Is that too much to
ask?  /rant

Does anyone know what's going wrong?  Do I need to upgrade
anything?

Thanks in advance.

Vinny


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: register and unregister Utility

2006-12-27 Thread Jürgen Kartnaller

component.provideUtility for a global utility.

See zope.component.interfaces.IComponentRegistrationConvenience


Or for local utilities registered in a site manager you use the site 
manager :


sm.registerUtility
sm.unregisterUtility

See zope.component.interfaces.IComponentRegistry

Jürgen


Florian Lindner wrote:

Hello,
easy question but I just don't finde the approbiate function. How to register 
and unregister programmatically an utility?


Thanks,

Florian


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: register and unregister Utility

2006-12-27 Thread Jürgen Kartnaller



Florian Lindner wrote:

Am Mittwoch, 27. Dezember 2006 19:15 schrieb Jürgen Kartnaller:

component.provideUtility for a global utility.


I've found that.


See zope.component.interfaces.IComponentRegistrationConvenience


Ok, for registering. But what to call for unregistering? (I have a global 
utility)


zope.component.getGlobalRegistry() implements IComponentRegistry




Or for local utilities registered in a site manager you use the site
manager :

sm.registerUtility
sm.unregisterUtility

See zope.component.interfaces.IComponentRegistry


Ok, there is the unregisterUtility function. Where do I get an object 
implementing this interface?


sm = site.getSiteManager()



Thanks,

Florian


Jürgen

Florian Lindner wrote:

Hello,
easy question but I just don't finde the approbiate function. How to
register and unregister programmatically an utility?

Thanks,

Florian

___
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] Re: proxied list object in a schema

2006-12-17 Thread Jürgen Kartnaller

Hi Tim,
Chat must implement IChat

Jürgen

Tim Terlegård wrote:

Would someone like to explain how to use a list in a schema object
without getting ForbiddenAttribute? This is my use case.

class IChat(Interface):
messages = Attribute('Chat messages')

class Chat(Persistent):
def __init__(self):
self.messages = persistent.list.PersistentList()

class class=.chat.Chat
require permission=zope.View interface=.interfaces.IChat /
require permission=zope.View set_schema=.interfaces.IChat /
/class

I have a Chat class that implements IChat and that is declared in
configure.zcml. Both the chat object and the 'messages' attribute are
proxied automatically, right? The require / tags in configure.zcml
adds security declarations to the chat object, but not to the 'messages'
attribute. Am I correct this far?

When I call self.context.messages.append(...) (in a browser page for
IChat) I get ForbiddenAttribute on append. I should get this, so this
is ok. But list or PersistentList has no interface I can use in IChat
instead of Attribute. So I tried using zope.schema.List instead, but
the interface of that was a small subset of what list provides and
doesn't have append either. So I don't know how to add these security
declarations to the 'messages' attribute.

How can I use a list without getting security proxy problems? Do I have
to make my own list implementation and interface?

Tim


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: exploring Zalchemy

2006-11-06 Thread Jürgen Kartnaller

Hi Catonano.

What version of SQLAlchemy are you using ?

I haven't had a look at SQLAlchemy the last 3 month. Maybe something has 
changed in SQLAlchemy.


If you look at the code in AlchemyEngineUtility.getEngine you see that 
the engine returned is the plain engine from SQLAlchemy.


It seems that the problem is not in ZAlchemy.

Regards
Jürgen

catonano wrote:

Hello people, hello Jurgen,

last time I wrote, I was at the point that aTable = 
sqlalchemy.Table('aTable', z3c.zalchemy.metadata, autoload=True)
doesn't work. I also promised that I would have seen if I could help 
with that; Sorry I still can't help.


I would love to succeed in zopezing my MySql database, before anything 
else.


So I tried to use the example in the zalchemy readme file as it is. It 
doesn't work either !


Please help me !
The work session follows.

PyCrust 0.9.5 - The Flakiest Python Shell
Python 2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit (Intel)] on 
win32

Type help, copyright, credits or license for more information.
  import sqlalchemy
  import z3c.zalchemy
  from z3c.zalchemy.datamanager import AlchemyEngineUtility
  engineUtility = 
AlchemyEngineUtility('tender','mysql:///root:[EMAIL PROTECTED]/tender',echo=False) 


  aTable = sqlalchemy.Table('zalch',
... z3c.zalchemy.metadata,
... sqlalchemy.Column('id', sqlalchemy.Integer,
... sqlalchemy.Sequence('atable_id'), primary_key=True),
... sqlalchemy.Column('value', sqlalchemy.Integer),
... redefine=True)
  class A(object):
... pass
...
  sqlalchemy.mapper(A, aTable) is not None
True
  from zope.component import provideUtility
  provideUtility(engineUtility)
  z3c.zalchemy.createTable('zalch')
  import transaction
  txn = transaction.begin()
  session = z3c.zalchemy.getSession
  session()
[2006-11-05 14:53:19,500] [pool]  : Error on connect(): (Connection 
failed) (OperationalError) (1045, Access denied for user 
'ODBC'@'localhost' (using password: NO))

sqlalchemy.orm.session.Session object at 0x0200D990
 

It tries to connect to MySql with [EMAIL PROTECTED] usng password: no

But the engineUtility I created had a completely different URL ! Maybe I 
wrote the url incorrectly ?

Also a simpler url gives the same url.

Look at this

Py 0.9.5
Python 2.4.3 (#69, Mar 29 2006, 17:35:34) [MSC v.1310 32 bit (Intel)] on 
win32

Type help, copyright, credits or license for more information.
import sqlalchemy
import z3c.zalchemy
from z3c.zalchemy.datamanager import AlchemyEngineUtility
engineUtility = AlchemyEngineUtility('tender', 'mysql:///[EMAIL PROTECTED]')
eng = engineUtility.getEngine()
eng.connect()
[2006-11-06 01:04:57,983] [pool]  : Error on connect(): (Connection 
failed) (OperationalError) (1045, Access denied for user 
'ODBC'@'localhost' (using password: NO))

Traceback (most recent call last):
  File input, line 1, in ?
  File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 477, in 
connect
  File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 179, in 
__init__
  File build\bdist.win32\egg\sqlalchemy\engine\base.py, line 500, in 
raw_connection
  File build\bdist.win32\egg\sqlalchemy\engine\default.py, line 42, in 
get_connection

  File build\bdist.win32\egg\sqlalchemy\pool.py, line 95, in connect
  File build\bdist.win32\egg\sqlalchemy\pool.py, line 172, in __init__
  File build\bdist.win32\egg\sqlalchemy\pool.py, line 108, in get
  File build\bdist.win32\egg\sqlalchemy\pool.py, line 294, in do_get
  File build\bdist.win32\egg\sqlalchemy\pool.py, line 91, in 
create_connection

  File build\bdist.win32\egg\sqlalchemy\pool.py, line 131, in __init__
  File build\bdist.win32\egg\sqlalchemy\pool.py, line 155, in __connect
  File build\bdist.win32\egg\sqlalchemy\engine\default.py, line 33, in 
connect
DBAPIError: (Connection failed) (OperationalError) (1045, Access denied 
for user 'ODBC'@'localhost' (using password: NO))


What's wrong with these sessions ?

Thanks so much for any hint
Bye
Catonano


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: viewtemplate

2006-10-29 Thread Jürgen Kartnaller

Hi Jakub.

eXt wrote:

Hi all

  I recently read Stephan Richter's blog post: 
http://blogs.lovelysystems.com/srichter/2006/09/20/the-skin-browser-and-lovely-systems-new-development-workflow 
and intendent scope of viewlets thread: 
http://thread.gmane.org/gmane.comp.web.zope.zope3.user/4652/focus=4652.


I like the idea behind viewtemplate very much (separation of template and view 
code), but I've some problems with putting all of this together. Let me 
summarize:


1. Views and Viewlets belong to the layer

2. Templates belong to the skin

3. ViewletManagers belong to.. ? 

4. Lovely's packaging practices says that: 
- views should be placed and registered in 
project.browser.layer.subpackage_for_the_view_impelentations 
- templates should be placed and registered in project.browser.skin 
package
- viewletmanagers... ? 


Where you place and register your code and templates is up to you.

Right now we do this :

Layer : view, viewlet and viewletManager code
simple template which are not skin dependent
Skin : templates registered for the views and viewlets

I also use the macro feature from the template tag heavily.

If you don't plan to reuse your code in different skins registering 
everything on the layer or skin will work too.


It is also possible to first register everything on the layer. Then you 
will have a running application. If you need to provide another skin you 
just register the parts to replace on the new skin.




ViewletManagers may have a class and a template, VMs are called from 
templates, viewlets are registered for VMs. Shouldn't it be resolved by 
template tag which registers a template with ViewletManager as it is done 
for Viewlets and Views?


Of course you can use all the features for ViewletManagers especially 
the RegisteredPageTemplate is perfect for ViewletManagers too.
A ViewletManager is just a special case of a ContentProvider (have a 
look at the interfaces).




One more thing is a layer declaration such as (from Stephan's post):

browser:viewlet
name=bloglist
for=myproject.interfaces.IBlog
manager=myproject.browser.interfaces.IContent
view=myproject.browser.blog.BlogPage
class=myproject.browser.blog.BlogList
layer=myproject.browser.IProjectLayer
permission=zope.Public
/

while template is registered for skin:
browser:template
template=bloglist.pt
layer=myproject.browser.skin.IProjectSkin
for=myproject.browser.blog.BlogList
/

I'm pretty new to the skinnig concept. What is the purpose of IProjectLayer? 
Is it that views and viewlets are registered to IProjectLayer which 
is project marker interface, while templates are registered for skins. As a 
result we have stable project's code base and skins which are just templates.


Yep



Any discussion on the above topics will be appreciated :)




___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Seeking a ZCML Example for a CSSViewlet

2006-10-09 Thread Jürgen Kartnaller



Thierry Florac wrote:

Le samedi 07 octobre 2006 à 17:00 +1300, Darryl Cousins a écrit :

configure zcml::

  browser:viewlet
  name=layout.css
  for=*
  manager=barrysmithgallery.layer.public.ICSS
  permission=zope.Public
  class=..BRSPublicLayerLayoutCSSViewlet
  layer=barrysmithgallery.layer.public.IBRSPublicBrowserLayer
  weight=2
  /


Maybe I'm wrong, but it seems that the weight parameter is not used by 
the default implementation of the CSS viewlet manager...

Correct ?


Correct, but look at z3c.viewlet.

Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Intended scope of viewlets?

2006-10-07 Thread Jürgen Kartnaller

Hi Alec


Alec Munro wrote:

Hi Jürgen,

So, just to give a concrete example for my case, I might replace this
(Metal-based):

body

div id=Navigation
 div metal:define-slot=navigation
   Nav tree needs a wee bit of work.
 /div
/div

div id=Content
 div metal:define-slot=body
  Some Content
 /div
/div

/body

with this (viewlet-based):

body

div id=Navigation
   span tal:replace=structure provider:my.project.navigation
 Nav tree needs a wee bit of work.
   /span
/div

div id=Content
 span tal:replace=structure provider:my.project.content
   Some Content
 /span
/div

/body


exactly



With seperate viewlet managers for navigation and content, or any
other types of views I would expect to have on this page? Would a
header viewlet manager also be sensible, say if I wanted a title
that changed format depending on what type of content was being
viewed?


What you need is up to your application.

You can define a header manager which the changes its content/viewlets 
depending on the page viewed.




Finally, are there any best practices for packaging in viewlet-based
templating? I'm currently creating this in my.project.browser.skin.


Our current structure is :

project.browser.layer.packages for the view implementations
  Here we provide the view code and the viewlet registrations.
project.browser.skin
  Here we provie the templates and the template registrations using 
z3c.viewtemplate.



How about the viewlet manager names, should they be my.project.*,
my.project.browser.*, or something different?


We use the interface name as the manager name.



Probably some of these questions aren't relevant to the work you are
doing on viewlets, but I find it helpful to try to follow industry
practices as closely as possible, especially on something I don't have
much experience with, so I am easily able to follow tutorials, and
people who are helping me can more easily understand what I am trying
to do.

Thanks very much for your help so far, I am excited about implementing
viewlets in our upcoming project.

Alec

On 10/5/06, Jürgen Kartnaller 
[EMAIL PROTECTED] wrote:

Hi Alec.

Alec Munro wrote:
 Hi List,

 I'm just getting up to speed with viewlets, having read a thread here
 and there in the past about them. I've installed the examples provided
 on this list, and while I believe I understand how they work, I don't
 understand in what circumstances they are most useful. The viewlets in
 the examples are all very small, such as retrieving an formatting a
 single piece of information about an object. However, from some of the
 posts to this list, I get the impression they are also being used for
 more complex items, like navigation menus.

Menus are a perfect example for the use of viewlets.
Have a look at z3c.menu. This package contains a base implementation for
menus based on viewlets.

 Is there a recommended scope? Can they be described in a way such as
 develop your templates up to point X, then use a viewlet for
 development of further depth?.

 In my case, I am developing a new skin for a project, and my
 experience with metal says to make the entire HTML page a macro with
 slots for content and navigation. Is there a comparable viewlet-based
 paradigm?

Yes there is one, see below


 Also, am I correct in stating that when working with viewlets, the
 only complete HTML page will be the primary skin file, with all
 viewlets based on snippets of HTML?

Thats exacly what we at Lovely Systems do and it works perfectly :)

We have one base template which is used for all pages. Instead of
defining slots to be filled by other templates it contains viewlet 
managers.

We then provide different view classes to be able to register our
viewlets for the pages of the application.
The view classes are empty classes they are just providing the class
name or if they provide additional functionality they also provide an
interface.
It is then possible to register the viewlets for specific pages.
The most important thing on viewlets is that they are adapters on the
*context*, the *request*, the *view* and the *manager*.

The viewlet solution is an extremely productive way to implement a
complex application.

Make sure you read this :
http://blogs.lovelysystems.com/srichter/2006/09/20/the-skin-browser-and-lovely-systems-new-development-workflow/ 



Stephan Richter describes here our use of the viewlet concept and our
development workflow. The most important part was the development of the
package z3c.viewtemplate. This package makes it possible to separate the
  development of the HTML page from the implementation of the python
view class. The package is not yet perfect but gives us what we need
right now but it needs a better integration into forms and viewlets.
Expect more in the near future!

In our applications really everything is done using viewlets, there is
no single use of fill-slot in the hole application!


 My questions are fairly broad-ranging, I know, but I have thus far
 been unable to find

[Zope3-Users] Re: Intended scope of viewlets?

2006-10-05 Thread Jürgen Kartnaller

Hi Alec.

Alec Munro wrote:

Hi List,

I'm just getting up to speed with viewlets, having read a thread here
and there in the past about them. I've installed the examples provided
on this list, and while I believe I understand how they work, I don't
understand in what circumstances they are most useful. The viewlets in
the examples are all very small, such as retrieving an formatting a
single piece of information about an object. However, from some of the
posts to this list, I get the impression they are also being used for
more complex items, like navigation menus.


Menus are a perfect example for the use of viewlets.
Have a look at z3c.menu. This package contains a base implementation for 
menus based on viewlets.



Is there a recommended scope? Can they be described in a way such as
develop your templates up to point X, then use a viewlet for
development of further depth?.

In my case, I am developing a new skin for a project, and my
experience with metal says to make the entire HTML page a macro with
slots for content and navigation. Is there a comparable viewlet-based
paradigm?


Yes there is one, see below



Also, am I correct in stating that when working with viewlets, the
only complete HTML page will be the primary skin file, with all
viewlets based on snippets of HTML?


Thats exacly what we at Lovely Systems do and it works perfectly :)

We have one base template which is used for all pages. Instead of 
defining slots to be filled by other templates it contains viewlet managers.
We then provide different view classes to be able to register our 
viewlets for the pages of the application.
The view classes are empty classes they are just providing the class 
name or if they provide additional functionality they also provide an 
interface.

It is then possible to register the viewlets for specific pages.
The most important thing on viewlets is that they are adapters on the 
*context*, the *request*, the *view* and the *manager*.


The viewlet solution is an extremely productive way to implement a 
complex application.


Make sure you read this :
http://blogs.lovelysystems.com/srichter/2006/09/20/the-skin-browser-and-lovely-systems-new-development-workflow/

Stephan Richter describes here our use of the viewlet concept and our 
development workflow. The most important part was the development of the 
package z3c.viewtemplate. This package makes it possible to separate the 
 development of the HTML page from the implementation of the python 
view class. The package is not yet perfect but gives us what we need 
right now but it needs a better integration into forms and viewlets. 
Expect more in the near future!


In our applications really everything is done using viewlets, there is 
no single use of fill-slot in the hole application!




My questions are fairly broad-ranging, I know, but I have thus far
been unable to find a straightforward explanation of viewlets, in
terms of how they relate to general site development.


All I can tell you now is : USE VIEWLETS, USE VIEWLETS, USE VIEWLETS,


Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: absolute_url in the viewlet ?

2006-10-03 Thread Jürgen Kartnaller

Or simply :

from zope.traversing.browser.absoluteurl import absoluteURL

absoluteURL(self.context, self.request)

Jürgen

[EMAIL PROTECTED] wrote:

self.context.absolute_url looks very zope2ish, absolute_url is no longer 
inherited, it is an adapted component, so I believe the accepted Zope3 way is...

from zope.app import zapi
from zope.app.traversing.browser.interfaces import IAbsoluteURL

.

def render(self):
url = zapi.getMultiAdapter( (self.context, self.request), IAbsoluteURL) 
return liIAbsoluteUrl == %s//li % url


 



Kevin Smith

- Original Message 
From: Christophe Combelles [EMAIL PROTECTED]
To: zope3-users@zope.org
Sent: Monday, October 2, 2006 7:14:22 PM
Subject: [Zope3-Users] absolute_url  in the viewlet ?

Hi,

How can I obtain the absolute_url of the context object in a content provider or 
in a viewlet ?


For example, in the demo3 of zope3demos, the render() method of the viewlet 
returns  self.context.__name__.

( http://zope3demos.googlecode.com/svn/trunk/demo3/demo.py )

How could I tell it to return the absolute_url instead of the __name__ ?

(self.context.absolute_url gives a ForbiddenAttribute error.)


thanks,
Christophe
___
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] Re: SqlAlchemy

2006-09-14 Thread Jürgen Kartnaller

Hi catonano.

As the developer of the z3c.zalchemy package let me give you a short 
introduction to zalchemy :


Zope3 contains a transaction mechanism which allows to plug in as many 
transaction managers as you like. The main purpose of the zalchemy 
package was to integrate SQLAlchemy into Zope3's transaction handling.
Actually the package provides this by implementing a data manager which 
joins Zope3's transactions when needed.
when needed in this case means, any time a session is requested from 
zalchemy via the getSession method a data manager for the current thread 
is activated.

The hole complexity of Zope3's transaction system is now behind the scenes.

See also my notes below.

And don't forget to read the README in z3c.zalchemy ;)

Jürgen


catonano wrote:

Hello zopers,

well this email is going to be quite long, I'm sorry I have many things 
to say


I saw the Zope 3 book, particulary the mapping (adapting) between the 
persistent objects defined there (a messageboard and a message objects) 
and some ftp files (and folders).


Now, I'd like to do the same with some, say, objects that are in a MySql 
database. I would love to realize a folders/files hierarchy that's 
mapped on my relational database !


I saw SqlAlchemy. It's impressive. I took a look at the Zalchemy code 
too, just to see wether I could borrow something.


I made a plan about how to achieve all this. I would like to expose it 
here and ask you, kind zopers, wether it's sane or there's something BIG 
I'm missing.


Because in the Zalchemy code I saw something I don't understand so I 
started to fear that there is something big I'm missing, indeed.


So, my plan is:

1) introduce all my tables and relationships between them. Something 
like users = Table('users', metadata, autoload = True)


If you use zalchemy, make sure you use z3c.zalchemy.metadata



and then overriding some table property where needed, also introducing 
some relationships, all what needed


2) define some interfaces as in the Zope 3 book, introducing containers 
and contained objects


3) define implementation classes for the interfaces that in their 
methods do something similar to what I saw in SQLAlchemyContainer, for 
example, which is, say,


   def __setitem__(self, name, item):
session = z3c.zalchemy.getSession()  #in my case I still don't 
know where I'll take the session from


If you use zalchemy this is how to get the session, that's it, no other 
case!



session.save(item)
session.flush([item])

4) adapt these components to files, as in the book example

Could this be a good plan ?

Because in the Zalchemy code I saw a strange class, that is:

class AlchemyDataManager(object):
Takes care of the transaction process in zope.

implements(IDataManager)


This is the transaction manager mentioned above.



shall I take care of this transaction process too ?


Of course :
- it makes your life easier because zalchemy takes care of it
- it makes sure nothing is commited in case of errors or on write conflicts



Because I know nothing about it and saw not so many docs about the 
internal Zope3 machinery.


Thanks so much for any hint
Bye
Catonano


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: nextUrl(), passing state in formlib

2006-09-10 Thread Jürgen Kartnaller

Hi Martin.

I did it this way :

The Edit Form implementation :

class AddClub(zope.formlib.form.AddForm):

base_template =zope.formlib.form.AddForm.template
template = ViewPageTemplateFile('club_add.pt')

...


def referer(self):
returnself.request.form.get('referer')\
   or self.request.getHeader('HTTP_REFERER')

def nextURL(self):
return self.request.form.get('referer','..')


The template ('club_add.pt') :

div metal:use-macro=view/base_template/macros/main 
  div metal:fill-slot=extra_info
   input type=hidden name=referer value= tal:attributes=value 
view/referer /

  /div
/div


Hope this helps

Jürgen

Martin Aspeli wrote:

Hi,

I have an add form (and later, an edit form) that may be invoked from a 
particular view among a few choices. That is, the user can be at @@foo 
or @@bar, click add X or edit Y.


When the form is successfully submitted (i.e. validated) I want to send 
the user back to @@foo or @@bar depending on where they originally came 
from.


Add forms (and my custom edit handler for the edit form) have a 
nextUrl() method to work out what the next URL should be. However, I 
need to pass the state of which page I came from along the requests. 
Using HTTP_REFERER doesn't work, because when it comes to the save 
button handler, the referer is the add form I was just on.


One way would be to put a hidden field in the form that looked at the 
referer the first time it was rendered and then passed that state along 
subsequent requests. However, I really need a generalisable solution 
(there will be many of these add and edit forms for different objects). 
Having a custom pageform template for all of them (I can make them all 
use a custom base class) would be one option, but I'd rather avoid it if 
I could, since this'd need to repeat all the other code in the pageform 
that I'd rather not have to keep manually in sync when the original 
version changes or bugs are fixed.


Is there some other way of passing this kind of where did I originally 
come from information along?


Martin


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: formlib, action decorators and inheritance

2006-07-17 Thread Jürgen Kartnaller

Hi Lorenzo.

Lorenzo Gil Sanchez wrote:

Hi,

I have an add form which a subclass of form.AddForm. It just adds a 
'cancel' action.


This is my code:

class AddView(form.AddForm):

Try this here :
  actions = form.AddForm.actions


form_fields = form.Fields(IDocument).omit('__name__')

def create(self, data):
return Document(**data)

def nextURL(self):
url = zapi.absoluteURL(self.context.context, self.request)
return url

@form.action(u'Cancel', validator=always_good)
def handle_cancel(self, action, data):
self.request.response.redirect(self.nextURL())

When I define the 'cancel' action using the @form.action decorator it 
seems that the 'add' action is lost. That action is defined in my super 
class.


As a workaround I do the following:

def handle_cancel(self, action, data):
self.request.response.redirect(self.nextURL())

actions = form.AddForm.actions + form.Actions(
form.Action(u'Cancel',
success='handle_cancel', validator=always_good),
)

but I'm not sure if I'm missing something since my workaround is uglier 
than the decorator solution.


Best regards,

Lorenzo Gil


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: formlib: Some additional text

2006-05-05 Thread jürgen Kartnaller
Hi Florian.

I do it this way :

The template :

div metal:use-macro=view/base_template/macros/main 
  div metal:fill-slot=extra_info
   input type=hidden name=referer value= tal:attributes=value
view/referer /
  /div
/div

The class :

class ViewIt(form.DisplayForm):

base_template =zope.formlib.form.DisplayForm.template
template = ViewPageTemplateFile('newTemplate.pt')

Jürgen

Florian Lindner wrote:
 Am Freitag, 5. Mai 2006 17:10 schrieb Fred Drake:
 On 5/5/06, Florian Lindner [EMAIL PROTECTED] wrote:
 Now I want to place some additional text above the form stuff. But I
 want to keep all this usefull JavaScript stuff that form lib inserts.
 Can you use the extra_info slot?
 
 I think that would work. (I've looked at its position in 
 zope/formlib/pageform.pt).
 
 But how can I fill that slot?
 
 I've tried by adding a template to the configure.zcml:
 
 
 html metal:use-macro=context/@@standard_macros/page
 body
 metal:block fill-slot=body
 
 /metal:block
 
 /body
 /html
 
 @@standard_macros/page is my template in my skin. The skin is derived from 
 the 
 rotterdam skin.
 
 Where do I add the fill-slot? I've tried a various locations in the template 
 above but nothing has a real effect.
 
 Thanks,
 
 Florian


-- 

---
Jürgen Kartnaller   mailto:juergen_at_kartnaller.at
http://www.kartnaller.at
http://www.mcb-bregenz.at
---

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Re : Re : formlib problem

2006-04-19 Thread jürgen Kartnaller
Stéphane Brault wrote:
 Hi Jim, 
  the Items object is my object, linked to my items, table which implements 
 the IItems interface I use for my form:
  
  from neteven.interfaces.items import IItems
  from zope.formlib import form
  
  class ItemsForm(form.EditForm):
  form_fields = form.Fields(IItems)
  form_fields = form_fields.omit('dateLastUpdate')
  
  Items is defined this way:
  
  from zope.interface import implements
  from sqlobject import *
  from sqlos import SQLOS
  from neteven.interfaces.items import IItems
  
  class Items(SQLOS):
  implements(IItems)
  
  class sqlmeta:
  table = 'items'
  
  
   When I add this zcml declaration :
  browser:page
for=.interfaces.items.IItems
name=edit.html
class=.forms.items.ItemsForm
menu=zmi_views
title=Edit a Item
permission=zope.ManageContent
/
  everything works fine from the ZMI (I created simple containers to test 
 that).
  
  My JSON server side code is:
  
  def getItemEdit(self, itemId):
  item = Items.get(itemId) #a sqlos function to get an Item instance 
 from the table given its Id
  return ItemsForm(item, self.request)()

After the request from the database your item has no location and is
therefore not physically locatable.
If you use it from within an SQLOS container the container puts the item
into a location proxy.
That's the difference between your test in the ZMI and this code.

Jürgen

  
 The fact is I don't use any page template right now ( though I might do this 
 later to have a nice GUI).
  
  Thanks,
  
  Stéphane
  
 - Message d'origine 
 De : Jim Washington [EMAIL PROTECTED]
 À : Stéphane Brault [EMAIL PROTECTED]
 Cc : zope3-users@zope.org
 Envoyé le : Mercredi, 19 Avril 2006, 5h01mn 09s
 Objet : Re: Re : [Zope3-Users] formlib problem
 
 Stéphane Brault wrote:
 Hi again,
  sorry to be a bore ;-)
  I keep on trying to use formlib, I no longer have a problem of adapters for 
 my fields but I get this error:
  2006-04-19T16:13:32 ERROR root 
 C:\Python24\Lib\site-packages\zope\publisher\publish.py line 138 in publish
  = 'result = publication.callObject(request, object)'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\app\publication\zopepublication.py line 
 161 in callObject
  = 'return mapply(ob, request.getPositionalArguments(), request)'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\publisher\publish.py line 113 in mapply
  = 'return debug_call(object, args)'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\publisher\publish.py line 119 in 
 debug_call
  = 'return object(*args)'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  c:\ZopeInst\lib\python\neteven\database\items.py line 43 in getItemEdit
  = 'return ItemsForm(item, self.request).render()'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\formlib\form.py line 733 in render
  = 'self.form_result = self.template()'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\app\pagetemplate\viewpagetemplatefile.py 
 line 83 in __call__
  = 'return self.im_func(im_self, *args, **kw)'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\app\pagetemplate\viewpagetemplatefile.py 
 line 51 in __call__
  = sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0),
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\pagetemplate\pagetemplate.py line 117 in 
 pt_render
  = 'strictinsert=0, sourceAnnotations=sourceAnnotations)()'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\tal\talinterpreter.py line 277 in 
 __call__
  = 'self.interpret(self.program)'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceClass zope.app.traversing.interfaces.IPhysicallyLocatable)
  C:\Python24\Lib\site-packages\zope\tal\talinterpreter.py line 352 in 
 interpret
  = 'handlers[opcode](self, args)'
  ** exceptions.TypeError: ('Could not adapt', Items at 0x3d7ce30, 
 InterfaceCla
  ss 

[Zope3-Users] Re: zalchemy alpha svn repository

2006-04-06 Thread jürgen Kartnaller
Let's first see if it works as expected.
I really have no idea if it is usefull for full blown applications.

I only tested my use cases, we'll see what happens if someone else uses it.

Since the repository is online I did a lot of changes and impovements
and I'm constantly working on.

I'm now starting to use it within my new application.

Jürgen

David Pratt wrote:
 Hi Jurgen! This is excellent news. Thank you for this work! I will also
 look at the code to see what I can do to contribute.

That's why it's public available :)

  I think it would
 be great for you to post an announcement to the SQLAlchemy list. There
 are folks there in tune with core SQLAlchemy code that may also be able
 to offer advice or recommendations.

Actually there seems to be a change on the way related to the
transaction management in sqlalchemy which I would appreciate.

 I also hope that folks like Brian,
 Florent and Sidnei will take time to review the code. Many thanks for
 your efforts!
 
 Regards,
 David
 
 j.kartnaller wrote:
 Hi all.

 As promised I set up a repository with my SQLAlchemy integration work.

 Actually it works under my test cases.

 The main part is the integration of the transaction process into zope
 so that it is transparent to the user.
 Someone with more SQLAlchemy experience should have a look at the data
 manager.
 I'm not completely sure if it is correctly integrated into the tpc
 process.
 There are a lot of open issues mentioned in TODO.txt

 The tests pass by using sqlite.
 I did a short test with MySQL which only worked with InnoDB tables.

 For a simple use I added a container class which is able to show
 objects mapped to a SQLAlchemy table.
 See the demo in demo/zalchemy.

 For the use of the ZCML directives see
 zalchemy/tests/test_directives.py and the demo.


 Checkout with :
 svn co svn://svn.kartnaller.at .


 Jürgen

 ___
 Zope3-users mailing list
 Zope3-users@zope.org
 http://mail.zope.org/mailman/listinfo/zope3-users



-- 

---
Jürgen Kartnaller   mailto:juergen_at_kartnaller.at
http://www.kartnaller.at
http://www.mcb-bregenz.at
---

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Traversal Tricks (was Seeking Reference Guide on TAL/TALES/METAL)

2006-04-02 Thread jürgen Kartnaller
Jeff Rush wrote:
 I need control over which namespace is searched, so I added a couple of
 generic TALES namespace adapters.  Now I can do:
 
   h1 tal:content=context/attribute:name /

How about :
h1 tal:content=context/++attribute++name /

 
 to -only- search for a name attribute, and (less frequently):
 
   h1 tal:content=context/item:ABC123 /

h1 tal:content=context/++item++ABC123 /

See zope.app.traversing for other namespaces.

Jürgen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: how to make static pages

2006-03-16 Thread jürgen Kartnaller
Lorenzo Gil Sanchez wrote:
 Hi,
 
 I'd like to ask what's the best way to create static html pages inside
 my application. For example, the intro page, a help page or a legal
 conditions page.
 
 I have a skin inside a browser package but if I understand them
 correctly the provide views for content objects. Do I need to create a
 content object for the each of my static pages? Can I create a template
 with just the information (e.g. a view without a content)?

Declare your page in zcml :

browser:page
  name=static.html
  for=*
  template=yourFilenameOfThePageHere
  permission=zope.View
  /
 
 Sorry, I'm a little bit lost here
 
 Best regards
 
 Lorenzo Gil


-- 

---
Jürgen Kartnaller   mailto:juergen_at_kartnaller.at
http://www.kartnaller.at
http://www.mcb-bregenz.at
---

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Prevent Duplicate Persistency

2006-03-15 Thread jürgen Kartnaller
Dax wrote:
 Thanks a lot, Mats.  This is a way to do it, but if I were to add a
 name schema to IMark and checkName on the actual name, then I
 would not be able to do this for url as well, right?  So my question
 is how would I do this for url without having url as the name for the
 Mark object?

You should have a look at formlib/form.txt.
See section Invariants.

Jürgen
 
 On 3/15/06, Mats Nordgren [EMAIL PROTECTED] wrote:
 This could be done by using the URL as the name for the Mark object.

 from zope.app.container.contained import NameChooser

 Class MarkNameChooser(NameChooser):
 def chooseName(self, name, object):
 name = object.url
 self.checkName(name, object)
 return name

 adapter
 for=.interfaces.IMarkContainer
   provides=zope.app.container.interfaces.INameChooser
   factory=.bookmarks.MarkNameChooser /

 Make sure your Mark object is configured with set_before_add

 addform
 ...
 set_before_add=url /


 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
 Behalf Of Dax
 Sent: Tuesday, March 14, 2006 8:00 PM
 To: zope3-users@zope.org
 Subject: [Zope3-Users] Prevent Duplicate Persistency

 For the following example (taken from Zope3 In 30 Minutes):

 class IMark(Interface):
 This is the book mark object.

 url = TextLine(
 title=uURL/Link,
 description=uURL of the website,
 default=uhttp://www.zope.org;,
 required=True)

 description = Text(
 title=uDescription,
 description=uDescription of the website,
 default=u,
 required=False)

 How can I prevent Mark objects from having the same url?  So if a Mark
 object exists in BookMarker with Mark.url=http://www.zope.org/;, how
 can I prevent another Mark object from being added when its url is
 http://www.zope.org;?

 Thanks.
 ___
 Zope3-users mailing list
 Zope3-users@zope.org
 http://mail.zope.org/mailman/listinfo/zope3-users




-- 

---
Jürgen Kartnaller   mailto:juergen_at_kartnaller.at
http://www.kartnaller.at
http://www.mcb-bregenz.at
---

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: Creating objects in software space when making site

2006-03-08 Thread jürgen Kartnaller
Joseph Method wrote:
 This should definitely be a prominent How-To somewhere.
Definitely, but where is somewhere !

Maybe in the upcoming zope3.org website ?

Jürgen
-- 

---
Jürgen Kartnaller   mailto:juergen_at_kartnaller.at
http://www.kartnaller.at
http://www.mcb-bregenz.at
---

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: redirects in a formlib EditForm

2006-02-27 Thread jürgen Kartnaller
Gary Poster wrote:
 
 On Feb 26, 2006, at 4:17 PM, jürgen Kartnaller wrote:
 
 Joel Moxley wrote:
 ** What is the best way to use a formlib EditForm to redirect a user
 after applying changes without fully cloning a handle_edit_action
 method? **

 I'm doing it this way :

 def render(self):
 if self.errors is None or self.errors:
 return super(EditPerson, self).render()
 self.request.response.redirect('..')

 Jürgen

 Thanks Jürgen!  That works perfectly for me.

 Looking one step forward, I would like to redirect the user back to
 the previous page from whence they came (without using sessions).  I
 figure I am going to need to stash that value on my EditForm class and
 then pull it up during the redirect in my render method.  I've done my
 best to explore this, but I can't figure out where the previous page
 information will be available on my EditForm.

 ** Where should I stash previous page information for future redirects
 on my EditForm? **

 That's also an unsolved use case I have.

 The 'default' template of 'FormBase' contains the slot 'extra_info'
 which could be filled with some hidden input fields.

 I defined a new template for my own EditForm.

 But now I would like to use the existing template in formlib
 'pageform.pt' and fill the slot but don't know how.

 Is this a possible way and the right way ?

 How can I use the existing template ?
   It must be useable with metal:use-macro somehow.
 
 Yes, we write custom templates that use hidden input fields.  We reuse
 the existing template by putting the default template on another
 attribute of the view class, and then saying 'metal:use-macro=view/...'
 
 For instance
 
 class MyForm(zope.formlib.form.EditForm):
 base_template = zope.formlib.form.EditForm.template
 template = (...a named template if you want, or just a page template
 directly...)
 
 Then in your template, you can refer to macros in the original like this:
 
 'metal:use-macro=view/base_template/macros/extra_info'

Thanks a lot for this.

The above metal statement doesn't work, I do it this way :
  metal:use-macro=view/base_template/macros/main
and then
  metal:fill-slot=extra_info

Jürgen


-- 

---
Jürgen Kartnaller   mailto:juergen_at_kartnaller.at
http://www.kartnaller.at
http://www.mcb-bregenz.at
---

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users