Re: [Zope3-Users] configure access from zcml

2007-02-22 Thread Tim TerlegÄrd
On Wed, Feb 21, 2007 at 11:04:26AM +0100, Michael Haubenwallner wrote:
 The publication requestfactories are available by default.
 Is there a way to configure protocol access to the whole site, local 
 sites, containers or objects through ZCML ?
 
 How would a sysadmin e.g. enable xmlrpc access to the site or a folder 
 only or disable xmlrpc access to a certain object or interface ?

I'm not completely sure, but perhaps you can override the traverse
zcml directives in zope/app/publisher/xmlrpc/configure.zcml

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


[Zope3-Users] Events

2007-02-22 Thread David Johnson
Does anyone know the process by which objects are notified by  
events?  I created a custom container that stores objects in MySQL.   
However, I noticed that when I add a container that an  
ObjectAddedEvent is then propogated to every single object in my  
container, generating nearly 2000 queries.  From my reading of the  
core Zope code, it seems that when an event is triggered it is sent  
to every single object in every container.  This seems rather  
inefficient if you have either a large container or large objects in  
your container.  Am I understanding this correctly?   None of my  
objects subscribe to events (at least not yet).


The problem seems to start in  
zope.app.container.contained.sublocations, which basically queries  
all objects in a container and sends an event to all of them.

excerpt from zope.app.container.contained.ContainerSublocations:

def sublocations(self):
container = self.container
for key in container:
yield container[key]


Warm regards,
David


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


[Zope3-Users] Re: Events

2007-02-22 Thread Philipp von Weitershausen

David Johnson wrote:

Does anyone know the process by which objects are notified by events?


Objects aren't typically notified of events. Event handlers are. The 
whole event setup, including object events, is explained in detail in my 
book, http://worldcookery.com. I suggest picking up a copy :)


I 
created a custom container that stores objects in MySQL.  However, I 
noticed that when I add a container that an ObjectAddedEvent is then 
propogated to every single object in my container, generating nearly 
2000 queries.  From my reading of the core Zope code, it seems that when 
an event is triggered it is sent to every single object in every 
container.  This seems rather inefficient if you have either a large 
container or large objects in your container.  Am I understanding this 
correctly?


To a degree. A common pattern in Zope is event dispatch. Dispatchers 
receive an event and propapage it further.


The container machinery has such a dispatcher for ObjectMovedEvents. 
When a container is moved, it propapates the event to its subobjects, so 
they know their overall physical location has changed. An 
ObjectAddedEvent is a special case of ObjectMovedEvent.


The problem seems to start in zope.app.container.contained.sublocations, 
which basically queries all objects in a container and sends an event to 
all of them.


You're probably talking about dispatchToSublocations. This is the code 
that looks up a containers sublocations and dispatches the event to them.


One way to prevent this behaviour for your container is to write a new 
ISublocations adapter for your container that simply returns an empty 
sequence:


  class MyContainerSublocations(object):
  implements(zope.location.interfaces.ISublocations)
  adapts(...IMyContainer)

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

  def sublocations(self):
  return ()


--
http://worldcookery.com -- Professional Zope documentation and training
Next Zope 3 training at Camp5: http://trizpug.org/boot-camp/camp5

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


[Zope3-Users] Re: Events

2007-02-22 Thread David Johnson


You're probably talking about dispatchToSublocations. This is the  
code that looks up a containers sublocations and dispatches the  
event to them.


One way to prevent this behaviour for your container is to write a  
new ISublocations adapter for your container that simply returns an  
empty sequence:


  class MyContainerSublocations(object):
  implements(zope.location.interfaces.ISublocations)
  adapts(...IMyContainer)

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

  def sublocations(self):
  return ()
This is probably the approach I will follow, but what if I want my  
container objects notified? Even if I don't it seems the default  
Folder implementation follows this logic and so if you have a folder  
with several large images for example, then you will pay a price  
whenever an event is issued.  In general it seems that any change  
will result in the entire ZODB being read for each event  
dispatch...if I still follow the logic here.


--
David








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


[Zope3-Users] Re: Events

2007-02-22 Thread Philipp von Weitershausen

On 22 Feb 2007, at 13:37 , David Johnson wrote:
You're probably talking about dispatchToSublocations. This is the  
code that looks up a containers sublocations and dispatches the  
event to them.


One way to prevent this behaviour for your container is to write a  
new ISublocations adapter for your container that simply returns  
an empty sequence:


  class MyContainerSublocations(object):
  implements(zope.location.interfaces.ISublocations)
  adapts(...IMyContainer)

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

  def sublocations(self):
  return ()
This is probably the approach I will follow, but what if I want my  
container objects notified?


I thought you don't... ?

Even if I don't it seems the default Folder implementation follows  
this logic and so if you have a folder with several large images  
for example, then you will pay a price whenever an event is  
issued.  In general it seems that any change will result in the  
entire ZODB being read for each event dispatch...if I still follow  
the logic here.


That's not what I said. It will only happen on object moves, in  
particular, when a container is moved. It will also only happen for  
the subitems of that container, not the whole ZODB, though arguably  
that can mean a lot of data.


I would personally like to see some form of disabling event handlers.


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


[Zope3-Users] Re: Events

2007-02-22 Thread Philipp von Weitershausen

On 22 Feb 2007, at 14:57 , David Johnson wrote:
This is probably the approach I will follow, but what if I want  
my container objects notified?


I thought you don't... ?
This is both a theory and practice question.  I want to make sure I  
follow practices that will not lead me into trouble in the  
future.   In this case I am likely to want an ObjectModifiedEvent  
so that my objects can be saved if they are modified.  For example  
if I edit an object via browser:editform, an ObjectModifiedEvent  
will be sent.  I am not clear whether Zope will examine every  
object in my container to see if it has an event handler for  
ObjectModifiedEvent; which is what it seems to do now.


You still don't seem to be getting it. The dispatching to container  
subobjects only happens for Object*Moved*Events, not on  
ObjectModifiedEvents or any other events.


Also, objects don't have event handlers. There is a certain class  
of events called object events. Code that does something to objects  
(create them, add the to a container, modify them, etc.) is supposed  
to send events about this. Then there aree event handlers that react  
to this. The original object is completely unaware of both the fact  
that an event is being sent about it and the fact that event handlers  
react to this. And that's exactly the beauty of it. Events let you  
implement business logic completely outside of the data model.


For further understanding, I really do suggest reading my book, it's  
explained in detail there. Any further discussion w/o that background  
will likely end up in confusion.


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


[Zope3-Users] translation domains and their scope

2007-02-22 Thread Giovannetti, Mark
Hello,

I am having some trouble with translation domains.  I 
have setup two for use.  Call one 'common' and the other
'myapp'.  They were created under a folder that was turned
into a site using the ZMI.  Call this site MYSITE.  

The translation domains were also registered via the ZMI.
I have filled in various message ids and their translations 
for en and fr in each domain.  I have also made sure to use
the proper i18n:domain declarations, as appropriate.

For locations under MYSITE, the myapp and common translations
work well (within a generic browser page template configured 
for ISite):

i.e. http://localhost:8080/MYSITE/

However, using http://localhost:8080/ to display the same
generic page (as another ISite), the translations do not happen.

I want to use the 'common' translation domain (TD) across more than
one site (i.e. the use case above would allow me to have a
splash page at the site root using common translations with
a choice among subsites).  

So, thinking I should move the 'common' TD to the zope instance
root I use the ZMI cut and paste functions to move the 'common'
domain from MYSITE to the root/global(?) site.  I also checked,
unregistered, and registered where appropriate.

Now the translations for common, formerly functional under
MYSITE, no longer work under MYSITE, nor do they work under the
root site, nor anywhere else.

What gives?  Is there something bad about using cut and paste 
to move a translation domain? 

How are translation domains looked up and used?  What are their
scopes?

Also,
What is the relationship, if any, between the name used
in the registration (as shown below) and the name of the 
translation domain 'common'?  (I did add text to the 'Register as' 
input box when I re-registered the 'common' TD.) 

 This object is registered:
zope.app.i18n.interfaces.ILocalTranslationDomain utility 
  named 'Common Look and Feel'

Thanks for shedding some light on how a site and a translation
domain inter-relate.

Mark


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


RE: [Zope3-Users] Events

2007-02-22 Thread Giovannetti, Mark
Hello David,

 
 Does anyone know the process by which objects are notified by  
 events?  I created a custom container that stores objects in MySQL.   
 However, I noticed that when I add a container that an  
 ObjectAddedEvent is then propogated to every single object in my  
 container, generating nearly 2000 queries.  From my reading of the  
 core Zope code, it seems that when an event is triggered it is sent  
 to every single object in every container.  This seems rather  
 inefficient if you have either a large container or large objects in  
 your container.  Am I understanding this correctly?   None of my  
 objects subscribe to events (at least not yet).
 

I was reading about this stuff (source code) last night.  
Perhaps this might help.  The file location is, of course,
system dependent.

From:

/usr/local/www/Zope3/lib/python/zope/app/container/interfaces.py

class IWriteContainer(Interface):
An interface for the write aspects of a container.

def __setitem__(name, object):
Add the given `object` to the container under the given name.

[snip]...

If the object's `__parent__` and `__name__` were already set to
the container and the name, then no events are generated and
no hooks.  This allows advanced clients to take over event
generation.

 


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


[Zope3-Users] User preferences for languages- possible?

2007-02-22 Thread Giovannetti, Mark
Hi,

This stuff is crazy.  I just want to implement a user
preference for a language (because I have to).  I've
read all the user pref. documentation (skinpref, apidoc
prefs and zope.app.preference) until I'm blue in the
face.  Nothing seems to work and there is no help via
google and so forth.

I know that UserPreferences() wants an ILocation object.
I can't seem to get one inside the BrowserFormLanguages
class.  I am only given the request object.

What do I need to do?  Getting a root site is insane
the way I found to do it via a mailing list message.  Not
to mention it had issues racking up db connections, then
failing on close.

Help! Please! Thank you!

Preferences seem to work since I can edit them using
the http://.../++preferences++/ form.

Mark

P.S.  This is not covered in Richter's book, nor von
Weitershausen's (1st ed.) both of which I bought.

Experimental code and traceback follow:

=== 8=== language.py ===
from zope.interface import implements
from zope.component import adapts
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.i18n.interfaces import IUserPreferredLanguages
from zope.i18n.interfaces import IModifiableUserPreferredLanguages
from zope.app.session.interfaces import IClientId
from zope.publisher.browser import BrowserLanguages

from zope.app.component.hooks import setSite, getSite
from zope.app.preference.interfaces import IUserPreferences
from zope.app.preference import UserPreferences
#import ZODB
#from zope.component import getUtility

class BrowserFormLanguages(BrowserLanguages):
implements(IModifiableUserPreferredLanguages)

language_store = []  # ignore this for now

def __init__(self, request):
super(BrowserFormLanguages, self).__init__(request)
print created BFL, self.language_store

def setPreferredLanguages(self, langs):
#prefs = UserPreferences()
#print prefs.eods.general.language
self.language_store = langs
print set language, self.language_store

def getPreferredLanguages(self):
langs = super(BrowserFormLanguages, self).getPreferredLanguages()
if self.language_store:
langs = self.language_store + langs
form_lang = self.request.get(Language, None)
if form_lang is not None:
langs.insert(0, form_lang)

#this just leads to madness and a horrible error
#[...] exceptions.ValueError: I/O operation on closed file
#db = getUtility(ZODB.interfaces.IDatabase)
#conn = db.open()
#root = conn.root().data['Application']
#setSite(root)
#prefs = UserPreferences(getSite())
prefs = UserPreferences()
print Prefs, repr(prefs)
#print repr(getSite())
print prefs.__dict__
# crashes on the next line - but prints the word lang
print lang, prefs.eods.general.language
print My prefered override, langs
#db.close()
return langs
==

Traceback:
==
created BFL []
Prefs zope.app.preference.preference.PreferenceGroup object at 0x963466c
{'__schema__': None, '__Security_checker__': zope.security.checker.Checker 
object at 0xa153dec, '__description__': u'', '_PreferenceGroup__parent': 
BaseGlobalComponents base, '__name__': '++preferences++', '__title__': u'User 
Preferences', '__provides__': zope.interface.Provides object at 0x95bfe8c, 
'__id__': u''}
lang--
2007-02-22T15:54:50 DEBUG twisted Exception rendering:
--
2007-02-22T15:54:50 DEBUG twisted Traceback (most recent call last):
  File /usr/local/lib/python2.4/threading.py, line 422, in run
self.__target(*self.__args, **self.__kwargs)
  File /usr/local/www/Zope3/lib/python/twisted/python/threadpool.py, line 
149, in _worker
context.call(ctx, function, *args, **kwargs)
  File /usr/local/www/Zope3/lib/python/twisted/python/context.py, line 59, in 
callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File /usr/local/www/Zope3/lib/python/twisted/python/context.py, line 37, in 
callWithContext
return func(*args,**kw)
--- exception caught here ---
  File /usr/local/www/Zope3/lib/python/twisted/web2/wsgi.py, line 139, in run
result = self.application(self.environment, self.startWSGIResponse)
  File /usr/local/www/Zope3/lib/python/zope/app/wsgi/__init__.py, line 50, in 
__call__
request = self.requestFactory(environ['wsgi.input'], environ)
  File /usr/local/www/Zope3/lib/python/zope/app/publication/httpfactory.py, 
line 69, in __call__
request = request_class(input_stream, env)
  File /usr/local/www/Zope3/lib/python/zope/publisher/browser.py, line 229, 
in __init__
super(BrowserRequest, self).__init__(body_instream, environ, response)
  File /usr/local/www/Zope3/lib/python/zope/publisher/http.py, line 323, in 
__init__
self.setupLocale()
  File /usr/local/www/Zope3/lib/python/zope/publisher/http.py, line 331, in 

[Zope3-Users] Re: User preferences for languages- possible?

2007-02-22 Thread Philipp von Weitershausen

Giovannetti, Mark wrote:

Hi,

This stuff is crazy.  I just want to implement a user
preference for a language (because I have to).  I've
read all the user pref. documentation (skinpref, apidoc
prefs and zope.app.preference) until I'm blue in the
face.  Nothing seems to work and there is no help via
google and so forth.

I know that UserPreferences() wants an ILocation object.
I can't seem to get one inside the BrowserFormLanguages
class.  I am only given the request object.

What do I need to do?  Getting a root site is insane
the way I found to do it via a mailing list message.  Not
to mention it had issues racking up db connections, then
failing on close.

Help! Please! Thank you!

Preferences seem to work since I can edit them using
the http://.../++preferences++/ form.


The zope.app.preference stuff stores the info in principal annotations, 
in a weird way. I personally find that stuff a bit convoluted.


The key, as you've correctly identified, is write your own 
IUserPreferredLanguages adapter (or a variant thereof). I would store 
the user's preferences in a cookie or a session. This makes things much 
easier. Simply adapt the request to ISession(request).


Note that this might not always work, e.g. when the request is 
instantiated and the request's locale is first created (because local 
utilities to store the session data in aren't available at that point). 
It seems you're hitting that exact problem with the preference stuff as 
well. The trick here is to stub this out when the adapter is first 
called, and then later during traversal, when you know the local 
components are there, you revisit it all again by calling 
request.setUpLocale() or whatever it is. The ++lang++ implementation 
might give some pointers.



--
http://worldcookery.com -- Professional Zope documentation and training
Next Zope 3 training at Camp5: http://trizpug.org/boot-camp/camp5

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


[Zope3-Users] Re: translation domains and their scope

2007-02-22 Thread Philipp von Weitershausen

Giovannetti, Mark wrote:

Hello,

I am having some trouble with translation domains.  I 
have setup two for use.  Call one 'common' and the other

'myapp'.  They were created under a folder that was turned
into a site using the ZMI.  Call this site MYSITE.  


The translation domains were also registered via the ZMI.
I have filled in various message ids and their translations 
for en and fr in each domain.  I have also made sure to use

the proper i18n:domain declarations, as appropriate.

For locations under MYSITE, the myapp and common translations
work well (within a generic browser page template configured 
for ISite):


i.e. http://localhost:8080/MYSITE/

However, using http://localhost:8080/ to display the same
generic page (as another ISite), the translations do not happen.

I want to use the 'common' translation domain (TD) across more than
one site (i.e. the use case above would allow me to have a
splash page at the site root using common translations with
a choice among subsites).  


So, thinking I should move the 'common' TD to the zope instance
root I use the ZMI cut and paste functions to move the 'common'
domain from MYSITE to the root/global(?) site.  I also checked,
unregistered, and registered where appropriate.

Now the translations for common, formerly functional under
MYSITE, no longer work under MYSITE, nor do they work under the
root site, nor anywhere else.

What gives?  Is there something bad about using cut and paste 
to move a translation domain? 


How are translation domains looked up and used?  What are their
scopes?


The scope of any local utility (and that includes translation domains) 
is the site that it was registered for. It's therefore not surprising 
that a translation domain you added and registered in MYSITE are not 
available outside that folder.


Why aren't you going for global translation domains that are maintained 
as gettext PO files on the filesystem and registered using ZCML? My book 
(also the 1st edition) explains how to do that.



--
http://worldcookery.com -- Professional Zope documentation and training
Next Zope 3 training at Camp5: http://trizpug.org/boot-camp/camp5

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


[Zope3-Users] RE: translation domains and their scope

2007-02-22 Thread Giovannetti, Mark
Hi Philipp,

Thanks for responding.  I am including the mailing list.

 From: Philipp von Weitershausen [mailto:[EMAIL PROTECTED] 
 Giovannetti, Mark wrote:
[snip]
  
  However, using http://localhost:8080/ to display the same
  generic page (as another ISite), the translations do not happen.
  
  I want to use the 'common' translation domain (TD) across more than
  one site (i.e. the use case above would allow me to have a
  splash page at the site root using common translations with
  a choice among subsites).  
  
  So, thinking I should move the 'common' TD to the zope instance
  root I use the ZMI cut and paste functions to move the 'common'
  domain from MYSITE to the root/global(?) site.  I also checked,
  unregistered, and registered where appropriate.
  
  Now the translations for common, formerly functional under
  MYSITE, no longer work under MYSITE, nor do they work under the
  root site, nor anywhere else.
  
  What gives?  Is there something bad about using cut and paste 
  to move a translation domain? 
  
  How are translation domains looked up and used?  What are their
  scopes?
 
 The scope of any local utility (and that includes translation 
 domains) is the site that it was registered for. It's therefore 
 not surprising that a translation domain you added and 
 registered in MYSITE are not available outside that folder.

Ok, fair enough.  That still doesn't explain why moving the 'common'
TD to the [top] 'site' (in the ZMI) didn't 'globalize' it.  Oh well, I
guess it's just another of those unexplained head scratchers that
zope3 seems to be infused with.  I was under the impression that
a utility that wasn't found in a local site was searched up-the-stack
to the global site.

 
 Why aren't you going for global translation domains that are 
 maintained as gettext PO files on the filesystem and registered 
 using ZCML? My book (also the 1st edition) explains how to do that.
 

I have reread the chapter on i18n and will try the ZCML 
registerTranslations directive.  Does this guarantee that
all translation domains registered via this directive will 
be available *everywhere* in the zope instance?  If so then
I thank you for reminding me about it.  If not, wtf?

I had wanted to use the GUI in the ZMI for simple testing 
before getting to the gettext formalization for the app.
I'd also like to have the possibility of allowing clerical
staff to enter immediate translations for content using
the ZMI GUI but my expectations in this may not be realized.

I will inform the mailing list of my progress. 

Thanks again.

Mark












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


[Zope3-Users] Re: translation domains and their scope

2007-02-22 Thread Philipp von Weitershausen

On 22 Feb 2007, at 23:59 , Giovannetti, Mark wrote:

From: Philipp von Weitershausen [mailto:[EMAIL PROTECTED]
Giovannetti, Mark wrote:

[snip]


However, using http://localhost:8080/ to display the same
generic page (as another ISite), the translations do not happen.

I want to use the 'common' translation domain (TD) across more than
one site (i.e. the use case above would allow me to have a
splash page at the site root using common translations with
a choice among subsites).

So, thinking I should move the 'common' TD to the zope instance
root I use the ZMI cut and paste functions to move the 'common'
domain from MYSITE to the root/global(?) site.  I also checked,
unregistered, and registered where appropriate.

Now the translations for common, formerly functional under
MYSITE, no longer work under MYSITE, nor do they work under the
root site, nor anywhere else.

What gives?  Is there something bad about using cut and paste
to move a translation domain?

How are translation domains looked up and used?  What are their
scopes?


The scope of any local utility (and that includes translation
domains) is the site that it was registered for. It's therefore
not surprising that a translation domain you added and
registered in MYSITE are not available outside that folder.


Ok, fair enough.  That still doesn't explain why moving the 'common'
TD to the [top] 'site' (in the ZMI) didn't 'globalize' it.  Oh well, I
guess it's just another of those unexplained head scratchers that
zope3 seems to be infused with.


Normally this works. You simply have to make sure you unregister the  
translation domain as a utility, move it, and then re-register it in  
the root site again. Even if those steps are messed up, it should  
work if you remember to re-register it with the root site. I wouldn't  
be surprised if you simply forgot that last step.



I was under the impression that
a utility that wasn't found in a local site was searched up-the-stack
to the global site.


Yes, utilities are searched up the stack. If not found in the local- 
most site, then perhaps in the next site, etc, until the root site is  
reached. If that doesn't have it, the global registry isn't searched  
for.



Why aren't you going for global translation domains that are
maintained as gettext PO files on the filesystem and registered
using ZCML? My book (also the 1st edition) explains how to do that.



I have reread the chapter on i18n and will try the ZCML
registerTranslations directive.  Does this guarantee that
all translation domains registered via this directive will
be available *everywhere* in the zope instance?  If so then
I thank you for reminding me about it.  If not, wtf?


Of course they will. That's the point of global components.

Next time I suggest you read the book first ;).


I had wanted to use the GUI in the ZMI for simple testing
before getting to the gettext formalization for the app.


That's fine, though I don't find the gettext way is neither  
formalized nor is it particularly more complicated than the local  
utility stuff (well, ok, you have to compile the .po files  
to .mo...). In the end you're just going to have to write code to  
export your persistent translation domains to .po files on the  
filesystem...



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


RE: [Zope3-Users] Re: User preferences for languages- possible?

2007-02-22 Thread Giovannetti, Mark
Hi Philipp,

You are a great resource, thanks for helping. See below.

 From: [EMAIL PROTECTED] 
 [mailto:[EMAIL PROTECTED] On Behalf Of Philipp 
 von Weitershausen
 Giovannetti, Mark wrote:
  Hi,
  
  This stuff is crazy.  I just want to implement a user
  preference for a language (because I have to).  I've
  read all the user pref. documentation (skinpref, apidoc
  prefs and zope.app.preference) until I'm blue in the
  face.  Nothing seems to work and there is no help via
  google and so forth.
  
  I know that UserPreferences() wants an ILocation object.
  I can't seem to get one inside the BrowserFormLanguages
  class.  I am only given the request object.
  
  What do I need to do?  Getting a root site is insane
  the way I found to do it via a mailing list message.  Not
  to mention it had issues racking up db connections, then
  failing on close.
  
  Help! Please! Thank you!
  
  Preferences seem to work since I can edit them using
  the http://.../++preferences++/ form.
 
 The zope.app.preference stuff stores the info in principal 
 annotations, in a weird way. I personally find that 
 stuff a bit convoluted.

If you find it convoluted, then how are us mere mortals
supposed to deal with it?  ;-)

 
 The key, as you've correctly identified, is write your own 
 IUserPreferredLanguages adapter (or a variant thereof). I would store 
 the user's preferences in a cookie or a session. This makes 
 things much easier. Simply adapt the request to 
 ISession(request).

I'll end up having to do something like this, I suppose.
It really sucks, though, because I *want* to use the
preferences machinery.  Why was it built if it can't be
used in certain places - and why aren't the places it can't
be used documented?  Arrg.  

 
 Note that this might not always work, e.g. when the request is 
 instantiated and the request's locale is first created (because local 
 utilities to store the session data in aren't available at 
 that point). 

How am I supposed to deal with what you say above?  I don't
even understand most of it!  ;-)

 It seems you're hitting that exact problem with the 
 preference stuff as well. The trick here is to stub this 
 out when the adapter is first called, 

'stub this out ... ' - I don't understand, sorry.

 and then later during traversal, when you know the local 
 components are there, you revisit it all again by calling 
 request.setUpLocale() or whatever it is. 

I don't know what you mean.  How is a noob supposed to 
deal with this?

 The ++lang++ implementation might give some pointers.

The ++lang++ implementation (and ensuing errors when I tested using
it) told me that I needed to change BrowserFormLanguages to 
use IModifiableUserPreferredLanguages.  Since I had to do that
in order to allow language preferences I decided to get the
UserPreferences machinery running for the app.  Now I have 
this problem.

The *must* be a common use case.  Why isn't this already solved
and documented as a 'best practice' example?

Mark


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


RE: [Zope3-Users] Re: User preferences for languages- possible?

2007-02-22 Thread Roger Ineichen
Hi Giovanni
 
 Subject: RE: [Zope3-Users] Re: User preferences for 
 languages- possible?
[...]
 The *must* be a common use case.  Why isn't this already 
 solved and documented as a 'best practice' example?

It's all done and implemented. Use the z3c.language package,
there you'll find a INegotiator implementation, language session
and views for switch the language.

As Philipp already said, it's simpler to use a session for
store user releated infos. The Preference is only needed if
you like to store user related data over the time of a session. 

Regards
Roger Ineichen


 Mark
 
 
 ___
 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: User preferences for languages- possible?

2007-02-22 Thread Philipp von Weitershausen

Giovannetti, Mark wrote:
The key, as you've correctly identified, is write your own 
IUserPreferredLanguages adapter (or a variant thereof). I would store 
the user's preferences in a cookie or a session. This makes 
things much easier. Simply adapt the request to 
ISession(request).


I'll end up having to do something like this, I suppose.
It really sucks, though, because I *want* to use the
preferences machinery.  Why was it built if it can't be
used in certain places - and why aren't the places it can't
be used documented?  Arrg.


Well, it's pretty simple, I've tried to outline it to you:

No matter whether you're going the route with sessions or the route with 
the preferences machinery: Both need to store their information 
persistently somewhere. That's why they employ local, persistent 
utilities. Those are only available after certain things have happened: 
the database has been opened and the publisher has successfully 
traversed over the sites that contain registered versions of such 
utilities. Then and only then the getUtility calls work.


The ComponentLookupError you were quoting in your original email is, I 
bet my ass on this, due to the fact that the languages adapter is 
invoked right when the request is instantiated, at which point none of 
the steps I outlined above have happened.


Note that this might not always work, e.g. when the request is 
instantiated and the request's locale is first created (because local 
utilities to store the session data in aren't available at 
that point). 


How am I supposed to deal with what you say above?  I don't
even understand most of it!  ;-)


I'm sorry if I haven't been clear. I also suggest picking up a copy of 
my 2nd edition and reading through the chapter on local sites. It 
explains the concepts of local components.


It seems you're hitting that exact problem with the 
preference stuff as well. The trick here is to stub this 
out when the adapter is first called, 


'stub this out ... ' - I don't understand, sorry.

and then later during traversal, when you know the local 
components are there, you revisit it all again by calling 
request.setUpLocale() or whatever it is. 


I don't know what you mean.  How is a noob supposed to 
deal with this?



The ++lang++ implementation might give some pointers.


The ++lang++ implementation (and ensuing errors when I tested using
it) told me that I needed to change BrowserFormLanguages to 
use IModifiableUserPreferredLanguages.  Since I had to do that

in order to allow language preferences I decided to get the
UserPreferences machinery running for the app.  Now I have 
this problem.


I'll try to be a bit clearer now:

* Your custom language adapter needs to gracefully deal with an absent 
preference machinery. In other words, you should catch that 
ComponentLookupError and fall back to whatever mechanism you want to 
fallback (I suggest you simply fall back to the super class's 
implementation).


* If the preference stuff is correctly set up, normal views invoking the 
translation machinery will get your adapter, there will be no 
ComponentLookupError (because the local site with the persistent 
utilities is active).


* The only problem lies in request.locale which has been initialized too 
early, when the local site wasn't active and when we caught that 
ComponentLookupError and simply ignored it. This should be revisited 
now. I recommend to write an event handler for IBeforeTraverseEvent for 
ISites that re-initializes request.locale. It would look something like 
this:


from zope.component import adapter
from zope.app.component.interfaces import ISite
from zope.app.publication.interfaces import IBeforeTraverseEvent

@adapter(ISite, IBeforeTraverseEvent)
def reinitializeRequestLocale(site, event):
event.request.setupLocale()

Register that using subscriber handler=.reinitializeRequestLocale /.

HTH

--
http://worldcookery.com -- Professional Zope documentation and training
Next Zope 3 training at Camp5: http://trizpug.org/boot-camp/camp5

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


Re: [Zope3-Users] Zope Book: Internationalizing still up to date?

2007-02-22 Thread Vinny
Hi Florian,

Read the chapter in Stephan's book.  It is excellent and is
only out of date on some minor points.  Here's one:

New:

from zope.i18n import MessageFactory
_ = MessageFactory(translationdomain)

This can be found here:  

http://kpug.zwiki.org/WhatIsNewInZope33

See section 7 Porting to Zope 3.3.0 

Stephan's book ties together a good portion of the
details needed for many parts of i18n in zope.

 Any other good sources about i18n?
 

I found the following helpful: 

http://wiki.zope.org/zope3/ZPTInternationalizationSupport

http://wiki.zope.org/zope3/ZPTInternationalizationExamples

I also think that these are useful and up-to-date as far
as I can tell:

http://wiki.zope.org/ZPT/MetalSpecification11
http://wiki.zope.org/ZPT/TALSpecification14

I've just been learning i18n as well so feel free
to post more questions!  Answers are even better. ;-)


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


Re: [Zope3-Users] User preferences for languages- possible?

2007-02-22 Thread Vinny
Hi,

[much snippage]

Try adding the code snippet shown below.  It detects
whether a principal is available and only checks
for preferences if there is one.  
 
class BrowserFormLanguages(BrowserLanguages):
implements(IModifiableUserPreferredLanguages)
 
language_store = []  # ignore this for now
 
def __init__(self, request):
super(BrowserFormLanguages, self).__init__(request)
print created BFL, self.language_store
 
def setPreferredLanguages(self, langs):
#prefs = UserPreferences()
#print prefs.eods.general.language
self.language_store = langs
print set language, self.language_store
 
def getPreferredLanguages(self):
langs =
super(BrowserFormLanguages,self).getPreferredLanguages() 
if self.language_store:
langs = self.language_store + langs
form_lang = self.request.get(Language, None)
if form_lang is not None:
langs.insert(0, form_lang)

# LOOK HERE 
# don't look up preferences unless we have
# something which _has_ preferences!
if self.request.principal != None:
prefs = UserPreferences()
print Prefs, repr(prefs)
# substitute your own 'None' value case.
if prefs.eods.general.language is not None:  
langs.insert(0, prefs.eods.general.language)

print My prefered override, langs
return langs


The principal annotation error seems to be avoided (since
we've made sure we have a principal).  

The language does seem to be set to the preference for page
displays, so what Philipp said about being able to ignore
uninteresting things until we've traversed far enough
was a good hint.

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