Re: [Zope-CMF] [CMF 2.1] opaque items calls make performance issue

2009-08-08 Thread Martin Aspeli
Wichert Akkerman wrote:
 On 2009-8-8 11:53, Hanno Schlichting wrote:
 On Sat, Aug 8, 2009 at 12:14 AM, Charlie Clarkchar...@begeistert.org  
 wrote:
 Is the patch for Plone or CMF?
 It's for Plone, I guess. The problem is solved in Plone 4.0 itself
 (via monkey-patching CMF).

 If it's for CMF then you should consider simply submitting a patch or
 opening a branch. But before you write any package I would like to know a
 little more about what exactly you want to do.
 The problem is the entire concept of opaque items. The only places I
 know they are still in use is the talkback objects as used by the
 discussion machinery in CMF. CMFUid also claims to implement the
 concept, but doesn't actually need any of the functionality, since it
 has its own event subscribers to deal with things.

 So the problem starts in
 CMFCore.CMFCatalogAware.dispatchToOpaqueItems, with the nice line:

 for opaque in ob.opaqueValues():

 which in turn calls later on the opaqueItems method which contains this 
 beauty:

 self_base = aq_base(self)
 for name in self_base.__dict__.keys()
obj = getattr(self, name)
if ICallableOpaqueItem.providedBy(obj):
  items.append((obj.getId(), obj))

That's just *nuts*!

 The whole method redispatches any IObjectEvent fired on an
 IOpaqueItemManager to any opaque item in it. In doing so, it needs to
 load every single entry in the objects __dict__ to see if it is an
 ICallableOpaqueItem.

 It happens that the CMFCatalogAware base class is such an
 IOpaqueItemManager, so any essentially any content object gets this
 treatment.
 
 Could it be that this considers dexterity content to be opaque items? I 
 have some code where events are recursively re-dispatched by CMF and I 
 suspect this is why.

I can't see how that could happen. A Dexterity content item is a CMF 
content item, with the same base classes. And it certainly doesn't 
implement ICallableOpaqueItem.

(Do note that Dexterity has an event handler to do some indexing, 
because in Plone 3/CMF 2.1 at least, it didn't happen automatically).

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] Customised permissions

2009-06-03 Thread Martin Aspeli
Charlie Clark wrote:
 Am 03.06.2009 um 13:05 schrieb Wichert Akkerman:
 
 Not if you use collective.autopermission.
 
 In which it states:
 
 # This is borrowed from Products.CMFCore to avoid a dependency.
 
 Where it states
 
 # XXX This ought to be in AccessControl.SecurityInfo.
 
 :-/


That code is, but not the whole functionality. The functionality to 
register Zope 2 style permissions when a permission / ZCML statement 
is used is new to collectie.autopermission. I merged that back into Zope 
for Zope 2.12, so if you're on 2.12 you're in luck. :)

 It looks like I only need use_mailhost_services which I've hooked up  
 in like this
 
 security = ModuleSecurityInfo('Products.CMFCore.permissions') -  
 should this reflect my module?
 
 security.declarePublic('UseMailHostServices')
 UseMailHostServices = Permissions.use_mailhost_services
 
 in a dedicated permissions module which I just include in the  
 configuration. Although I do like the event handling. Wouldn't it be  
 an idea to put this actually in the CMF?

The point is that Zope 2 permissions spring into existence when you 
start using them in a Module/ClassSecurityInfo. If nothing imports a 
module that has one of those, your permission doesn't exist. Prior to 
Zope 2.12, the permission / directive only used to map Zope 2 
permissions to IPermission utilities, but not actually create new ones.

 I also noticed that the CMF permissions are actually declared in Five.  
 Is there a reason for this? Surely the CMF permission declarations  
 should be in CMFCore

Sure. Historical reasons.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


[Zope-CMF] IIndexableObjectWrapper

2009-04-05 Thread Martin Aspeli
Hi,

Plone 3.3's IIndexableObjectWrapper implementation (in plone.indexer) 
has a method _getWrappedObject(), to return the object that was wrapped 
by the indexable object wrapper. It is (or rather, will be) used by 
TextIndexNG3, which needs to access the raw object during indexing.

Any objections to pushing this down into CMFCore's definition of that 
interface?

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IIndexableObjectWrapper

2009-04-05 Thread Martin Aspeli
Jens Vagelpohl wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 
 On Apr 5, 2009, at 12:14 , Martin Aspeli wrote:
 
 Hi,

 Plone 3.3's IIndexableObjectWrapper implementation (in plone.indexer)
 has a method _getWrappedObject(), to return the object that was  
 wrapped
 by the indexable object wrapper. It is (or rather, will be) used by
 TextIndexNG3, which needs to access the raw object during indexing.

 Any objections to pushing this down into CMFCore's definition of that
 interface?
 
 A method name starting with an underscore is presumably a private  
 method with restricted use by the internal implementation. I would at  
 least rename it to something without underscore before putting it into  
 the interface.

In general, I agree, but there's a problem: any method on the wrapper 
could collide with an index or metadata item and thus get indexed in the 
catalog. Thus, the method is private in the sense that it's not to be 
considered part of the wrapped object.

It may not seem very likely that someone has an index called 
getWrappedObject, but there's (stupid) support in Archetypes to create 
indexes from fields based on the accessors of those fields, so an 
auto-created index for an AT field wrappedObject would default to being 
called getWrappedObject(). Again, not hugely likely, but I think it 
makes sense to say that all methods on the wrapper that are *not* 
indexable are private in this sense.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IIndexableObjectWrapper

2009-04-05 Thread Martin Aspeli
yuppie wrote:
 Martin Aspeli wrote:
 Plone 3.3's IIndexableObjectWrapper implementation (in plone.indexer) 
 has a method _getWrappedObject(), to return the object that was wrapped 
 by the indexable object wrapper. It is (or rather, will be) used by 
 TextIndexNG3, which needs to access the raw object during indexing.
 
 Why is there a need to access the raw object? The wrapper should provide 
 all the interfaces and attributes required for indexing.

TextIndexNG3 does some deeper inspection on the object. It basically 
needs to bypass some of the things that are ordinarily intercepted by 
the wrapper. Andreas Jung will have to give more detail, but it feels 
prudent to me to have some kind of API to get the wrapped object for 
cases like this in any case.

plone.indexer now has this (and we're rapidly approaching a stable 
release - rc2 just went today), so it's not crucial that it's in CMF, 
but it'd be nicer if it were.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] Proposal: Action expression contexts

2009-03-31 Thread Martin Aspeli
Miles wrote:
 Hi,
 
 One of the things that we find slightly cumbersome here in our 
 applications is that when defining actions, there's no easy way to 
 adjust the variables available to an expression.  This tends to make the 
 expressions longer and harder to read, plus commonly used variables are 
 calculated multiple times.
 
 For example, my application has a concept of a page, and I would like 
 to make this available as a variable rather than work it out each time.
 
 Therefore I think it would be useful to adjust getExprContext in 
 CMFCore.Expression so that it is pluggable, by using a factory to create 
 the ExpressionContext.  In that way I can register different ones as 
 required.
 
 Is this a desirable change?

+1

It'd be nice to used named adapters on the context to achieve this. You 
look up all named adapters from the action context to some interface. 
This way, you can plug in new ones, override per type, and override by 
name, if required.

Note that actions are currently a performance bottleneck in Plone. We 
should at least try not to make it slower, and see if we can make it faster.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


[Zope-CMF] Improvements to Discussion Items

2009-03-22 Thread Martin Aspeli
Hi,

I've been working on improving commenting in Plone. I'm not 100% sure 
we'll stay with CMFDefault's idea of Discussion Items forever, but for 
now there are a couple of low-risk things that would make them a lot 
more useful.

  1) Fire an IObjectAddedEvent when a Discussion Item is created
  2) Fire an IObjectRemovedEvent when a Discussion Item deleted
  3) Do not hardcode the review_state of a Discuss Item. This allows 
discussion items to participate in workflow.

  4) Create discussion items based on an IFactory utility rather than 
hardcoding the class.

I've implemented 1-3, along with a simple review workflow and indexers 
that index the number of comments and the people who've commented on a 
content item (to make it easier to find items the current user has 
commented on, and to show the number of comments an item has received in 
a content listing), in a new Plone product, collective.discussionplus. 
There's a file of simple monkey patches to CMFDefault here:

http://dev.plone.org/collective/browser/collective.discussionplus/trunk/collective/discussionplus/patches.py

Would it be useful to push this down into CMF itself? I can't promise I 
have time to do that (with tests) in the short term, but I'm happy to 
help anyone who wants to do it. I may find time later, of course.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-11 Thread Martin Aspeli
yuppie wrote:

 Why is IIndexableObjectWrapper in Plone a multi-adapter and not a simple 
 adapter for object?

Some of the indexers need access to the site root. I think the idea was 
that you could have different adapters in different types of sites by 
marking the site root, but a single adapter is probably enough.

 Could we push this further down the stack to the ZCatalog, making it 
 unnecessary to override catalog_object in CMF? AFAICS all CMF-specific 
 stuff could be done inside the wrapper.

Maybe. Touching ZCatalog is kinda scary, though.

 Still, the important use case, imho, is to make custom indexers for 
 your custom types. I quite like the pattern in plone.indexer where we 
 use an annotation to make a function into an indexer adapter:

 http://pypi.python.org/pypi/plone.indexer
 
 I agree that's an important use case, but looking up 
 IIndexableObjectWrapper based on the object provides already a solution 
 for it. So we have a basic solution inside the framework and hook for 
 plugging in alternative solutions like plone.indexer.

Yep, I think that's a good idea.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-10 Thread Martin Aspeli
Jens Vagelpohl wrote:

 That's not the issue I was trying to address. I was specifically  
 talking about putting functionality in the most appropriate part of  
 the stack, meaning moving it further towards the core. If there are  
 bits and pieces that make more sense in the CMF then saying well,  
 just install our package may satisfy users, but developers will  
 continue wasting time maintaining different implementations.

I think we all agree on this. In retrospect, it would've been a better 
idea to push for plone.indexer to be a part of CMF. However, I 
implemented it driven by Plone's release cycle and feature proposal 
process, which is why it ended up as it did. *I* want this feature for 
Plone, but it'd be even better if others could benefit.

Of course, it's not too late for that. If the license issue can be 
overcome (and I'm pretty sure that it will by April/May), then CMF can 
depend on plone.indexer if it so wants, and I'm willing to help make 
that possible if it means changing plone.indexer or helping with the CMF 
level implementation.

In the future, it may be that we can meet in the middle on this. When 
the PLIP process kicks off, it'd be good if the CMF developers had a 
look in as well. We should probably be better at announcing the various 
deadlines and proposals on this list, but if you guys see something that 
you feel would be a good fit further down, it doesn't hurt to raise 
that, lest the developer hasn't thought about it.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-10 Thread Martin Aspeli
yuppie wrote:
 Hi!
 
 
 Wichert Akkerman wrote:
 Previously Jens Vagelpohl wrote:
 That's not the issue I was trying to address. I was specifically  
 talking about putting functionality in the most appropriate part of  
 the stack, meaning moving it further towards the core. If there are  
 bits and pieces that make more sense in the CMF then saying well,  
 just install our package may satisfy users, but developers will  
 continue wasting time maintaining different implementations.
 Why would there be multiple implementations if they can just use the
 existing one? I do not see that.
 
 For the CMF project it is essential to have full control over its own 
 layer of the stack and to participate in the development of the Zope 
 layer. Using packages from the Plone repository means either using them 
 as a black box or joining the Plone Foundation to participate in their 
 development. IMO both options are not acceptable.

You don't need to join the Plone Foundation to develop packages in 
svn.plone.org. You *do* need to sign a contributor agreement granting 
some IP rights over that code to the Plone Foundation, in return for a 
promise that it will always be available under an open source license. 
There are no limits on who can sign that agreement or for what purpose 
they choose to work with the code in that repository.

Of course, the same goes for svn.zope.org: you need to sign a document 
and grant certain rights over your work to the Zope Foundation.

If CMF really cannot use packages not in svn.zope.org, then that's a bit 
sad and will invariably lead to a lot of re-invention rather than 
re-use. I don't really understand why it is essential to have this 
level of control over every line of code you use. This is entirely a 
self-imposed restriction.

 I do agree that work should be in in
 CMF itself, and this particular instance of the indexable wrappers is an
 excellent example of that. I hope that in the last few years we have
 already demonstrated that we really do want to work closer with the
 CMF and Zope communities. 
 
 For technical reasons this collaboration is asymmetric. Plone is built 
 on top of Zope and CMF, not the other way round. If you want to work 
 really close with these communities, you have to be part of them and use
 their repository.

I wrote a package that, I hope, is useful. I am pretty sure it'll work 
with plain CMF and therefore with other consumers of the CMF, and if 
doesn't, I'd consider that a bug and fix it. I'm willing to work to make 
that package a part of the CMF platform, whether optional or fully 
integrated.

To a certain extent, it already is: someone suing the CMF can choose to 
use plone.indexer in their own project, though they'll need to install 
it themselves. I don't quite see how this is asymmetric. Rather, it is 
an outcome of the evolution of this particular package.

It's up to the CMF maintainers to decide whether it is desirable to 
actually adopt this package as part of a standard release.

It's not always going to be appropriate (or even if it is, it's not 
always going to be the case) for every new line of code that *could* be 
useful to all/most CMF consumers to be built as part of the CMF itself 
from the outset. If the CMF project has no model for incorporating code 
from outside its (rather small) community, then I think that is more to 
the detriment of CMF than to those who created those packages and chose 
to put the effort in to reduce their dependencies and make them more 
generally useful.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-10 Thread Martin Aspeli
Hi Miles,


 This should work with plain CMF and be simple to hook into the catalogue 
 tool.
 
 (For me) this is the root of the problem - it can only be hooked into 
 the catalog by subclassing at the moment, there is no other mechanism to 
 use different implementations.  If there was, then plone.indexer (or 
 whatever) could be used directly.
 
 Therefore, can I make a proposal (which I am happy to carry out), as I 
 think this is a desirable change?
 
 PROPOSAL: Use CA to look up the indexable object wrapper

+1 - Plone already has this, and it's pretty easy to do. If CMF got 
this, then Plone could drop its own custom adapter and use the CMF one 
to hook in plone.indexer, as could anyone else wanting to use this package.

 PROBLEM: It is not possible to provide alternative implementations of 
 the IndexableObjectWrapper class at the moment - this prevents 
 customising the indexing process.
 
 SOLUTION: Look up the IndexableObjectWrapper using the Component 
 Architecture.  The catalog tool will look up a named utility that 
 creates a wrapped object suitable for indexing.

Actually, I'd suggest you look it up as an adapter on the object being 
indexed. Also, it probably shouldn't be named, as there's nothing to 
switch the name on.

 The default implementation of the utility will return the object 
 wrapped using the current IndexableObjectWrapper.
 
 If required, Local Site configuration can be used to provide different 
 implementations as needed.
 
 BACKWARDS COMPATIBILITY: Any catalog implementation that used a 
 different wrapper class would have to subclass the main catalog and 
 override the relevant function, so will be unaffected by the change.
 
 Any thoughts?

+1 in general

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-10 Thread Martin Aspeli
Jens Vagelpohl wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 
 On Mar 10, 2009, at 11:08 , Martin Aspeli wrote:
 
 I think we all agree on this. In retrospect, it would've been a better
 idea to push for plone.indexer to be a part of CMF. However, I
 implemented it driven by Plone's release cycle and feature proposal
 process, which is why it ended up as it did. *I* want this feature for
 Plone, but it'd be even better if others could benefit.
 
 IMHO the release cycle argument doesn't wash. We've always had CMF  
 releases in preparation for important Plone releases, and I'm happy to  
 continue that.

I'm not arguing. I'm saying that it didn't really cross my mind, because 
I was improving something that was already Plone specific (the 
ExtensibleIndexableObjectWrapper) in response to a Plone demand and 
working towards a Plone deadline. Hindsight is a good thing, and maybe 
it would've been better to try to all of it down into the stack. In this 
case, I didn't.

Except that I kind of did... I created a package with no other Plone 
dependencies, in the hope that it *could* be useful. I didn't take the 
time to discuss it on this list, which I should have. However, the 
desire for it to be re-usable by other CMF consumers is clearly in evidence.

 Of course, it's not too late for that. If the license issue can be
 overcome (and I'm pretty sure that it will by April/May), then CMF can
 depend on plone.indexer if it so wants, and I'm willing to help make
 that possible if it means changing plone.indexer or helping with the  
 CMF
 level implementation.
 
 Thanks, I appreciate that.
 
 Generally, I think now that the ZF has cleared up the remaining issues  
 about code ownership etc. we finally have two entities, the ZF and the  
 Plone Foundation, that are the perfect platform for official issues  
 like code donations, or for coordinating other cooperation issues. I  
 can't judge how the Plone Foundation acts within the Plone community,  
 but as far as the Zope Foundation goes, Martijn has been doing a lot  
 of work to make it more relevant and an important player in the actual  
 software development process.

Indeed!

Bear in mind that the Plone Foundation has an explicit goal *not* to 
interfere with software development. However, it does deal with issues 
of IP and so I agree the two foundations are the right forum for this 
type of thing.

 In the future, it may be that we can meet in the middle on this. When
 the PLIP process kicks off, it'd be good if the CMF developers had a
 look in as well. We should probably be better at announcing the  
 various
 deadlines and proposals on this list, but if you guys see something  
 that
 you feel would be a good fit further down, it doesn't hurt to raise
 that, lest the developer hasn't thought about it.
 
 Is there any kind of low-traffic announcement list for things like  
 PLIPs? I'm not subscribed to any Plone list because of (for me at  
 least) signal to noise ratio fears.

There's plone-announce, but I don't think this was announced there. I 
actually think the Plone release manager should cross-post a few 
important announcements to this list, though.

The actual feature discussion happens on the medium-traffic 
framework-team list, which you can join. In fact, it'd be great if you 
did, as we'd appreciate your input, but I realise it may not be 
something you want to spend a lot of time on.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-10 Thread Martin Aspeli
yuppie wrote:

 AFAICS wrapping the object before looking up adapters is unnecessary. 
 The catalog should do the lookup directly and the existing features 
 provided by IndexableObjectWrapper should be reimplemented as adapters.

Bear in mind that there is a difference between getting the wrapper 
itself, and getting the value to catalogue for a particular *attribute* 
of the wrapper (e.g. allowedRolesAndUsers).

The CatalogTool subclass in Plone solves the former. plone.indexer uses 
the hook it puts in place to solve the latter.

I think at a minimum, CMF should just make the whole wrapper swappable 
by looking it up as an adapter. Then people could choose to use 
plone.indexer if they so needed (we'd obviously need to change 
plone.indexer to provide an appropriate adapter based on a CMF interface 
rather than a Plone one, and then deprecate the Plone version). For 
smaller applications, it may just be unnecessary complexity.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-09 Thread Martin Aspeli
Miles wrote:
 Hi,
 
 Can anyone tell me if it is possible to register an adapter to provide a 
 different IndexableObjectWrapper class from the stock CMF one?  There's 
 some sort of framework code that hints that it ought to enable this, but 
 I can't see how!
 
 The code still seems to instantiate the wrapper directly using the 
 class, rather than looking it up via the component architecture.
 
 Can anyone explain what's going on?  I've drawn a blank from googling 
 for examples.

In plain CMF, probably not. In Plone, we have a custom CatalogTool which 
does let you provide a new wrapper wholesale based on object type.

In Plone 3.3, we'll *also* have a means of providing individual 
*attributes* of the wrapper via adapters. See 
http://pypi.python.org/pypi/plone.indexer. This package should work with 
stock CMF (though you'll need to wire it into the catalog tool yourself).

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] IndexableObjectWrapper

2009-03-09 Thread Martin Aspeli
Jens Vagelpohl wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 
 On Mar 9, 2009, at 22:47 , Wichert Akkerman wrote:
 
 Previously Jens Vagelpohl wrote:
 On Mar 9, 2009, at 21:09 , Miles wrote:

 Can anyone tell me if it is possible to register an adapter to
 provide a
 different IndexableObjectWrapper class from the stock CMF one?

 You already noticed that the wrapper is instantiated directly, so
 that's what's going on. No magic, no component architecture.

 Whether that is good or bad or should be changed is a different  
 issue.
 Martin Aspeli implemented an adapter based index wrapper for Plone  
 3.3.
 
 It's nice to see that Plone has it, but that doesn't help anyone  
 working off the CMF itself. I wish there was more communication to  
 determine where improvements fit best. Not knowing how Plone  
 implemented it I would make a guess this one small item would have  
 been better off in the CMF itself.

Point taken!

Back in the day (before Plone 3.0), Alec Mitchell and I implemented a 
simple wrapper adapter that lets you look up a different version of the 
IndexableObjectWrapper. However, this wasn't terribly useful, because it 
seems what people want is not to replace the wrapper wholesale, but to 
provide different 'indexers' for specific catalogued attributes on a 
per-type basis.

Even before that, Plone had its own ExtensibleIndexableObjectWrapper 
that let you add 'getters' for attributes on the wrapper via module 
level imports. This has worked well, except that there's no way to make 
particular indexers work only on one particular content type.

In Plone 3.3, with the plone.indexer package, we've changed this so that 
you can add new 'getters' to the standard IOW via adapters. This is in 
the plone.indexer package: http://pypi.python.org/pypi/plone.indexer

This should work with plain CMF and be simple to hook into the catalogue 
tool. There are some discussions about licensing going on with the Plone 
Foundation, but chances are good that it can be licensed in such a way 
that CMF could adopt it you want. Doing so should be simple, even, and 
I'd be willing to help make this happen.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] CMF 2.2 plans?

2009-03-01 Thread Martin Aspeli
Jens Vagelpohl wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 
 On Mar 1, 2009, at 04:01 , Martin Aspeli wrote:
 
 Jens Vagelpohl wrote:

 Are there _specific_ dependencies on unreleased code that would
 require new eggs? Let's identify which specific eggs are needed and
 concentrate on those first.
 I am currently relying on backports/monkey patches for the add form
 stuff in code that may be part of Plone 4 at some point. It'd be  
 nice to
 be able to avoid those. The patches are:

  - Add the add view expression to the FTI type
  - Add the related code to the TypesTool
  - The ++add++ traverser

I think they're all in Products.CMFCore.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] CMF 2.2 plans?

2009-03-01 Thread Martin Aspeli
Jens Vagelpohl wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 
 On Mar 1, 2009, at 10:50 , Martin Aspeli wrote:
 
 Jens Vagelpohl wrote:
 On Mar 1, 2009, at 04:01 , Martin Aspeli wrote:

 Jens Vagelpohl wrote:

 Are there _specific_ dependencies on unreleased code that would
 require new eggs? Let's identify which specific eggs are needed and
 concentrate on those first.
 - Add the add view expression to the FTI type
 - Add the related code to the TypesTool
 - The ++add++ traverser
 I think they're all in Products.CMFCore.
 
 I'll look at CMFCore and CMFDefault over the next few days (I'm  
 traveling). Are there any code changes that you still need or is the  
 current trunk state ready to be released from your point of view?

I haven't looked into it in great detail, but from what I can tell, 
these things are al stable. Yuppie would know best, though.

Thanks!

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] CMF 2.2 plans?

2009-02-28 Thread Martin Aspeli
Jens Vagelpohl wrote:

 Are there _specific_ dependencies on unreleased code that would  
 require new eggs? Let's identify which specific eggs are needed and  
 concentrate on those first.

I am currently relying on backports/monkey patches for the add form 
stuff in code that may be part of Plone 4 at some point. It'd be nice to 
be able to avoid those. The patches are:

  - Add the add view expression to the FTI type
  - Add the related code to the TypesTool
  - The ++add++ traverser

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests



Re: [Zope-CMF] CMF add views and browser:page /

2008-12-11 Thread Martin Aspeli
Hi Yuppie,

 Mmmm... I'm not sure most people would find it natural to think about 
 the add form as an adapter like this.
 Well. I find it natural to think about browser pages as a special kind 
 of adapters. 
 Having explained this to a lot of different people with different levels 
 of experience, I think natural is too strong a word for most people. 
 The fact that browser views are adapters is an implementation detail 
 that often give people an aha! type reaction when they really 
 understand it. However, a lot of people will use browser views for a 
 long time without really understanding adapters (if they ever do or care).
 
 Well. I guess it depends on your perspective. For Plone users adapters 
 might be implementation details, for others they are important tools for 
 solving many different problems.

Adapters are of course important tools. However, the fact that browser 
pages are named multi-adapters that provide Interface and adapt the 
context object and the request, normally via a marker interface called a 
layer that's applied to the request during traversal, is an 
implementation detail, and one that requires quite a lot of explanation 
and even then doesn't make a whole lot of sense unless you are quite 
familiar with Zope 3's brand of the adapter pattern. It took me 32 words 
to state that as completely and concisely as I could, without even 
explaining any of the concepts.

The concept of a named multi-adapter is an order of magnitude more 
advanced than, say, page templates skin layers or the concept of having 
a class/template that's registered in an XML file. People who are not 
steeped in software design patterns can learn the latter quite quickly. 
They struggle with the former, Plone user or not.

 Providing customized solutions for specific use cases makes it easier to 
 solve these use cases, but it also makes the framework more complex and 
 less framework-ish.

Then why do we have browser:page /?

You could of course do:

adapter
   for=.interfaces.IMyType
Products.CMFDefault.interfaces.ICMFDefaultLayer
   provides=zope.interface.Interface
   name=myview
   factory=.myview.MyView
   /
class class=.myview.MyView
   require
   permission=zope2.View
 
allowed_interface=zope.publisher.interfaces.browser.IBrowserPage
   /
/class


 I can't see a need for the directive you propose. 
 But if you also volunteer to maintain the additional code in the long 
 run, I can live with it.

I can probably do that, but I'd like to know if others agree. I actually 
don't have an immediate need for it myself, since I've implemented the 
same thing for my specific use case using a martian grokker, but I 
suspect people would prefer an analogue to browser:page / rather than 
having to register their add views manually.

If we want people to use add forms (in Plone we certainly do - premature 
object creation sucks), then we need to make it easy to do so.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] CMF add views and browser:page /

2008-12-09 Thread Martin Aspeli
Martin Aspeli wrote:
 Hi Yuppie,
 
 It is not obvious why you have to use explicit Zope 2 style security for 
 add views and declarative Zope 3 style security for other views. But I'd 
 rather like to see the 'permission' attribute of adapter / implemented 
 for Zope 2 instead of a new cmf:addview / directive.
 Mmmm... I'm not sure most people would find it natural to think about 
 the add form as an adapter like this.
 Well. I find it natural to think about browser pages as a special kind 
 of adapters. 
 
 Having explained this to a lot of different people with different levels 
 of experience, I think natural is too strong a word for most people. 
 The fact that browser views are adapters is an implementation detail 
 that often give people an aha! type reaction when they really 
 understand it. However, a lot of people will use browser views for a 
 long time without really understanding adapters (if they ever do or care).
 
 And since add forms don't fulfill all the special criteria 
 for browser:page /, we have to fall back to the more generic adapter /.
 
 Right. But there's a reason why browser:page / is special. 
 Logically, views and adapters are quite different things, and, of 
 course, browser:page / does a lot more than just register an adapter.
 
 Also, Five's browser:page / does quite a lot of stuff that we now 
 can't have for CMF add views:

  o It allows a template to be registered
  o It allows an attribute other than __call__ to be used to render 
 the view
  o It sets up security on attributes, by interface or explicit list
  o It sets up security on the view class itself
 Sure. The question is: Do we really need these features for add views?

 I don't think the adapter permission attribute would be sufficient in 
 any case. In Zope 3, it's tied to a type of low-level security proxy 
 that doesn't really exist in Zope 2. The ClassSecurityInfo stuff only 
 affects restricted python/traversal, whereas Zope 3 security proxies are 
 applied everywhere.
 AFAICS I didn't register the add views correctly. Provided interface 
 should be IBrowserPage or IPageForm, not IBrowserView.

 Given that, in the Zope 3 world adapter /'s 'permission' attribute and 
 browser:page /'s 'permission' attribute would do the same: Creating a 
 security checker that protects 'browserDefault', '__call__' and 
 'publishTraverse' by the specified permission. Or am I missing something?
 
 I'm not sure. Zope 2 doesn't really have a concept of security outside 
 restricted python/traversal, so the translation form Zope 3 is always 
 going to be a bit odd.
 
 Currently this is not true for Zope 2. While Five implements Zope 2 
 specific behavior for browser:page /'s 'permission' attribute, the 
 same attribute of adapter / is useless in Zope 2.
 
 I wonder why this is, though. There's probably a reason why the Five 
 developers didn't want to extend the security stuff to the adapter / 
 registration.
 
 I can't see a fundamental problem in using the generic adapter directive 
 for registering browser pages. I just see limited support for the 
 adapter directive in Zope 2. As long as these issues are not resolved, I 
 can live with Zope 2 security declarations in add views.
 
 FWIW, I think this'll work:
 
  adapter
  for=Products.CMFCore.interfaces.IFolderish
   zope.publisher.interfaces.browser.IBrowserRequest
   ..interfaces.IDexterityFTI
  provides=zope.publisher.interfaces.browser.IBrowserView
  factory=.add.DefaultAddView
  /
  class class=.add.DefaultAddView
  require
  permission=cmf.AddPortalContent
  interface=zope.publisher.interfaces.browser.IBrowserView
  /
  /class
 
 I don't much like it, though. :-/
 
 I'd wager this is a lot closer to what people would expect:
 
cmf:addview
   for=Products.CMFCore.interfaces.IFolderish
   fti=..interfaces.IDexterityFTI
   class=.add.DefaultAddView
   permission=cmf.AddPortalContent
   /

Meh - of course, I meant:

 cmf:addview
name=my.type
for=Products.CMFCore.interfaces.IFolderish
fti=..interfaces.IDexterityFTI
class=.add.DefaultAddView
permission=cmf.AddPortalContent
/

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] CMF add views and browser:page /

2008-12-09 Thread Martin Aspeli
Hi Yuppie,

 It is not obvious why you have to use explicit Zope 2 style security for 
 add views and declarative Zope 3 style security for other views. But I'd 
 rather like to see the 'permission' attribute of adapter / implemented 
 for Zope 2 instead of a new cmf:addview / directive.
 Mmmm... I'm not sure most people would find it natural to think about 
 the add form as an adapter like this.
 
 Well. I find it natural to think about browser pages as a special kind 
 of adapters. 

Having explained this to a lot of different people with different levels 
of experience, I think natural is too strong a word for most people. 
The fact that browser views are adapters is an implementation detail 
that often give people an aha! type reaction when they really 
understand it. However, a lot of people will use browser views for a 
long time without really understanding adapters (if they ever do or care).

 And since add forms don't fulfill all the special criteria 
 for browser:page /, we have to fall back to the more generic adapter /.

Right. But there's a reason why browser:page / is special. 
Logically, views and adapters are quite different things, and, of 
course, browser:page / does a lot more than just register an adapter.

 Also, Five's browser:page / does quite a lot of stuff that we now 
 can't have for CMF add views:

  o It allows a template to be registered
  o It allows an attribute other than __call__ to be used to render 
 the view
  o It sets up security on attributes, by interface or explicit list
  o It sets up security on the view class itself
 
 Sure. The question is: Do we really need these features for add views?
 
 I don't think the adapter permission attribute would be sufficient in 
 any case. In Zope 3, it's tied to a type of low-level security proxy 
 that doesn't really exist in Zope 2. The ClassSecurityInfo stuff only 
 affects restricted python/traversal, whereas Zope 3 security proxies are 
 applied everywhere.
 
 AFAICS I didn't register the add views correctly. Provided interface 
 should be IBrowserPage or IPageForm, not IBrowserView.
 
 Given that, in the Zope 3 world adapter /'s 'permission' attribute and 
 browser:page /'s 'permission' attribute would do the same: Creating a 
 security checker that protects 'browserDefault', '__call__' and 
 'publishTraverse' by the specified permission. Or am I missing something?

I'm not sure. Zope 2 doesn't really have a concept of security outside 
restricted python/traversal, so the translation form Zope 3 is always 
going to be a bit odd.

 Currently this is not true for Zope 2. While Five implements Zope 2 
 specific behavior for browser:page /'s 'permission' attribute, the 
 same attribute of adapter / is useless in Zope 2.

I wonder why this is, though. There's probably a reason why the Five 
developers didn't want to extend the security stuff to the adapter / 
registration.

 I can't see a fundamental problem in using the generic adapter directive 
 for registering browser pages. I just see limited support for the 
 adapter directive in Zope 2. As long as these issues are not resolved, I 
 can live with Zope 2 security declarations in add views.

FWIW, I think this'll work:

 adapter
 for=Products.CMFCore.interfaces.IFolderish
  zope.publisher.interfaces.browser.IBrowserRequest
  ..interfaces.IDexterityFTI
 provides=zope.publisher.interfaces.browser.IBrowserView
 factory=.add.DefaultAddView
 /
 class class=.add.DefaultAddView
 require
 permission=cmf.AddPortalContent
 interface=zope.publisher.interfaces.browser.IBrowserView
 /
 /class

I don't much like it, though. :-/

I'd wager this is a lot closer to what people would expect:

   cmf:addview
  for=Products.CMFCore.interfaces.IFolderish
  fti=..interfaces.IDexterityFTI
  class=.add.DefaultAddView
  permission=cmf.AddPortalContent
  /

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


[Zope-CMF] CMF add views and browser:page /

2008-12-08 Thread Martin Aspeli
Hi,

Thanks to yuppie, trunk now allows us to use the ++add++type 
traverser, which will look up an add view as an adapter on (context, 
request, fti) with name equal to fti.factory.

This is good, but it does mean that those add views cannot be registered 
with a browser:page / directive. Unfortunately, Five's browser:page 
does quite a lot of stuff, from allowing a template to be specified, to 
setting up class and attribute level security, to supplying a docstring 
if required to allow publication.

In CMFDefault, we have some base classes (tied to formlib) and we do 
manual security with a ClassSecurityInfo and InitializeClass(). This 
feels like a step backwards to me, at least in Plone, where we encourage 
people to use browser views with declarative (ZCML) security. It's 
difficult to explain that add forms are special so that they need to 
have manual security, explicit docstrings (for better or for worse), and 
be registered as an adapter /, not a browser:page /.

Did we envisage a solution to this? How about a new cmf:addview / 
directive that mimics browser:page /, but registers the 
(context,request,fti) adapter? I could probably put that together if 
people think it's a good idea.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] Customising types with add views

2008-12-08 Thread Martin Aspeli
yuppie wrote:
 Hi Martin!
 
 
 Martin Aspeli wrote:
 [...]

 Let's consider a type Alpha that has a custom add form registered as 
 such a (context, request, fti) adapter with name Alpha. fti.factory is 
 Alpha, and there's a corresponding IFactory utility (with name Alpha).

 Now, let's say I want to create a new type Beta (e.g. by copying the FTI 
 object TTW), based on Alpha. I want this to use Alpha's add form, but 
 construct objects with portal_type Beta.

 Is this possible? If I set Beta's fti.factory to be something other than 
 Alpha, then it won't find the add view, but if fti.factory is Alpha 
 then the objects constructed will use Alpha's factory.
 
 You should be able to register the same add view twice. One registration 
 for the name Alpha and one for the name Beta.

Sure. I was thinking more about the case of customising by copying the 
FTI TTW.

 I can't quite decide whether this is a problem in real life or not, 
 although it does seem a bit strange that the add view adapter name and 
 the factory utility name have to be the same.

 Would it make sense to decouple these, e.g. with a new add_view_name 
 property?
 
 If people really have that problem we can decouple this later. For now I 
 can't see a need.

I suspect it's YAGNI since the add view calls _setPortalTypeName() on 
the newly created instance as well, so the resulting object will have 
type Beta, not type Alpha.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] CMF add views and browser:page /

2008-12-08 Thread Martin Aspeli
yuppie wrote:
 In CMFDefault, we have some base classes (tied to formlib) and we do 
 manual security with a ClassSecurityInfo and InitializeClass(). This 
 feels like a step backwards to me, at least in Plone, where we encourage 
 people to use browser views with declarative (ZCML) security. It's 
 difficult to explain that add forms are special so that they need to 
 have manual security, explicit docstrings (for better or for worse), and 
 be registered as an adapter /, not a browser:page /.

 Did we envisage a solution to this?
 
 No.
 
 How about a new cmf:addview / 
 directive that mimics browser:page /, but registers the 
 (context,request,fti) adapter? I could probably put that together if 
 people think it's a good idea.
 
 CMF add views are different because they are looked up by a special 
 traverser, using the additional type info object. You have to be aware 
 of that. No matter if you use adapter / or cmf:addview /.

Sure.

 It is not obvious why you have to use explicit Zope 2 style security for 
 add views and declarative Zope 3 style security for other views. But I'd 
 rather like to see the 'permission' attribute of adapter / implemented 
 for Zope 2 instead of a new cmf:addview / directive.

Mmmm... I'm not sure most people would find it natural to think about 
the add form as an adapter like this.

Also, Five's browser:page / does quite a lot of stuff that we now 
can't have for CMF add views:

 o It allows a template to be registered
 o It allows an attribute other than __call__ to be used to render 
the view
 o It sets up security on attributes, by interface or explicit list
 o It sets up security on the view class itself

I don't think the adapter permission attribute would be sufficient in 
any case. In Zope 3, it's tied to a type of low-level security proxy 
that doesn't really exist in Zope 2. The ClassSecurityInfo stuff only 
affects restricted python/traversal, whereas Zope 3 security proxies are 
applied everywhere.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] Should portal_setup be registered as utility?

2008-11-18 Thread Martin Aspeli
yuppie wrote:
 Hi Dieter!
 
 
 Dieter Maurer wrote:
 Thus, why do local utilities registered by Five (i.e. these utilities are
 for Zope2 use) do not provide access to the request in the normal
 Zope2 way?
 
 That's what we tried first. But it turned out that Zope 3's site manager 
 code caches the utilities across request boundaries. AFAICT it would 
 have been necessary to rewrite the registry code completely to make sure 
 we return always the right request.
 
 If they would, local utilities were much nearer to tools and
 the transition would be facilitated.
 
 They would be nearer to tools, but also more distant from zope 3 
 utilities. I doubt that would really be a win.

This won't solve this particular problem, but it may be worth looking at 
how other frameworks work. Pylons, for example, has the request 
available as global variable - actually a thread-local. Zope could set 
the request as a thread local in the same way that it sets the site 
manager (so you can get it via getSite()). Calling getRequest() would in 
many ways be cleaner than doing self.context.REQUEST or whatever, and 
would work regardless of whether the context was acquisition wrapped.

Cheers
Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] 'add' actions and views - a proposal

2008-09-21 Thread Martin Aspeli
Hi Yuppie,

 1.) CMF add views adapt not only container and request, but also the 
 type info object. This way the views can't be accessed directly and have 
 self.fti available.
 This is quite interesting, and possibly necessary. However, it means 
 that CMF add views are not just views and will need to be registered 
 differently to other views (i.e. you can't just use browser:page / 
 which also means that you won't get the Five security treatment etc).
 
 Yes. This causes more problems than it solves. I think I found a much 
 better solution:
 
 CMF add views are registered for a special layer called IAddViewLayer. 
 Like any other layer, IAddViewLayer extends IBrowserRequest. And it 
 defines an additional 'ti' attribute for the request.
 
 Like before views can't be accessed directly and have self.ti available. 
 (I now use 'ti' instead of 'fti' because we have other type info 
 implementations than FactoryTypeInformation.)

I'm not sure I like this much more. It involves adding a marker 
interface to the request conditionally during traversal. You'll possibly 
run into funny sequence dependent conditions if you want to customise 
the add view for a particular theme browser layer.

My preference would be:

  - Define an interface IFTIAwareView that has an 'fti' property
  - Define a traversal view (@@add) that does this kind of thing on 
traversal:

  addview = queryMultiAdapter((self.context, request), name=name)
  if IFTIAwareView.providedBy(addview):
  addview.fti = fti
  return addview.__of__(self.context)

or something to that effect.

This keeps the view that the developer writes close to a real view 
that can be customised in the normal ways. Of course, it can only be 
traversed to via the traversal adapter, but I think this'll be the case 
no matter what.

 3.) A traversal hook looks up the type info based on the view name. And 
 then returns the corresponding add form:
 queryMultiAdapter((container, request, fti), name=fti.factory)
 Why do we need to *both* adapt the FTI and use the factory name as the 
 view name?
 
 Because we want to use different views for different content factories 
 *and* pass the type info to the view. This way we don't depend on an 
 environment that sets the ti value later. And all view methods work from 
 the beginning without fallback code for a missing ti.

The addview definitely needs to know which FTI it's being used for. 
However, in the case above, you could just have it be an unnamed 
adapter, since self.fti.factory will always equal self.__name__ in the 
view, no?

 As mentioned above, I now propose to pass in the type info as part of 
 the request object.

Right. I'm not sure this is naturally something that belongs in the 
request, though.

 6.) An IPublishTraverse adapter is used for IFolderish objects. It tries 
 to resolve names starting with '+' and falls back to 
 DefaultPublishTraverse behavior if no add view is found. This way URLs 
 like http://www.example.org/folder/+PortalType are supported.
 -1

 Or maybe -10 now that I think about it a bit more...
 
 I also started with -1, but thinking a bit more about it my vote is +1.

Why? Why is the +PortalType convention so important? It's not used 
elsewhere, and it means dictating a convention that developers must know 
about and follow.

Moreover, this convention currently means something else in Plone. :)

In plone.app.contentrules, for example, we have a +condition view 
that's very similar to the + view; it provides IConditionAdding that's 
analogous to IAdding (provided by +). I'm pretty sure your proposed 
traverser would conflict and screw up the +condition (and +action and 
+portlet) views we have there already, necessitating complex workarounds 
that would need to be aware of the semantics of multiple packages.

 This is pretty invasive. It'd make it impossible to have another 
 IPublishTraverse adapter for any IFolderish without either subclassing 
 from the CMFDefault one or breaking all add forms.
 
 Shrug. That is how the IPublishTraverse adapter works. There are many 
 use cases for the IPublishTraverse hook and only one available slot.

So you want CMF to steal that slot for *all* folders?

 You 
 never can be sure that this hook is free. If you write your own 
 IPublishTraverse adapter, you always have to look at the code base and 
 subclass those adapters you want to use.

Well, you can avoid writing the one adapter for a very generic 
interface. In the @@add case, CMF provides *one* view (i.e. we reserve 
the name @@add for any IFolderish) and traversal continues from that view.

Put differently, traversal from a folder is complex, but also well 
established. You travese into attributes/contained objects or views. 
Traversal from a new @@add view does not have any pre-existing 
semantics. We can choose exactly what we do with the traversal sub-path. 
We don't need to derive from the default IPublishTraverse at all.

 Rather than invent a pseudo namespace with a naming 

Re: [Zope-CMF] [dev] add view traversal

2008-09-14 Thread Martin Aspeli
Jens Vagelpohl wrote:

 b) for URLs like http://www.example.org/guestbook/+/Message

 The '+' view already implements IPublishTraverse, so we can't change
 traversal using an adapter. The only solution I can see is to replace
 the '+' view by a customized version.
 
 This looks like a good solution. I believe Zope 3 uses the same or a  
 similar style.

I don't think we can do this. The + view implements IAdding which has 
special semantics. Existing types are likely to rely on + being an 
IAdding view.

Zope 3 does use IAdding for zope.app.form/zope.formlib based add views; 
With z3c.form, IAdding support is optional, but the preference is to 
just use views like @@add-foo.html (note: I hate the .html convention; 
it is superfluous and looks weird, IMHO).

I think it's better to use a different name. For plone.dexterity, I've 
done this:

http://dev.plone.org/plone/browser/plone.dexterity/trunk/plone/dexterity/browser/add.py

The add view traverser is called @@add-dexterity-content. It's 
deliberately framework-specific since I want particular semantics (a 
default add view based on FTI information only if no type-specific add 
view is registered). That's all fine, though, since we look up the exact 
URL for add view in an action anyway. We don't need a one-size-fits all 
traverser (which the + view had to be).

I'm monkey patching the TypesTool to backport the changes Yuppie already 
made to CMF trunk to support folder/add actions.

For CMF, how about a simple @@add or maybe @@add-content?


 3.) For which context should we register the add views?
 ---

 The add views will depend on special portal type handling done by the
 traverser. So we register the add views for traverser?

No. That's how IAdding works, and it's basically what we're trying to 
avoid. If the context of the view is the IAdding view, then self.context 
is not a content item, which makes for all kinds of self.context.context 
type lookups, messes with vocabulary factories, makes security tricky in 
some cases, and generally is confusing.

(If you *do* want this, then we should just use CMFAdding form 
Products.Five, by the way).

The add view should be registered for IContainerish, unless it's a type 
addable only in one particular type of container.

The add view needs to do some checking that adding is allowed, too; see 
the pasted file above.

 Or should all views have a default portal type that is used if we  
 access
 add views directly? In that case we would register the add view for  
 the
 container.

I think if you access @@add directly, you get an error. I can't see 
there being a use case for a default type.

 plone.dexterity[3] uses an @@add-dexterity-content traverser, but I
 don't think product names like dexterity or cmf should be visible in
 URLs. Those are implementation details that should be transparent  
 for users.
 
 I agree.

I agree with that sentiment, but it doesn't really matter, I don't 
think. Users never type add view URLs anyway, do they - they come from 
actions :)

My preference is actually @@add. However, that's very generic. Like I 
said, Dexterity needs its own version to have its own semantics, which 
means it needs its own name. I didn't want to do an @@add override or 
anything like that, since not all content is going to be Dexterity-managed.

So, in summary:

  +1 for http://site.com/folder/@@add/PortalType

  -1 for anything with .html

...and + is probably not going to work.

One last thing to note: You need to put the portal type in the URL, but 
portal types can have spaces and the like in the name. That's probably 
not a problem, but there may be a case for some kind of normalisation.

Cheers,
Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] CMFActionIcons vs. new-style actions

2008-09-14 Thread Martin Aspeli
Wichert Akkerman wrote:

 Easier customization - no need to let people touch the action itself?

You can change a property of an action easily enough with GS or in the 
ZMI. So, a separate registry is more isolated, but it's also harder to 
guess which portal_actionicons thing you need to add/modify to modify a 
particular action. Looking in two places doesn't necessarily make it easier.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] add view traversal

2008-09-14 Thread Martin Aspeli
Charlie Clark wrote:
 Am 14.09.2008 um 13:30 schrieb Martin Aspeli:
 
 Zope 3 does use IAdding for zope.app.form/zope.formlib based add  
 views;
 With z3c.form, IAdding support is optional, but the preference is to
 just use views like @@add-foo.html (note: I hate the .html convention;
 it is superfluous and looks weird, IMHO).
 
 
 I used to think this but then I thought about the possibility of any  
 non-Zope upstream handling such as caching which might be very  
 grateful for this kind of convention.

We don't have .html extensions on content items or views in Plone, and 
setting up Caching has never been a problem.

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] add view traversal

2008-09-14 Thread Martin Aspeli
Charlie Clark wrote:

 b) for URLs like http://www.example.org/guestbook/+/Message

 The '+' view already implements IPublishTraverse, so we can't change
 traversal using an adapter. The only solution I can see is to replace
 the '+' view by a customized version.


 c) for URLs like http://www.example.org/guestbook/add/Message

 If we use our own adding view, we can implement IPublishTraverse  
 inside
 the view or as adapter.
 
 I could live with either b) or c). I guess we need to weigh up the  
 desirability of being as close to Zope 3 style without unwanted side  
 effects. c) would to be the cleanest implementation. Would it be  
 possible to implement b) as a sort of alias for this if desired?

As I outlined in the other response:

  - Using '+' is not being close to Zope 3. In Five, we already have 
an IAdding view called +, which is close to Zope 3, but which has 
different semantics. It'd a great mistake, I think, to make something 
that *looked* like IAdding and wasn't. It'd also conflict with Plone, 
which *does* use IAdding in some cases, and I suspect other CMF users too.

 I guess the circle we're trying to square here would be what's the  
 best way to be able to add objects to a particular container. Our  
 particular experience has been to rely on the need to register views  
 for a particular container object but, of course, you still need type  
 information. As the type information (allowed content types for a  
 container object) is always required it probably makes sense to use  
 this rather than an implicit allowability through a registered view. I  
 think this means +1 for registering for the traverser.

Again at the risk of repeating myself, I don't think this really works. 
It's important that the context of the view is the container object and 
not another view (the traverser). Otherwise, we should go back to 
IAdding and use what's in Five already :)

 Absolutely. We've found the add forms to be extremely useful but the  
 dependence on knowing the name of the view is a pain even if you can  
 enforce a naming convention.

That's a bit like any view, though, surely? :)

Martin

-- 
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See https://bugs.launchpad.net/zope-cmf/ for bug reports and feature requests


Re: [Zope-CMF] [dev] more add menu changes

2008-08-07 Thread Martin Aspeli

Hi Yuppie,



yuppie-4 wrote:
 
 Hi!
 
 
 We now have to support two ways to add content:
 
 
 1.) oldstyle (no add view specified)
 
 
 The addable types are listed in folder_factories. After specifying type 
 and ID the object is added. constructContent redirects to the immediate 
 view.
 
 
 2.) newstyle (add view is specified)
 
 
 The addable types are listed as actions. These actions should show up in 
 a menu. The add action points to a type specific add form. After 
 completion of the form the object is added. The add form redirects to 
 the immediate view.
 
 Some parts are still missing:
 
 - add a traverser that allows to use pretty URLs and better portal type 
 handling for add views (not part of this proposal)
 
 - don't show newstyle types in folder_factories
 
 - show add actions in the CMFDefault skin
 
 
 Proposal 1: allowedContentTypes
 ---
 
 This PortalFolder method is used by folder_factories and by 
 folder_contents to decide if the 'New...' button is added. I propose to 
 add a new skip_add_views argument to allowedContentTypes. If true, 
 newstyle types are skipped.
 

Please let this default to False. I wonder if it's better to have a separate
method that does the skipping. allowedContentTypes may be used by other
things already. Plone uses it in a few places, for example. :)

I don't suppose there's a way to make all FTI's expose actions, and just
construct an appropriate fallback URL (e.g. createObject or whatever) if no
add view has been specified? That'd mean folder_factories could just loop
through the actions.



 Proposal 2: main_template
 -
 
 CMFDefault menus are implemented in main_template. I propose to add a 
 new section for 'folder/add' actions.
 
 
 If there are no objections I'll make these changes on trunk.
 

+0 - Plone would need this in its content menu implementation, but that's
custom anyway.

Martin
-- 
View this message in context: 
http://www.nabble.com/-dev--more-add-menu-changes-tp18867664p18873994.html
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] [dev] more add menu changes

2008-08-07 Thread Martin Aspeli

Hi Yuppie,


yuppie-4 wrote:
 
 I don't suppose there's a way to make all FTI's expose actions, and just
 construct an appropriate fallback URL (e.g. createObject or whatever) if
 no
 add view has been specified? That'd mean folder_factories could just loop
 through the actions.
 
 Not sure I understand what you propose. folder_factories is a form that 
 allows to specify type and ID. I don't think we should ask for the ID 
 *before* showing the add view. And if we have no add view, we need 
 folder_factories' ID input field.
 

Ah In Plone, folder_factories is a list of addable types. You click
Add next to each one and it's created with a temporary ID. Then you save
it, and it's renamed to a better ID, usually.



 But this might work: If we also implement the traverser, the traverser 
 could return a default add view that just asks for the ID. In that case 
 we could use actions for newstyle and oldstyle types.
 

That may be nice.



 That solution would change the add procedure for oldstyle types, but 
 maybe that's better than listing newstyle and oldstyle types in two 
 different places.
 

I think so. Why should the user have to know whether something is old or
new?

Martin
-- 
View this message in context: 
http://www.nabble.com/-dev--more-add-menu-changes-tp18867664p18875455.html
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] more add menu changes

2008-08-07 Thread Martin Aspeli

Charlie Clark wrote:

Am 07.08.2008 um 19:21 schrieb Martin Aspeli:

Ah In Plone, folder_factories is a list of addable types. You  
click
Add next to each one and it's created with a temporary ID. Then  
you save

it, and it's renamed to a better ID, usually.



Add forms are much nicer than that.


Of course. We just haven't had many of them until recently.

Objects are only created if the  
add form is correctly completed.


Yes, that's why they call them add forms 

I haven't looked at yuppie's latest  
implementation but the use of INameChooser for default id's is very  
usable - in many context management situations auto-generated id's are  
preferable although Plone's are a bit verbose.


No kidding. :)

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] type infos and 'add' actions - a proposal

2008-07-21 Thread Martin Aspeli

Hi Yuppie,

This is a proposal for implementing one part of what we discussed in 
this thread:

http://mail.zope.org/pipermail/zope-cmf/2008-July/027500.html

Using add views instead of folder_factories for creating content makes 
it necessary to provide some kind of menu items for them. In CMF menu 
items are usually represented by 'actions'.



Type infos already define most data required for actions:

- 'id': can be reused

- 'title': can be reused; if we want action titles like 'Add File ...' 
instead of 'File' we can change that in the template


- 'description': has already the same purpose as in actions

- 'icon': 'content_icon' is a path relative to the site root, but we can 
use the same icon and compute the required absolute path


- 'available': can be computed using allowType of the container

- 'allowed': can be computed using isConstructionAllowed

Missing are these properties:

- 'category': can be hardcoded, e.g. as 'folder/add'

- 'url': requires a new type info property, I propose to use 'url_expr' 
to keep it in sync with normal Action objects


I wonder whether addview_url or something similar would be more 
appropriate, since the url of a type is somewhat ambiguous.



- 'visible': can be hardcoded as True


So instead of adding separate 'add' actions we can extend the type info 
classes, making them implement IAction as well.


How about making them adaptable to IAction instead of directly 
implementing it? That sounds cleaner than trying to bend some of the old 
properties.


listActions of the types tool would include type infos if they provide 
IAction *and* have an url specified.


Apart from the two comments above, a great +1. :)

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-16 Thread Martin Aspeli
yuppie [EMAIL PROTECTED] writes:
 
  class MyAddForm(CMFBaseAddForm):
  fields = form.Fields(IMyType)
  portal_type = 'My type'
 
 Here you are mixing up content type with portal type. We can't hardcode 
 the portal type if we want to use the add form for renamed/derived 
 portal types as well.

Right, sorry. We probably don't need this at all, actually, if the
traverser sets it along with the factory name.

   - The base form knows to look at self.factory_name to look up the 
  factory when it does the create() call.
 
 create() needs to know the portal type, not just the factory name.

Okay, sure, but that's known at this stage too if the traverser saves it.

 Above you wanted to use self.factory_name inside the form, now you set 
 addview.portal_type.

 We definitely have to pass the portal type to the view. If we have to 
 look up the factory name in publishTraverse, we might want to pass it to 
 the view as well.

Right.

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-16 Thread Martin Aspeli
Robert Niederreiter [EMAIL PROTECTED] writes:

 +/-
 i would provide a default add form anyway. consider how archetypes
 works.

Not necessarily an example to follow, though, is it. :)

 you never write an addform (especially because there are
 none :)). for most of the usecases default sequencial add forms fit
 quite fine. so for most usecases even the registration for the add form
 is lost code lines.

I'm not so sure about that, because ...
 
 to provide this, the CMFBaseAddForm simply has to provide one more
 property.
 
 class CMFBaseAddForm(BrowserView):
 
 @property
 def fields(self):
 portal_types = getToolByName(self.context, 'portal_types')
 fti = getattr(portal_types, self.portal_type)
 return form.Fields(fti.schema)


Here you assumption is that that schema is saved on and returnable from the FTI.
This is a pretty fundamental change to the way CMF and CMF types work. First of
all, it requires that the FTI can know the schema, which will probably mean
storing the dotted name of the schema somewhere or inferring it from something
else (a class, or the factory - the IFactory interface actually has some support
for this).

Now, I'm not actually against this. Dexterity works in this very manner (it has
a lookup_schema() method that works a bit like the schema property above, and
can source the schema from a number of different places including TTW-only
configuration, a filesystem file or a real filesystem interface via a dotted
name). If some of that could be pushed down to CMF, then of course that'd be
great - less code to be kept in Dexterity. But I'm not sure CMF wants to swallow
that much of an architectural change at this stage.

Also note that defaulting to form.Fields(fti.schema) is probably not enough.
Many forms, at least, will require custom widgets, and settings like groups and
so on. Dexterity has a way for the schema interface to give hints for how it
will be rendered (using tagged values) and a (fairly hairy) algorithm for
including them, but I won't actually recommend that pattern for general purpose
filesystem code (it's necessary for the case where you have pluggable UI that
source schema fields from multiple sources - again something that's probably not
in scope for base CMF).

If we want to be true to the tradition of Zope 3 and its simplified content
types metaphor, then  I think we should assume that a type consists of:

 - a class
 - a schema interface
 - an add form/view
 - an edit form/view

plus the FTI to install it into the CMF site. I wouldn't try to be too clever
and generalise away any of these.

Martin



___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-16 Thread Martin Aspeli

 it's not that big architectual change. everything else discussed is
 possible anyway. i would rather call it a feature than a design change
 (since the change happens anyway).

I think it's a fairly big shift to assume that the FTI has knowledge of the
schema of the type. It's not necessarily a *bad* idea (at least I don't think
so, since this is basically how Dexterity works :-), but right now, FTI doesn't
have any notion of a schema. With this change, you're effectively dictating (or
strongly suggesting) that all CMF types have a schema and that this is the
basis for forms, and suggesting that forms aren't registered as independent
views but rather inferred from this schema.

 we discuss the generic adding approach, we further discuss what has to
 be considered to be generic.

I'm just not sure that generic is so good. If it's easy to make add- and edit-
views (probably with convenience classes for CMFish container adding behavior)
and obvious how to register them, then do you need more framework? At least not
in CMFCore.

Better to leave that up to higher level frameworks to implement this type of
generality.

 2 more properties on the fti (addforminterface, schemainterface), both
 are optional, but provide then the discussed and requested flexibility
 for different type implementations.

Optional properties still need to be maintained and may still create confusion
or conflicting assumptions. Here, we've invented two new concepts (the type has
a schema, the type has an interface that describes the add form). It may be that
more advanced frameworks need something a bit different, and so they'll have to
either overload or ignore those properties.

 if we do not consider this questions at this state, again the result
 will be stupid and ugly subclassing and incompatibility and bad readable
 code and overrides.zcml (which is one thing i really hate!).

I don't know if that's true. Trying to solve all problems at the most basic
level is probably not a good idea. Giving the right hooks probably is.

I think if we make the addview name used for the rendering of menus a TALES
expression, then the traverser thing becomes a CMFDefault implementation detail
(not even CMFCore).

Dexterity has its own FTI type. It will always need that, no matter how many
hooks you have here. I have no problem with that, actually - GenericSetup makes
it easy. Dexterity does not need any overrides.zcml either. ;-)

 right, therefor you always have the possibility to write your own form
 implementation.

I think it's a mark of bad framework design if that possibility really means
throwing away most of the conventions and standard support and building up
something else starting from a very low level. In that case, the framework's
tried to too much application-level work that ends up being useless to the
actual applications (like Plone), who then have to invent their own parallel
framework to support their own slightly divergent use cases.

 i simply wonder why people should write code for default behaviour when
 there can be a default implementation.

I don't think it's a safe assumption that *at the CMFCore level* we'll have a
sensible default. It's a pretty big assumption that it's sensible for most
applications to have a linear form that uses formlib's default widgets with no
custom setup code for most types.

 i only want to point here to the plone portlets engine. why is it
 necessary to provide 4 (!) classes, a template and a zcml configuration
 for 1 portlet? thats imo too much, especially because people are
 familiar with and love the 'write-less-do-more' mentality, and adherence
 to a tradition is not automatically more productive or easier to
 understand.

I can tell you why it's necessary in another thread. It's irrelevant here (and
on this list).

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-16 Thread Martin Aspeli
Wichert Akkerman [EMAIL PROTECTED] writes:

 Possibly related: I have often had a desire to be able to annotate or
 extend the FTI. In Plone (and to a lesser degree CMF) we have lots of
 settings that change a portal type's behaviour that are stored in
 various places: versioning settings, markup configuration, workflow
 chains, etc.

I agree that this is important. The FTI is a natural place to store persistent
information about a type, and this pattern is possibly a bit under-appreciated
as we try to use individual local components for type-specific stuff.

Dexterity subclasses the standard FTI to add a few more properties, which is
nice because you get some TTW configurability for free. Using different FTI
types is relatively non-problematic when we use GS for installation.

I think this is slightly off-topic in this thread, though. :)

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-16 Thread Martin Aspeli
Daniel Nouri [EMAIL PROTECTED] writes:

 
 Robert Niederreiter writes:
 
  Am Mittwoch, den 16.07.2008, 16:24 +0200 schrieb Daniel Nouri:
  Where would we need overrides.zcml?
 
  in the case where ICMFAddForm is no longer my interface to look up. then
  i have to overwrite the traverser.
 
 Why would ICMFAddForm no longer be the interface to look up?  It's the
 the only type of add form that promises to do something meaningful with
 the 'portal_type' attribute that's set on it in the traverser.

And even if it weren't - we shouldn't hardcode the traversal adapter. We should
make this a convenient implementation option. The actual URL of the add view
should configurable via a TALES expression, which means that it can be written
without the @@add bit.

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-15 Thread Martin Aspeli

Hi Robert,


imo its a bad idea to depend on static zcml configuration for factory
types. martin did a nice approach in his portlets engine with a name
traverser when calling a generic adding view. 
I'm not quite sure I follow here. The portlets machinery just looks up 
the add view in a utility that stores its name, and then invokes it. 
There's a custom analog to IAdding called +portlet to keep the 
namespace separate.


you post i.e. /++contextportlets++plone.rightcolumn/+/portlets.Login as
action for adding a portlet and let your ITraversable implementations
perform what to do in plone.app.portlets.browser.traversal.py.

thats imo a nice approach


Ah, I get you. Actually, the ++contextportlets++plone.rightcolumn bit is 
a namespace traversal adapter that addresses a particular portlet 
manager (which is basically an ordered container); + is an IAdding view 
(actually, an IPortletAdding view) registered for the portlet manager 
container. portlets.Login is the name of the add view for a particular 
portlet.


So, this approach is identical to (and borrowed from) the old Zope 
3/ZMI approach that you have an add view that is a statically registered 
view for IAdding. The adding view is *not* generic. Each portlet 
registers its own add view. We have a formlib-based base class though.


Now, I think this is fine for portlets, since it's relatively easy to 
register this add view (there's a single ZCML directive to register all 
portlet-related information), and portlets are not like portal types 
(there's no persistent FTI that can be cloned).



i took this idea and the
adding mechanism of devilstick works this way as well and depends on the
fti too. so a call of foo/add/portal_type returns an add view for
requested type.

How's that different to foo/+/factory-name ?


not that much. i only wanted to say that there might be no need to
register a seperate addview/form for every portal type. having the type
name it should be possible to get the schema interface of the requested
type, so it's possible to provide a generic addview/form.


Right. That's probably a reasonable default (and is, in effect, what 
Dexterity does as well, although it registers add views as local adapter 
factories that know their portal_type).



this interface lookup, and addview/form instanciation might be done then
in a traverser, that's the most 'zopeish' solution imo.


This is quite an interesting approach, actually. After traversal, what 
is self.context in the add form? Is it the form, or the 'addview' 
traverser thing?


Having the add view be a view for a view (i.e. the context of the real 
add view is not a content object) is sometimes quite painful.


until someone got the clue :). yes you're right here, constructs like
``aq_inner(self.context.context)`` and similar simply look ugly. but on
the other hand, if you kick this construct, you have to provide another
mechanism which is responsible to finally add what has to be added. if
this is more elegant then...?


The final 'add' operation can be done by a base class for the view. 
That's how Yuppie's formlib thing works, and how z3c.form prefers to work.


self.context.context can be majorly painful, though. For example, look 
at 
http://dev.plone.org/plone/browser/plone.app.vocabularies/trunk/plone/app/vocabularies/workflow.py.


Here, we need to acquire something, but since the context may be the 
IAdding view, we have to do this everywhere:


 context = getattr(context, 'context', context)

Yuck!

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-15 Thread Martin Aspeli

yuppie wrote:

Robert Niederreiter wrote:
Your proposal has some advantages. On the other hand this requires to 
create CMF specific code and patterns in a place where a more generic 
solution also works.

it does not if you call a formfactory inside the traverser, so it's
hoohable for CMF, Plone or whatever even with different formlib
implementations.

like:

formfactory = getAdapter(context,
 IFormFactory,
 name='factoryNameFromFti')
return factory()

which handles all the magic in there. just a thought.


Writing generic code is just the first step. Pushing this down the stack 
and making it the default pattern for Zope is much harder.


We may not have to, though... In Zope 3, there either:

 - is no pattern, everyone does it their own way; or
 - everyone uses IAdding views; and/or
 - everyone uses Zope 3 browser menus via ZCML

This would all be feasible for CMF except that we want to support a 
single content type instantiated as multiple (persistent) portal types, 
all of which are likely to (but may not) share a single view.


I'm still on the fence as to whether I like Robert's proposal. However, 
if we let 'addview' be a TALES property, then I think with his proposal 
it'd look like:


 string:${folder/absolute_url}/@@add/mytype

This would basically allow a default add view to be written that could 
work on all types (provided there was a way to look up the schema of 
that type, which there may not be in plain CMF). The view @@add would be 
a view providing IPublishTraverse. It'd have:


 def publicTraverse(self, request, name):
 portal_type = name
 return GenericAddView(self.context, request, portal_type)

GenericAddView could then be a form that took portal_type as a parameter 
and rendered an add form that knew how to configure and add this type.


This would of course just be one option - if I had a more conventional 
custom add form, I could do:


 string:${folder/absolute_url}/@@my-add-view

or whatever.

Note that we're now getting into the territory that plone.dexterity 
(which, by the way, aims to work with plain CMF as well) covers. It has 
a way for the FTI to broadcast its schema (and that schema can come from 
a number of places, including a filesystem interface, an XML file or 
some TTW configuration). It then has generic add- and edit- forms that 
look up this schema and render the relevant forms.


If we envisage that every plain type in CMF will have a custom add 
view registered as a regular view with a unique class (probably a good 
thing), then I think the @@add/portal_type pattern is overkill. It's 
easier just to let the FTI represent the URL to the view, and for the 
menu code that lets the user pick something to add, to loop over the 
FTIs of addable types and render each link in turn.


Martin


--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-15 Thread Martin Aspeli

Daniel Nouri wrote:

Daniel Nouri writes:


Robert Niederreiter writes:



yuppie writes:


I like pretty URLs, and 'foo/+/MyPortalType' looks much prettier than 
the URLs needed with my approach:


   foo/AddViewName?form.portal_type=MyPortalType

Your proposal has some advantages. On the other hand this requires to 
create CMF specific code and patterns in a place where a more generic 
solution also works.

it does not if you call a formfactory inside the traverser, so it's
hoohable for CMF, Plone or whatever even with different formlib
implementations.

like:

formfactory = getAdapter(context,
 IFormFactory,
 name='factoryNameFromFti')
return factory()

which handles all the magic in there. just a thought.

If I understand this correctly, it should be more like:

  formfactory = getMultiAdapter((context, request),
IAddForm,
name='factoryNameFromFti')


My suggestion is rubbish.  First, it should be 'form', not
'formfactory'.  Then, I realize it's not the same pattern since your
factory is supposed to do some work before it passes on control (I
believe?) whereas mine is the add form class itself.

Both patterns require the same amount of registrations.  As many for
IFormFactory as for IAddForm.  What's worse is that the implementations
will have a hard time to work reusably without the portal type name,
which they're registered with.

What about the traverser does this:

try:
view = getMultiAdapter((context, request),
   IAddForm, name=factory_name)
except ComponentLookupError, e:
view = getMultiAdapter((context, request), IAddForm)

view.factory_name = factory_name
return view()

In this case, the adapter/form would actually have a chance to work for
more than one portal type.

How does this sound?


It still feels a bit fishy to me.

I don't really see why you need a traverser *unless* you're trying to 
have a single add form implementation that covers multiple types. You 
may of course have that, and maybe it's helpful to let people write 
that, but I think most people would prefer to write plain add views 
that use the standard z3c.form patterns.


For something like Dexterity, where we explicitly want to support 
generic content with a schema that varies according to runtime 
configuration, this is more of an issue. But even there, the intention 
is that whilst the framework has a few hooks like this so that it works 
with content that's more malleable, it doesn't force you to use 
unconventional patterns if you do something yourself on the filesystem.


In the case above, you end up having to register your form as a 
particular adapter rather than a browser view. That's fairly unnatural, 
and also doesn't necessarily deal with things like security settings. It 
makes the add view quite different to write than the edit view, too.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-15 Thread Martin Aspeli

Charlie Clark wrote:

Am 14.07.2008 um 12:37 schrieb yuppie:

Add links are just special 'actions', they should be integrated with  
CMF's action machinery. Based on the information in the type infos  
we should be able to create normal IActionInfo objects. (IActionInfo  
defines the non-persistent wrapper around actions, today we would  
use adapters to implement this.)


If we don't want to use a convention, we need a new property. And if  
we want to be flexible enough to add the portal type name to the  
query, a TALES expression for the URL wouldn't be overkill.



Works for me - would this be something like the initial view for  
types?


Actually, that's interesting... what purpose does 'initial view' serve 
in a world with add forms?


Should we re-purpose this slightly to make it provide the add form view URL?

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-14 Thread Martin Aspeli

Hi Yuppie,



I doubt constraints based on __setitem__ and __parent__ work in Zope 2.
Well, they do in the sense that if you have them and we have this code, 
we'll get an exception. They don't work generally, tough, so this may be 
YAGNI. It was copied from Five's Adding implementation, so I figured it 
should be kept if someone's relying on it.


That's quite hypothetical. If someone figures out how to use this for 
stuff like the allowType check, it's useful. If not, it is YAGNI.


In case of doubt, I prefer to remove code like that and to wait until 
someone complains.


I have no problem with doing that.


content.id = name
container._setObject(name, content)
content = container._getOb(name)
if fti is not None:
fti._finishConstruction(content)

CMF trunk uses events instead of _finishConstruction.
Ah, nice. Do you think it'd be feasible to backport this, i.e. copy the 
event handler somewhere in Plone so long as Plone's still using an older 
version of CMF? Or does the new event handler rely on other changes to 
CMF as well?


The changes in handleContentishEvent are simple. The tricky part is to 
make sure notifyWorkflowCreated and indexObject aren't called twice if 
the types tool is used for creating content.


How did you?

BTW: plone.z3cform's AddForm doesn't include a create method, so I can't 
see your complete create-and-add procedure.


The idea is that the concrete add view implements this method. I'm not 
sure it's desirable to completely generalise this, but maybe a default 
implementation would be useful.


You might want to compare 
your code with the ContentAddFormBase of CMFDefault trunk:

http://svn.zope.org/Products.CMFDefault/trunk/Products/CMFDefault/formlib/form.py?rev=86225view=auto


Will do!


We could make this overrideable as well, with another FTI property.
I guess I'd rather have a flexible explicit URL than an implicit URL 
ruled by convention.
Agree. So does this mean we want a separate property for the add view 
name? Should it be a simple string or a TALES thing?


Add links are just special 'actions', they should be integrated with 
CMF's action machinery. Based on the information in the type infos we 
should be able to create normal IActionInfo objects. (IActionInfo 
defines the non-persistent wrapper around actions, today we would use 
adapters to implement this.)


If we don't want to use a convention, we need a new property. And if we 
want to be flexible enough to add the portal type name to the query, a 
TALES expression for the URL wouldn't be overkill.


So, a single new property that contains TALES? Called 'addview'?

I can get with that. ;-)

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-14 Thread Martin Aspeli

Hi Robert,



maybe it's a little late to join this discussion. i read the thread and
want to point some of my thoughts here.

imo its a bad idea to depend on static zcml configuration for factory
types. martin did a nice approach in his portlets engine with a name
traverser when calling a generic adding view. 


I'm not quite sure I follow here. The portlets machinery just looks up 
the add view in a utility that stores its name, and then invokes it. 
There's a custom analog to IAdding called +portlet to keep the 
namespace separate.



i took this idea and the
adding mechanism of devilstick works this way as well and depends on the
fti too. so a call of foo/add/portal_type returns an add view for
requested type.


How's that different to foo/+/factory-name ?


doing it this way would even work if someone renames a
portal_type for some reason without the needs to modify or overwrite any
existing zcml, because the traverser simply tries to read the fti of
``portal_type``.


Mmm right. Local components work here too, of course.


to make custom add views available there could be a new attribute in the
fti which contains the name of a custom add view to look up. the
traverser could then first lookup if a custom add view was set (this has
to be configured static with zcml anyway) and looks it up by its name or
returns the default add view. as an alternative this could also be done
by aliases.


I'm not sure you need the traverser, though, if you have a standard way 
to generate the list of URLs for the add view, but maybe I'm missing 
something?



im not sure if it is desirable to alter the IAdding mechanism with
something like a simple view. at least i see no reason for implementing
'yet another adding mechanism'.


Having the add view be a view for a view (i.e. the context of the real 
add view is not a content object) is sometimes quite painful.



in the end a quick question. isn't the portal_factory itself obsolete if
a clean adding mechanism is working then and the only thing to maintain
further the fti stuff?


Plone's portal_factory has nothing to do with this, but yes, we want to 
rip the damned thing out.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-13 Thread Martin Aspeli

Hi Yuppie,


Martin Aspeli wrote:
I see that Yuppie has been experimenting with add forms. From what I can 
tell, he's using a custom formlib base class and registering views as 
e.g. addFile.html. It also look as if he's registering that view as an 
action in portal_actions, in the 'folder' category.


That's correct. But I have to mention that not all parts of these 
changes have reached the same stage of maturation. Using 'folder' 
category Actions is a temporary hack to generate menu items for the new 
add forms. I'm glad you want to help to find a better solution.


Ah, good.

Plone currently supports add forms for the IAdding (+) view in a 
somewhat ugly way (it looks to see if there's a view for IAdding with 
the same name as the 'factory' set in the FTI of an addable type, and if 
so, provides a link to it). IAdding can be a bit painful, so we're 
interested in supporting an approach based on simple views.


Good.

It's also worth noting that z3c.form (via plone.z3cform, which should be 
plain CMF compatible, though you may want a different default template) 
has support for such views in quite a generic way. The CMF version of 
that looks like this:


http://dev.plone.org/plone/browser/plone.z3cform/trunk/plone/z3cform/add.py

z3c.form is generally nicer to work with than formlib.


Maybe we should discuss this in a different thread. Here a short reply: 
My code for the AddForm would look quite different, especially for CMF 
trunk, 


I'm curious how it would look different. Now is the time to get the 
correct base class behavior in plone.z3cform, before we release a new 
version of it.


but in general that's the way to go. Since z3c.form became the 
standard in the Zope 3 world I'd like to see Zope 2 and CMF moving in 
the same direction. Unfortunately using plone.z3cform is no option for 
CMF because it has a different license and repository. *If* Plone wants 
to donate that code to the Zope Foundation or someone writes something 
similar (maybe five.z3cform), I'd be happy to help with CMF integration.


Bah, I hate these discussions. I'm sure Daniel Nouri would be happy to 
relicense. Re-invention for the sake of a license is just too dumb.


I'd prefer to keep the name to avoid breaking existing packages, though.

Another option is to factor out a few things to a five.z3cform and have 
plone.z3cform import from it as appropriate.


In any case, I'd like to know why you went down the portal_actions route 
for rendering the add links. I'm not quite sure I like the idea of 
having this be persistent configuration, separate to the FTI, as the two 
would need to be kept in sync, and in sync with the view name registered 
in ZCML.


CMF makes a distinction between portal types and content types. Portal 
types are persistent wrappers around the non-persistent content types. 
You can define many different portal types based on one content type.


Right.

In CMF you add *portal type* instances, so the 'add' links should be 
persistent as well. The non-persistent add form has to take the portal 
type name as argument to create the correct portal type.


I'm not sure what the right solution is, but I guess extending the type 
info classes will be the best approach.


Also, why not try to use the Zope 3 menu concept? There's even a special 
add menu directive.


Moving away from persistent actions is not on my todo list. And as I 
tried to explain above, the current portal type concept depends on 
persistent actions.


Right, I see that. But having things in two places is obviously not very 
desirable either.


I'd quite like to find a good approach here that can be used by both 
Plone and plain CMF, if possible.


I hope you find one ;)


How about we use a naming convention that's linked to the factory that's 
persisted in the FTI, i.e. we look for a view called 
add-factory_name and link to that if it's available.


The idea is that the factory name is unique and specific to the content 
type. Different portal types that use the same factory would almost by 
necessity have the same add view.


We could make this overrideable as well, with another FTI property.

The assumption here is that the add menu is rendered with some custom 
code, i.e. it doesn't use the actions machinery or the Zope 3 browser 
menu concept.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-13 Thread Martin Aspeli

Charlie Clark wrote:

This is probably necessary anyway. I'm not sure whether it's right to  
try and go straight to z3c.form. My understanding is that there isn't  
a great deal of difference between the two libraries so hopefully an  
implementation could live with both. I don't think that everyone has  
moved onto z3c.form - certainly that wasn't my impression at  
Europython. It would be nice to have a formlib based CMF 2.2 and I  
think I now understand most of this well enough to contribut. We could  
possibly  onto z3c.form in 2.3 which might have replaced zope.formlib  
in Zope by then.


I doubt that formlib will be replaced by z3c.form. Rather, it just seems 
that everyone prefers to work with the latter and so the former is 
becoming less relevant.


They are definitely different, and don't share any code as far as I 
know, but if you know one, moving to the other is pretty trivial. 
z3c.form also has good (if a bit too abundant) documentation.


Thus, if CMF hasn't yet picked a form library in a release, then you 
could try to learn from Plone's mistakes and not jump on a sinking ship. :)


How about we use a naming convention that's linked to the factory  
that's persisted in the FTI, i.e. we look for a view called add- 
factory_name and link to that if it's available.


You might as well stick with actions if you're going to do that. I've  
been experimenting with the following


portal_type = self.request.form.get('portal_type')
at = getToolByName(self.context, 'portal_actions')
actions = at.listFilteredActionsFor(self.context)
addable = actions.get('add', [])
for a in addable:
 if a['id'] == portal_type:
	return request.response(%s/%s (%self.context.absolute_url(),  
a['url']))


It's workable but so easy to break as it relies on add actions  
having the same name as the portal_type. It makes much more sense to  
me to have this on the type info: if I ask the type tool for the  
factory, surely I can also ask it for the view?


You mean we have an action on the FTI object with category 'add' and 
name == FTI name/portal_type? That still means having to get that link 
right, though (a typo in the FTI name or a rename of the FTI makes it 
break), and I question whether you ever need all the other info that 
actions provide. We already have ways to control add permissions and 
other filters for what's addable where.


Martin


--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-13 Thread Martin Aspeli

Hi Tres,


Putting the policy in the typeinfo objects seems like a much saner place
to keep this stuff than embedding it in a component registry.


+1, at least if we're talking about persistent configuration (which I 
guess we are).


Do you have a preference for what shape this should take?

 - A simple property 'addview' that gives a view name?

 - A simple property 'addview' that gives a view name in a TALES 
expression?


 - Something using FTI actions?

 - Something else?

Also, why not try to use the Zope 3 menu concept? There's even a special 
add menu directive.


The Z3 menu stuff seems to me bound up with the needs of the
never-gonna-use-it Z3MI:  it is overcomplicated for little purpose, and
puts too much policy into emergent behavior (ordering of component
lookups, for instance).


Plone uses it to make the content menu (the green bar in the 
editable border) somewhat pluggable and customiseable-by-context. In 
hindsight, we could probably just as easily have invented our own 
interfaces and used that instead of the ones in zope.app.publisher, 
though I don't think they've done too much harm either.


The ordering thing is irritating though.

For add menus, however, there *may* be a purpose to using it since Zope 
3 has a specific ZCML directive to declare your add action. At least 
we should consider it.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Add forms and menus

2008-07-13 Thread Martin Aspeli

Hi Yuppie,


Ok. I added some comments to the 'add' method of plone.z3cform:


Thanks for that!


def add(self, object):

container = aq_inner(self.context)

content = object

name = self.contentName

chooser = INameChooser(container)

# Ensure that construction is allowed

portal_types = getToolByName(container, 'portal_types')
fti = portal_types.getTypeInfo(content)

if fti is not None:
# Check add permission
if not fti.isConstructionAllowed(container):
raise Unauthorized(uYou are not allowed to create a %d here % 
fti.getId())


Inside an add form this should always be true. If it isn't true, we'll 
get an error anyway. So this check is redundant and can be removed.


Cool.


# Check allowable content types
if  getattr(aq_base(container), 'allowedContentTypes', None) is not 
None and \
not fti.getId() in container.allowedContentTypes():
raise Unauthorized(uYou are not allowed to create a %d here % 
fti.getId())


allowedContentTypes is quite expensive. I use this code instead:

   #check container constraints
   container_ti = portal_types.getTypeInfo(container)
   portal_type = content.getPortalTypeName()
   if container_ti is not None and \
   not container_ti.allowType(portal_type):
   raise ValueError('Disallowed subobject type: %s' % portal_type)


Nice!


# check preconditions
checkObject(container, name, content)


I doubt constraints based on __setitem__ and __parent__ work in Zope 2.


Well, they do in the sense that if you have them and we have this code, 
we'll get an exception. They don't work generally, tough, so this may be 
YAGNI. It was copied from Five's Adding implementation, so I figured it 
should be kept if someone's relying on it.



if IContainerNamesContainer.providedBy(container):
# The container picks it's own names.
# We need to ask it to pick one.
name = chooser.chooseName(self.contentName or '', content)
else:
request = self.request
name = request.get('add_input_name', name)

if name is None:
name = chooser.chooseName(self.contentName or '', content)
elif name == '':
name = chooser.chooseName('', content)
else:
# Invoke the name chooser even when we have a
# name. It'll do useful things with it like converting
# the incoming unicode to an ASCII string.
name = chooser.chooseName(name, container)

if not name:

raise ValueError(Cannot add content: name chooser did not provide a 
name)


All that name handling is copied from an old version of Five's 
BasicAdding, which in turn is copied from old Zope 3 code. I think we 
should use our own code here to make sure we understand the code and it 
reflects our policy.


Yeah, that code's pretty nuts and doesn't make a lot of sense. I tried 
to refactor it when I copied it over, actually, and then found that I 
didn't really understand it so I left it alone.


Creating the content I set a provisional id. In the 'add' method I just 
use this line:


   name = chooser.chooseName(content.getId(), content)


+1


content.id = name
container._setObject(name, content)
content = container._getOb(name)

if fti is not None:

fti._finishConstruction(content)


CMF trunk uses events instead of _finishConstruction.


Ah, nice. Do you think it'd be feasible to backport this, i.e. copy the 
event handler somewhere in Plone so long as Plone's still using an older 
version of CMF? Or does the new event handler rely on other changes to 
CMF as well?


Another option is to factor out a few things to a five.z3cform and have 
plone.z3cform import from it as appropriate.


+1

plone.z3cform seems to contain Plone specific stuff. Factoring out the 
generic stuff to a five.z3cform package sounds good to me.


I'm CC'ing Daniel Nouri if he has an opinion. I think it should be 
unproblematic to test this stuff out in plone.z3cform and then have it 
depend on a new five.z3cform and just do convenience imports where required.



But I don't know if everybody agrees that CMF 2.2 should depend on z3c.form.


CMFCore shouldn't need to. CMFDefault may want to though.

How about we use a naming convention that's linked to the factory that's 
persisted in the FTI, i.e. we look for a view called 
add-factory_name and link to that if it's available.


The idea is that the factory name is unique and specific to the content 
type.


I sometimes use different factories for one content type, but a 1:1 
relationship doesn't seem to be necessary for your proposal.


Different portal types that use the same factory would almost by 
necessity have the same add view.


This is the 

[Zope-CMF] Re: Add forms and menus

2008-07-13 Thread Martin Aspeli

Charlie Clark wrote:

Am 13.07.2008 um 20:21 schrieb Martin Aspeli:

I doubt that formlib will be replaced by z3c.form. Rather, it just  
seems that everyone prefers to work with the latter and so the  
former is becoming less relevant.


I wonder who everyone is? When I asked Maartijn Faassen as  
Europython he didn't seem to be in a hurry to migrate Grok to using  
z3c.form and his work on Formulator was possibly the start of a Zope  
forms library of which formlib and z3c.form are the nth and n+1th  
generations.


Well, let me put it another way then: A lot of people have expressed 
dissatisfaction with formlib and seem to like z3c.form better.


They are definitely different, and don't share any code as far as I  
know, but if you know one, moving to the other is pretty trivial.  
z3c.form also has good (if a bit too abundant) documentation.


I've only briefly looked at z3c.form but it seems to make abundant  
reference to how zope.formlib works.


Right. z3c.form is an attempt to rectify some of the mistakes from 
zope.formlib and build something better.


Thus, if CMF hasn't yet picked a form library in a release, then you  
could try to learn from Plone's mistakes and not jump on a sinking  
ship. :)


We're already using zope.formlib in the experimental browser views  
edit forms. The reference to a sinking ship is totally off-target. My  
own view is that sometimes it is better to wait for version 2 of a  
product or library to be released before adoption. Surely Plone has  
suffered from adopting some stuff too early?


*shrug*

Do what you please. I'm not particularly wedded to one or the other. But 
having used both, I'm pretty sure that z3c.form is a better library. In 
many ways, z3c.form *is* version 2 of formlib.


Yes, which is why I don't favour this approach: it can work but is  
likely to cause problems.


I don't have an approach, I'm trying to find one that works. I'm not 
sure what problems you're referring to, though.


What we all want is to be able to get the add view for a particular  
portal_type but we can't do this through QueryMultiAdapter because the  
view has to be registered on a container.'


Mmmm... I'm not sure I follow here. The issue is how to render the 
correct link to the add view for each addable type. You loop through the 
addable types and then render a list of links. If by queryMultiAdapter 
you mean the browser view lookup, then that's something the publisher 
does when someone clicks the link, not something we'd do to find out 
what those links are.


Actions are unsuitable but  
provided Yuppie with a bootstrap to test the whole procedure and  
highlight the deficiencies.


Obviously.

I'm afraid I don't understand the  
internals too well but isn't something like cmf:registerAddView ...  
or what we're after until the Zope 3 world comes up with the right  
way to do this?


Zope 3 has a way, it's called browser:addMenuItem / (or something like 
that). However, Tres and Yuppie have pointed out reasons why doing this 
with global component registrations is not ideal.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Why do we need types.xml and workflows.xml?

2008-06-29 Thread Martin Aspeli

yuppie wrote:

Hi!


Martin Aspeli wrote:
The GS handlers for portal_types and portal_workflow both require a 
single file - types.xml and workflows.xml - that declares the objects, 
and a directory full of files - types/*.xml and workflows/*.xml - to 
initialise them.


However, in both cases, there is enough information in the per-item 
files (id, meta_type) to make the types.xml and workflows.xml redundant. 


Some tools are ordered containers, the types tool might become ordered 
as well. GS always specifies the order of sub-objects in the container's 
file.


To what end?

It's not ordered now, and I can't see a good reason to make it ordered.

Right now we have a relatively easy rule: Adding, moving or removing 
sub-objects modifies the container, so these changes *always* have to be 
specified explicitly in the container's file.


'id' and 'meta_type' in the per-item files are not really used. Would it 
be an improvement to remove that redundant information from the per-item 
files?


A marginal one (no repetition), but this is still really cumbersome. I 
have to tell people to remember to add two files, and to match up three 
things (line in the types.xml, filename in types/*.xml, and line in 
types/*.xml file itself) just to install something.


FWIW, collective.wtf, which provides an alternate syntax for workflow 
installation, doesn't require a workflows.xml.



Worse, it's easy to forget, and no warning that there are orphan files.


Adding a warning might be an other solution.


That sounds like attacking the symptom rather than the problem, though.

I'm pretty sure it's an easy fix to make types.xml and workflows.xml 
optional (or even deprecated, though of course workflows.xml also has 
bind information that should remain there).


All the information required for adding, moving or removing sub-objects 
is currently stored in the container's file. Additional code and 
complexity is necessary to extract that information from per-item files.


True, but not very much. See 
http://dev.plone.org/collective/browser/collective.wtf/trunk/collective/wtf/exportimport.py#L128 
for an example.


In general, repetition like this is counter-productive. I've had to 
explain this to three people new to Plone recently, and it feels like 
I'm making excuses rather than a strong case.


We could add 10 lines of code and save 100 people from making common 
mistakes that cause problems of the type why doesn't my workflow show 
up? with no errors or warning messages.


I would probably not deprecate the existing two-file pattern though, 
just make it optional.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Why do we need types.xml and workflows.xml?

2008-06-29 Thread Martin Aspeli

yuppie wrote:

Hi!


Martin Aspeli wrote:

yuppie wrote:

Martin Aspeli wrote:
The GS handlers for portal_types and portal_workflow both require a 
single file - types.xml and workflows.xml - that declares the 
objects, and a directory full of files - types/*.xml and 
workflows/*.xml - to initialise them.


However, in both cases, there is enough information in the per-item 
files (id, meta_type) to make the types.xml and workflows.xml redundant. 
Some tools are ordered containers, the types tool might become ordered 
as well. GS always specifies the order of sub-objects in the 
container's file.

To what end?

It's not ordered now, and I can't see a good reason to make it ordered.


It would be useful to specify the order in 'add' menus by ordering the 
type infos.


Possibly, although that gets a bit tricky (or rather, counter-intuitive) 
since many types in portal_types may not be addable in many contexts. 
For types that filter content types, we can use the order in the 
allowable_content_types property. For types that don't filter, it'd make 
more sense to set a default order among globally addable types 
explicitly via a separate property/tab on portal_types.


I'm pretty sure it's an easy fix to make types.xml and workflows.xml 
optional (or even deprecated, though of course workflows.xml also has 
bind information that should remain there).
All the information required for adding, moving or removing 
sub-objects is currently stored in the container's file. Additional 
code and complexity is necessary to extract that information from 
per-item files.
True, but not very much. See 
http://dev.plone.org/collective/browser/collective.wtf/trunk/collective/wtf/exportimport.py#L128 
for an example.


That code uses a hard-coded factory and the first part of the file name 
is used as 'id'. Right?


Yeah. collective.wtf isn't a complete solution for a lot of things - it 
also ignores a bunch of things that are edge cases or never used in 
Plone, at least. It is, however, easier to work with that the 
workflows/*xml format in 90% of (Plone) cases. Anyway, that's moot here.


The types tool can contain many different objects: Several kinds of 
TypeInfos and scripts for ScriptableTypeInfos. You can't hard-code the 
factory, you have to parse the file to find out which factory is required.


Yeah, I know. We'd need to look in the file for the id and meta type. 
See below.


But you can't be sure the file is an XML file of a specific format. The 
import/export adapter for scripts has a different format. I haven't seen 
an alternative adapter for TypeInfos, but right now you can plug in a 
different format (like CSV for workflows) by using a different 
import/export adapter.


How about we turn it on its head. If we have an importer that scans 
types/*.xml and looks for files to parse, it can create the objects in 
portal_types if they don't already exist. That should be safe for other 
import handlers too. And of course, it should be done defensively, so 
that if types.xml was present it was parsed first and types that exist 
would not be overwritten, as now.


In general, repetition like this is counter-productive. I've had to 
explain this to three people new to Plone recently, and it feels like 
I'm making excuses rather than a strong case.


We could add 10 lines of code and save 100 people from making common 
mistakes that cause problems of the type why doesn't my workflow show 
up? with no errors or warning messages.


I would probably not deprecate the existing two-file pattern though, 
just make it optional.


I'm not happy with the current file format. But representing containers 
is a general problem and I want *one* generic solution that works for 
all use cases.


I'm not sure most people think of portal_types as a container per se. 
Rather, they think I need to register my content type, and for that I 
need an XML file that describes it. The fact that portal_types is a 
container for FTI objects is an implementation detail that probably 
doesn't belong too explicitly in the declarative GenericSetup syntax.


We have .objects files for content and .xml files for configuration. You 
propose a different pattern, and I doubt it could replace the other two 
patterns.


Mmmm I'm not sure I agree. Unless you happen to be intimately 
familiar with the implementation of TypesTool and WorkflowTool and other 
things, then these are not the same really. The use case is just to 
register types and workflow definitions. Each of those has a custom 
format anyway.


In general, I think warning signals should go off when we require people 
to type the same thing in more than one place or ensure that names 
match across multiple files and file names. It's far too easy to make 
mistakes, it's too easy to forget to change one during refactoring, and 
it's hard to explain and document. The DRY (Don't Repeat Yourself) 
principle that Grok has adopted is a great rule to live by.


I can see that there may be edge

[Zope-CMF] Re: Why do we need types.xml and workflows.xml?

2008-06-29 Thread Martin Aspeli

Tres Seaver wrote:


One point of the types.xml file is that the type name may *not* map
intuitively onto the name of the XML file (people seem determined to
embed spaces in object names, for instance).


Sure. So now we rely on a not entirely obvious convention (space becomes 
underscore) and/or redundant information in the per-type file itself.



It is also not a given
that one knows unambiguously how to parse any give file in the types or
workflows directories.


Why not?


I strongly prefer the pattern that the tools state is stored in a common
file, with per-object customization stored in separate files:  explicit
is better than implicit. 


I don't think it's implicit to say that if we have a file in types/*.xml 
with an id and a meta_type, then that object is created in portal_types 
- with that id and meta_type - if it doesn't exist.



The redundant information is actually what
Yuppie specified:  the ID and metatype in the XML files.  Dropping that
information would be OK with me.


Sure, that reduces redundancy, but it still means that the information 
needed to install a type resides in two places, not once.


It's not entirely non-redundant, though. The id of the thing in 
types.xml and the filename have to match (with the space-to-underscore 
mapping).



Note that both the workflow and the types tools *are* containers for
arbitrary objects:  there are cases in the wild, for instance, which
deploy non-DCWorkflow objects as workflow definitiions, and which have
non-standard type info objects.  Using heuristic rules makes it harder
to support such combinations.


I'm not sure I understand why it's harder. I'm not really talking about 
a heuristic, I don't think. Rather, I think the algorithm could be:


 - list all files in types/*.xml
 - read id
 - if it doesn't exist in portal_types:
 -- read meta_type
 -- create object of this type
 - else:
 -- fetch object with this id
 - populate with type info

As a bonus, we no longer depend on the file name matching the id 1:1.

The assumption here is that types/*.xml is reserved for the standard 
property-based type import/export handler. If I had a different type of 
FTI with a different parser, I'd need to pick a different directory.


I don't think that's any less reasonable than to say that types.xml (or 
propertiestool.xml or whatever) is specific to the default types 
import/export handler.


Is there any documentation anywhere that explains what types.xml is 
needed for and how it relates to types/*.xml? I've tried to explain to 
people why we need both, and I can't come up with a compelling argument, 
even after reading this thread. :-/


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Why do we need types.xml and workflows.xml?

2008-06-28 Thread Martin Aspeli

Hi guys,

The GS handlers for portal_types and portal_workflow both require a 
single file - types.xml and workflows.xml - that declares the objects, 
and a directory full of files - types/*.xml and workflows/*.xml - to 
initialise them.


However, in both cases, there is enough information in the per-item 
files (id, meta_type) to make the types.xml and workflows.xml redundant. 
Worse, it's easy to forget, and no warning that there are orphan files.


I'm pretty sure it's an easy fix to make types.xml and workflows.xml 
optional (or even deprecated, though of course workflows.xml also has 
bind information that should remain there).


Is there a reason to keep this repetition?

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: cmfuid and zope.app.intids

2008-05-29 Thread Martin Aspeli

Miles wrote:

Hi,

I was wondering if the CMFUid package could be replaced by a thin 
wrapper around zope.app.intids.  As (I think) one of the few users of 
CMFUid, I'd like to replace it within something a little more robust and 
this seemed like a possible way to do it.


Generally, I've found having the concept of uids available a very useful 
thing.  So, my questions are:


  - Has anyone used zope.app.intids at all, or done anything similar?


Yes. There's a five.intid package for Zope 2 integration. This is used 
by plone.relations and plone.app.relations. The latter are actually very 
nice reference engine implementations (and not Plone specific as far as 
I'm aware).



  - Does this sound achievable at all?


Yes.


  - Is this a generally useful thing to do?


Yes, but beware of migration.

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Workflow state change event

2008-05-15 Thread Martin Aspeli

Tim Terlegård wrote:

I was wondering if it perhaps would make sense to move the
ActionSucceededEvent notification after the reindexing of the
workflow status has been done?

doActionFor(...) calls _invokeWithNotification(...) and the bottom
of that method looks like this:

def _invokeWithNotification(self, wfs, ob, action, func, args, kw):
 ...
 for w in wfs:
 w.notifySuccess(ob, action, res)
 notify(ActionSucceededEvent(ob, w, action, res))
 if reindex:
 self._reindexWorkflowVariables(ob)
 return res

In an event handler I would like to use the catalog and search for  
published
objects, but it's not possible because the catalog is updated after  
the event

handler is triggered.


That shouldn't matter, though - you get the object as part of the event, 
no need to search for it.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: What is the status of GS wiping catalog indexes on catalog.xml import?

2008-02-29 Thread Martin Aspeli

Andreas Jung wrote:


--On 28. Februar 2008 20:35:09 +0100 Dieter Maurer [EMAIL PROTECTED] 
wrote:



Andreas Jung wrote at 2008-2-28 07:13 +0100:

--On 27. Februar 2008 21:59:58 + Maurits van Rees
[EMAIL PROTECTED] wrote:


greenman, on 2008-02-27:

So, for the catalog.xml importer, why can't the trigger for reindexing
an index be a flag on the catalog index declaration itself? Is it
really generic setups role to determine if changes to an index
invalidate the values it already holds? If you were to change
properties of an index through code and not GS, then it would be up to
you whether you reindexed all your objects or not.

The problem is that GenericSetup does not know if your current index
is of the same type and has the same settings/properties as the index
that you specify in catalog.xml.  Apparently it is hard/impossible to
reliably compare the existing and the wanted index.  So GenericSetup
has no choice but to remove the existing index and make a new one.



How about the following idea:

- within the Zope core we define an _optional_ interface for indexes -
  something like:

 class IIndexConfiguration(Interface):

 def getConfiguration():
  Returns a dict with index specific configuration
 parameters.
 

- on the CMF/GS side we could register adapter for each index type
  we know (basically the Zope 2 core indexes, ExtendedPathIndex,
  TextIndexNG 3) and retrieve the related information

I do not understand why something like this should be necessary.

When the export handler is able to extract all relevant configuration
parameters for an index, why should the import handler
not be able to check the configuration parameters in a profile
against an existing index and determine that it needs to do nothing?


Huh? Because we're looking for a clean solution and not for a hack!
Because this solution is extensible. An index can provide the introspection 
directly or another application could implement the functionality as needed 
through adaption. Having something hardcoded for each index type within the 
setuphandlers is a hacker solution. And the setuphandler should ideally not 
know about index internals.


Respectfully, I'd say that if we can have a hacky solution today that 
doesn't wipe indexes on re-install, then that's very valuable. The set 
of standard index types is well known and doesn't change much.


Of course, we should also provide a way to get an interface or something 
else describing the configuration for introspection purposes. Waiting 
one or two Zope versions for that to get a non-purging GS import handler 
when there's a works-90%-of-the-time solution (falling back on current 
behaviour) would be a shame though.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] GenericSetup: using global steps

2007-12-22 Thread Martin Aspeli

Tres Seaver wrote:


Worse, an import is potentially destructive.  I am now of the opinion
that content import / export should be treated as a separate
application, not built into the profile.


From a design perspective, I'd tend to agree. I've always felt that the 
'structure' import step sat a bit awkwardly with the rest of GS.


That said, there are grey bits. For example, I'm working on a Plone 
enhancement to make it possible to manage portlet setup (assignment) via 
GenericSetup. That's easy enough for global portlets, but some 
portlets may be assigned to specific folders. Both export and import are 
tricky here.


Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: eggification status?

2007-11-06 Thread Martin Aspeli

Tres Seaver wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

yuppie wrote:

Hi!


Right now there are two versions of CMFCore and GenericSetup:

Products.GenericSetup and GenericSetup
Products.CMFCore and CMFCore

wichert is currently working on GenericSetup/trunk, tseaver stitched 
today the 6 weeks old Products.GenericSetup/trunk/Products/GenericSetup 
into CMF/trunk/ and 
Products.GenericSetup/tags/1.3.2/Products/GenericSetup into 
CMF/branches/2.1/


Products.CMFCore seems not to be used - changes still go into CMF/*/CMFCore

Can we please have *one* location for each product?


Ouch, sorry about that.  I forgot I hadn't merged the change to use
'Products.GenericSetup' already.  I'd rather that we moved to use
'Products.GenericSetup' and 'Products.CMFCore' everywhere, and leave the
older stuff just pulling in from externals.


+1 - me want repoze :)

Martin

--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: CMF collector on Launchpad?

2007-08-13 Thread Martin Aspeli

Jens Vagelpohl wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Andreas Jung is in the process of getting the regular Zope 2 issue  
collector moved onto Launchpad. He said the Launchpad guys could move  
other collectors like the CMF collector at the same time. The  
question is, do we want this?


My vote is -0.5, mostly because I never used Launchpad. One  
drawback that was mentioned is the fact that bugtracker emails do not  
contain the full bug history. From other bugtracker experience I know  
that's very annoying.


Andreas mentioned some arguments for the move, like having the same  
user base on all those collectors, the ability to move bugs between  
them, and a much better user interface than the sometimes odd  
collector UI.


What's the consensus?


+1 to move. I find the CMFCollector instances on zope.org incredibly 
cumbersome and unintuitive to use. The downside is that you'd probably 
get more people reporting bugs because they are able to figure out how. ;-)


Martin

--
Acquisition is a jealous mistress

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: GenericSetup extension profile import step mis-feature

2007-07-31 Thread Martin Aspeli

Hanno Schlichting wrote:


One example where the current behavior makes sense is when you write an
add-on product which wants to install itself into a standard Plone site
and change the settings of the Archetypes tool. The import handler for
the Archetypes tool is only specified in the extension profile for
Archetypes and not in the Plone base profile. It is however always
installed into a Plone site via an import various step.


Mmm, well that's another problem: Installing one profile during 
installation of another also does not work reliably (I believe Rob was 
working on a generic dependency solution for this).



I think this kind of decoupling the different profiles into the packages
they came from is a sensible idea. In order for that to work reliable we
need to have some profile dependency support, though.


Right. You could extend my argument to include and those extension 
profiles explicitly marked as dependencies of the current base profile 
or the extension profile being installed.



When we would have that I would extend your idea in the following way:


The only sane behaviour, IMHO, is this:

 - When importing a base profile, only steps from the base profile are run.

 - When importing an extension profile, only steps from the *current*
base profile and any additional steps explicitly defined in the
*selected* extension profile (via an import_steps.xml file) are run.


In both cases all the steps from any (recursively) defined dependencies
are run as well.


Yes.


So the Plone Base profile would depend on the Archetypes extension
profile (as well as the other half a dozen we install manually right
now) and you could always assume the Archetypes tool import step to be
present.

For an add-on X it can decide to depend on Y and thus re-use all of
their import steps as well, without having to specify the handler itself.


No steps are ever implicitly pulled in from other extension profiles,
and switching base profiles resets the base set of steps that are run
for any extension profile.

Another solution (better than the current behaviour, less good imho than
the solution above) would be to load all steps from all profiles at Zope
startup, when the profile registry is populated, so that all steps are
always run if a package registering a new step is installed. This still
means having lots of flag/file-checking and could be quite inefficient.


This is really bad. That way if there is some experimental profile
registered somewhere it would get loaded automatically. So as soon as I
have one broken import step somewhere I would have no chance to exclude
it. The registration of an import step should still be an explicit task.


Yeah, good point. :)


What do you think? Is there a sane use case for the current behaviour?


Apart from the decoupled but guaranteed-to-be-there extension profiles I
cannot think of any.


Explicit being better than implicit and all that. :)

Martin


--
Acquisition is a jealous mistress

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Re: GenericSetup extension profile import step mis-feature

2007-07-31 Thread Martin Aspeli



yuppie-3 wrote:
 
 Hi!
 
 
 The proposed solution doesn't work:
 
 The ImportStepRegistry is not only used for imports - it is also used 
 for creating new 'import_steps.xml' files for exports.
 
 Exported profiles are always base profiles, they have to specify *all* 
 import handlers used for creating the site.
 

Right, that's fine. I think the current export functionality is right.
However, the current *import* functionality for extension profiles is
arbitrary and unpredictable.

What if we stored in the import step registry:

 - The setuphandler to call
 - The base or extension profile it came from

For an export operation, you just take the union of all the steps
(de-duplicated, of course).

For an import operation, you run:

 - All steps that came from the current base profile
 - All steps that came from explicit, transitive dependencies of the current
base profile (provided we get support for declaring profile dependencies)
 - All steps explicitly defined in the extension profile being run
 - All steps explicitly defined in transitive dependencies of the extension
profile being run (provided we get support for declaring profile
dependencies)

Transitive here means that if A depends on B and B depends on C, we run
steps from A, B and C.



 I can see two ways to specify available import steps:
 
 1.) 'import_steps.xml' is used as an index of available import steps. 
 That's the way it was used before extension profile support was added to 
 CMFSetup. It requires to maintain a lot of redundant information and a 
 way to identify and remove duplicate steps for exports.
 

Yes... this sounds like what I am talking about above?



 2.) The files in the profile determine which import steps are available. 
 This is the current behavior, but further changes would make this more 
 clear: Getting rid of 'import_steps.xml', using a global handler 
 registry instead. And adding new code that checks if a step is available 
 without actually running it.
 

I'm not sure how this gets any clearer... e.g. how does the author of an
extension profile for an add-on product ensure that the steps he needs are
in the registry?

To me (and for a long time when I was using this blissfully unaware)
extension profiles really are separate entities that will generally be
applied in an uncontrolled order (unless we get explicit dependency support,
which would be really great). Flag files (be they empty boolean switches or
XML files with processing instructions) feel like a dirty way of dealing
with this unpredictability.

Martin
-- 
View this message in context: 
http://www.nabble.com/-Zope-CMF--GenericSetup-extension-profile-import-step-mis-feature-tf4190394.html#a11922157
Sent from the Zope - CMF list1 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Re: GenericSetup extension profile import step mis-feature

2007-07-31 Thread Martin Aspeli



Tres Seaver wrote:
 
 
 I think it's wrong :) The export functionality suffers from the same
 problen as the import functionality: the export steps defined in
 extension profiles are only used if they have been selected once.
 In other words: it is just as unpredictable.
 
 What is unpredictable?  If you import an extension profile, its steps
 (both export and import) get grafted into the effective baseline profile.
 

Yes, that's true and right.

What's unpredictable is that it gets grafted in (at least to import steps, I
haven't tested export steps) even if you only *look* at the profile in the
Import tab. As soon as you select a profile to look at what steps it offers,
those steps are forever part of the registry, whether you run them or not.

Martin
-- 
View this message in context: 
http://www.nabble.com/-Zope-CMF--GenericSetup-extension-profile-import-step-mis-feature-tf4190394.html#a11924305
Sent from the Zope - CMF list1 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Re: GenericSetup extension profile import step mis-feature

2007-07-31 Thread Martin Aspeli



yuppie-3 wrote:
 
 
 For an import operation, you run:
 
  - All steps that came from the current base profile
  - All steps that came from explicit, transitive dependencies of the
 current
 base profile (provided we get support for declaring profile dependencies)
 
 ???
 
 Base profiles have per definition no dependencies. No?
 

Probably, though in Plone, for example, it'd be very useful to be able to
say when installing Plone, please also install extension profiles from
Archetypes and CMFEditions, where those are dependencies. That's mostly
from a code-management point of view, though. Anyway, that functionality
doesn't exist yet, so let's not quibble.



 Not really. You are mixing both ways: Some import steps come from the 
 registry (or are looked up in other profiles?), some from 
 'import_steps.xml'.
 

I think looked up in other profiles is more predictable for imports, where
other profiles means the current base profile and any explicit
dependencies, plus the one being installed right now.



 2.) The files in the profile determine which import steps are available. 
 This is the current behavior, but further changes would make this more 
 clear: Getting rid of 'import_steps.xml', using a global handler 
 registry instead. And adding new code that checks if a step is available 
 without actually running it.

 
 I'm not sure how this gets any clearer... e.g. how does the author of an
 extension profile for an add-on product ensure that the steps he needs
 are
 in the registry?
 
 The author of the add-on product is not responsible for this - just like 
 he is not responsible for registering all adapters or utilities used by 
 his product.
 
 The author of the setup handler should add a ZCML file that registers 
 the setup handler.
 

Okay, that's different, now we have an instance-global registry. That may
make sense, though Tres pointed out you'd need to not run unexpected export
steps on export, for example.



 To me (and for a long time when I was using this blissfully unaware)
 extension profiles really are separate entities that will generally be
 applied in an uncontrolled order (unless we get explicit dependency
 support,
 which would be really great). Flag files (be they empty boolean switches
 or
 XML files with processing instructions) feel like a dirty way of dealing
 with this unpredictability.
 
 Why is it more explicit to have a 'flag' import step in 
 'import_steps.xml' or in 'import_steps.xml' of a dependency than a flag 
 file in the current profile?
 

The flag file is magical. It's not used for anything.

But it's the reverse case that's the problem: As an author of product Y with
an extension profile, if I want to make sure I run steps that were in
setuphandlers in product X, I don't have a sane way of making sure they get
run. They *may* get run if the user looked at and/or ran the import steps
for X, but I have no way of controlling that.

Therefore, I have to be explicit and include those steps. Therefore, having
import steps from extension profiles be additive is an unpredictable
feature. Therefore, why require magic flag files?

Obviously, that goes away with an instance-global setuphandler registry.
Then we still have flag files, but at least it's predictable.

Martin
-- 
View this message in context: 
http://www.nabble.com/-Zope-CMF--GenericSetup-extension-profile-import-step-mis-feature-tf4190394.html#a11924378
Sent from the Zope - CMF list1 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Re: GenericSetup extension profile import step mis-feature

2007-07-31 Thread Martin Aspeli



Tres Seaver wrote:
 
 'importVarious' is a brutal hack:  better to focus efforts on making it
 disappear.  The entire point of the tool is to externalize configuration
 as declarative data in the profile;  accomodating imperative
 configuration is not something I care to support.
 

I think that's a bit puritanical. Sometimes it's just not possible to have
declarative configuration for anything, either for time or complexity
reasons. There will be setup tasks that can only feasibly be achieved in an
imperative way, and need to run during the installation of a product.



   - It's impossible to predict which steps actually get run for an 
 extension profile.
 
 Yes it is:  *all* steps will get run, and will consult the profile to
 see whether they have configuration to apply.
 

All steps of what?

The way it works now, it's all steps of any base or extension profile that
has ever been examined by the user or imported, which is not terribly
predictable.



 Say, for example, that I wrote extension profile Y and I wanted to use 
 an import handler used in extension profile X. If X had been run (or in 
 fact, looked at under the Import tab, the registry filling happens as 
 soon as you look at a profile there, even without running it) at least 
 once, then it would get attempted for Y as well. If the appropriate XML 
 or flag file was found it'd be run.
 
 That is by design.  Once an import step is grafted into the baseline, it
 is part of the site's configuration for ever.  Resetting the baseline
 profile (a drastic step) is the only way to wipe it out.
 

That makes a lot of sense for export or creation of a new base profile.
However, due to the lack of predictability of what has actually been grafted
in to date, third party product authors writing an extension profile will
never be able to safely depend on steps from anything else than a
supported base profile (or explicit dependencies if and when we get
those).



 But there is no way for Y to know that X was run (or looked at). In 
 fact, it may be that users of Y do not want X to be loaded at all.
 
 You'd better make this un-abstract:  the presence of the enabling files
 in the profile being imported *is* the signal that those steps should be
 active.
 

It's not about files, it's about the registry.

Here's an example from Plone:

 - Product CacheFu has an extension profile that declares a new import
handler for the Cache Settings tool/control panel. Let's say it creates a
handler for the cache.xml file.

 - Product MyContentType wants to configure caching, with a cache.xml file.

Now, if CacheFu has been looked at once or imported, cache.xml is run.
CacheFu may or may not be in a sane state at the point (e.g. if you just
looked at the profile, you may get an error because the setuphandler is
expecting CacheFu to be installed when it isn't). 

Equally, if CacheFu isn't installed and was never looked at, the cache.xml
file is never run, even though the product author probably intended it to
be.

Of course, there may be a good reason to have cache.xml not be processed if
CacheFu isn't installed, but it's still unpredictable. The only way I can
make it predictable would be if I explicitly declared a dependency on this
profile and/or I explicitly declared a dependency on the product that
provided it.

In other cases, the setuphandler may be more generic and thus not really
depend on e.g. a tool being installed. In that case, it may be very
desirable to have the XML file always be processed, but it won't happen
unless the product with the setuphandler was installed or looked at once.



 The only sane behaviour, IMHO, is this:
 
   - When importing a base profile, only steps from the base profile are
 run.
 
 Do you mean when setting a new baseline?  Otherwise, -1:  snapshots, for
 instance, are baseline profiles, and represent accumulated steps.
 

Yeah, you're right.


   - When importing an extension profile, only steps from the *current* 
 base profile and any additional steps explicitly defined in the 
 *selected* extension profile (via an import_steps.xml file) are run.
 
 No steps are ever implicitly pulled in from other extension profiles, 
 and switching base profiles resets the base set of steps that are run 
 for any extension profile.

There is nothing implicit about this:  those steps are part of the
configured state of the site.  If the profile-being-imported has
configuration for them, they should do their stuff;  otherwise, they
should pass.



 As above:  quit doing imperative configuration, and the problems go away.
 

I wish I could, but I've yet to come across a non-trivial product where I
didnt need at least a tiny bit of imperative configuration. Most often, it's
because things I depend on don't yet have (sufficiently expressive) XML
configuration for the option I need to set. I don't really want to invent my
own XML syntax for third party products all the time.

Martin
-- 
View this message in context: 

[Zope-CMF] GenericSetup extension profile import step mis-feature

2007-07-30 Thread Martin Aspeli

Hi guys,

After a lot of is-this-a-bug type discussions with Rob and Wichert, 
I've come to feel pretty strongly about the following:


When you load an extension profile for the first time in GS, it looks to 
see if it has any import steps (in import_steps.xml) that are not 
already known. If so, it adds them to the import step registry and 
then runs all steps in the registry.


Any time a profile (the same, or another one) is run subsequently, that 
import step will be run too. In Rob's words, the import steps and the 
profile that they came from (import_steps.xml-wise) get decoupled.


We normally don't mind too much, because steps are run in the context of 
a particular profile, and if that context has no matching XML file, 
nothing is loaded. At least so we assume - there's of course nothing to 
stop the setuphandler from having side effects even if the XML file is 
not found. We *do* see a problem with importVarious-type hacks, though. 
Here, people resort to checking for a flag (normally an empty text 
file) to determine if the setuphandler should be run.


I believe this is fundamentally Bad(tm) for three reasons:

 - People don't expect it to work that way.
 - Authors of setuphandlers have to be a lot more careful about having 
side effects on entirely alien packages.
 - It's impossible to predict which steps actually get run for an 
extension profile.


Say, for example, that I wrote extension profile Y and I wanted to use 
an import handler used in extension profile X. If X had been run (or in 
fact, looked at under the Import tab, the registry filling happens as 
soon as you look at a profile there, even without running it) at least 
once, then it would get attempted for Y as well. If the appropriate XML 
or flag file was found it'd be run.


But there is no way for Y to know that X was run (or looked at). In 
fact, it may be that users of Y do not want X to be loaded at all.


The only predictable way for Y's author to run said import step is to 
explicitly list a setuphandler from X's package in Y's own import_steps.xml.


I cannot see a good use case for the current behaviour, and it causes a 
lot of confusion (either why was this step run again? or why wasn't 
this step run?). Having to have flag files for pure-python 
setuphandlers is also pretty hacky (even if such handlers themselves are 
a bit hacky, but sometimes unavoidable).


The only sane behaviour, IMHO, is this:

 - When importing a base profile, only steps from the base profile are run.

 - When importing an extension profile, only steps from the *current* 
base profile and any additional steps explicitly defined in the 
*selected* extension profile (via an import_steps.xml file) are run.


No steps are ever implicitly pulled in from other extension profiles, 
and switching base profiles resets the base set of steps that are run 
for any extension profile.


Another solution (better than the current behaviour, less good imho than 
the solution above) would be to load all steps from all profiles at Zope 
startup, when the profile registry is populated, so that all steps are 
always run if a package registering a new step is installed. This still 
means having lots of flag/file-checking and could be quite inefficient.


What do you think? Is there a sane use case for the current behaviour?

Martin

--
Acquisition is a jealous mistress

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] tools-as-utilities roadmap

2007-07-06 Thread Martin Aspeli

yuppie wrote:

Well. The 2.1 changes are based one the assumption that we switch 
quickly and completely to utilities, making all tools work as utilities. 
The roadmap proposed by Tres means it will take several years and we'll 
have to work with tools and utilities side by side for a long time.



I can live with that approach, but would like to see CMF 2.1 adjusted:

'getToolByInterfaceName' is a completely misleading method name if tools 
will not become utilities. This method has no 'context' (or 'REQUEST') 
argument, so it can't return tools. It returns utilities. 
'getUtilityByInterfaceName' would be a much better name for a 
'getUtility' replacement used in untrusted code.


I propose to run a search 'n' replace *before* the next beta.


I'm getting a bit lost in all the jumps back and forth now, but can I 
please ask (beg?) that the following stays true for CMF 2.1 at the very 
least:


 - getToolByName works as before, on all standard tools
 - getToolByName never spits deprecation warnings

I support a move to utilities and views (if they are true utilities and 
views, not just for the sake of more Zope3ish syntax) in principle, 
but I've already converted a whole bunch of code to use getUtility and 
then had to convert it back to getToolByName.


I'm also in the position of writing documentation and issuing 
guidelines. A rule that says X and Y are acquired using getToolByName, 
A, B and C you have to use getUtility is just too arbitrary and 
confusing for most people.


Martin

--
Acquisition is a jealous mistress

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] five.localsitemanager: proposal

2007-06-23 Thread Martin Aspeli

Hi Yuppie,

This proposal is now implemented on CMF and five.localsitemanager trunk. 
Everything *seems* to work, but maybe I'm missing something. This might 
be a good time to review and test the changes - any feedback is welcome.


Well done - great work! :)


Done:
-

There are 10 tools in CMF that are not ready for being used as 
utilities, they have to be used the old way until they are fixed:


content_type_registry
cookie_authentication
portal_actions
portal_calendar
portal_catalog
portal_skins
portal_types
portal_uidhandler
portal_url
portal_workflow


Are these registered as utilities as all? Or only available using 
getToolByName?


These 15 CMF tools are registered as utilities, AFAICS only the security 
machinery uses their acquisition context (except for portal_membership, 
which uses 'self.acl_users'):


Products.CMFActionIcons.interfaces.IActionIconsTool
Products.CMFCore.interfaces.ICachingPolicyManager
Products.CMFCore.interfaces.IDiscussionTool
Products.CMFCore.interfaces.IMemberDataTool
Products.CMFCore.interfaces.IMembershipTool
Products.CMFCore.interfaces.IMetadataTool
Products.CMFCore.interfaces.IPropertiesTool
Products.CMFCore.interfaces.IRegistrationTool
Products.CMFCore.interfaces.ISiteRoot
Products.CMFCore.interfaces.ISyndicationTool
Products.CMFCore.interfaces.IUndoTool
Products.CMFUid.interfaces.IUniqueIdAnnotationManagement
Products.CMFUid.interfaces.IUniqueIdGenerator
Products.GenericSetup.interfaces.ISetupTool
Products.MailHost.interfaces.IMailHost


five.localsitemanager now returns wrapped utilities without 
RequestContainers. This requires a new LookupClass.


Interesting.

Do we still get deprecation warnings if these are looked up using 
getToolByName?


My feeling is that we should *not* get deprecating warnings for these. 
It's rather late in the day for this release to officially deprecate 
such fundamental parts of CMF, and I fear that people won't be able to 
remember which tools are now utilities and which ones are tools, since 
the distinction really comes down to implementation detail.


Hopefully, the path forward is that *all* the tools become utilities 
(your last to-do below). In that case, I think full deprecation of 
lookup via getToolByName makes sense, since we have a uniform API 
(getUtility()) for looking up CMF's fundamental components. Until then, 
I think we should give people the choice on the utilities we still have, 
but not prod them too hard.



ToDo:
-

- real world testing

- backport to the CMF 2.1 branch


Is this in the pipeline? i.e. will this code land in Plone 3.0? :-)

- write migration code for CMF 2.1 beta sites that replaces the 
LookupClass and removes some utility registrations


Plone will likely need the same migrations.


- fix the GenericSetup handler


How so?


- figure out if we can make acl_users an utility


Spooky...


- in the long run, modify all tools to make them work as utilities


Yes - as per above, I think this needs to be the ultimate goal.

AFAICS, KSS will no longer need the monkey patch if it sets the 
LookupClass to FiveVerifyingAdapterLookup.


Great - this is really wonderful news.

Martin

--
Acquisition is a jealous mistress

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Re: Making TypesTool faster

2007-05-04 Thread Martin Aspeli



Charlie Clark-3 wrote:
 
 
 Am 03.05.2007 um 00:50 schrieb Alexander Limi:
 

 At present, Archetypes-based content types cannot be used with a  
 factory (I
 tried hard, but there are some acquisition-related/factory related  
 reasons);
 I'd like to refactor this, but we can't for Plone 3.0 at least.

 Right. Obviously, we'd like to do this the proper way, but we  
 can't do that for a while yet.
 
 I'm sorry but it's -1 from me. The change is unnecessary and the  
 problem seems to be with Archetypes and not the CMF. In my view it is  
 incorrect to change the infrastucture to compensate for the  
 deficiencies of a component. If you need it in Plone you can add it  
 as a patch.
 

I'm not entirely convinced the problem is in AT, and I think we are
conflating two different issues here. One is an observation of Tres' that AT
has a function that could perform more cacheing. That's a good point, and
may mitigate some of the performance issues by cacheing at a higher level,
but it doesn't mean there aren't further opportunities for improvements to
the underlying code.

The other issue is some code in TypesTool which is making a lot of calls to
a procedure in Zope which is unlikely (impossible?) to ever return a
different result until Zope is restarted and new products are detected.

If the two are orthogonal, and we already have a sane patch, then why not
(at least if we can get some tests in place) fix the one at the CMF level
and deal with the other Archetypes issue separately.

Martin
-- 
View this message in context: 
http://www.nabble.com/Making-TypesTool-faster-tf3678114.html#a10321411
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Making TypesTool faster

2007-05-03 Thread Martin Aspeli

Tres Seaver wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Alexander Limi wrote:
On Wed, 02 May 2007 10:03:39 -0700, Martin Aspeli  
[EMAIL PROTECTED] wrote:



+1, but I don't think the two need to be mutually exclusive.

Amen.

At present, Archetypes-based content types cannot be used with a factory  
(I
tried hard, but there are some acquisition-related/factory related  
reasons);

I'd like to refactor this, but we can't for Plone 3.0 at least.
Right. Obviously, we'd like to do this the proper way, but we can't do  
that for a while yet.


I do have a notion which would make this better, faster, stronger for
Plone, which is much more afflicted by this problem than other CMF-based
sites (because it presents an add menu on each page):  I think the
bottleneck is actually inside 'ATContentTypes.lib.contraintypes', in the
'getDefaultAddableTypes' method of the 'ConstrainTypesMixin' class:  it
could cache the typeinfo list (or a list of mappings derived from it),
with the container and the user_id as keys.

Most of the win would come immediatelely, and at the place most affected
by the clurrent slowness, leaving us time to figure out why Z3-style
factories don't work with AT.


I know why... or rather, I did know, and I'm sure if I looked it again I 
could remember. It has to do with the extra work that's being done in 
the auto-generated factory (see ClassGen.py) which calls 
initializeArchetype(). I'd love to get rid of this (for various 
reasons), but I tried to rewrite it as a factory and failed (this is 
where I don't remember why).


Given that Alec  co essentially had a patch which worked, I suggest  
that we

have a look at it, and include it if possible, and then encourage the use
factories in general. I'd hope we could avoid deprecating it outright  
until

we can fix up AT to use them, though.
Also note that according to Alec, it would work better as a instance-level  
thing than a thread-level one.


The cache is actually based only on the container (which could be a
path) and the user ID.  It would be a perfect use of a RAM Cache Manager
 (assuming that we cached mappings rather than persistent references).
Using a volatile here (which is what I assume you mean) would dilute the
locality of the cache by the number of database connections in use.

I've looksd, and all the callers of 'getDefaultAddableTypes' need only
the ID and / or the title of the FTI, which simplifies things a bunch.


Isn't this something like 2 lines of code in TypesTool? :)


I don't think so.  Getting the tests right is likely to be *lots* of
lines of code in 'tests/test_TypesTool.py', if we make the change there.


I feel like we're having a very abstract discussions here. Have you 
looked at the patch Alec/Ben/Mike/Rob did? If not, Limi - can you find 
it and paste it here so that we can discuss its merits? I don't recall 
whether it came with tests, but even so it didn't look terribly complicated.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Making TypesTool faster

2007-05-02 Thread Martin Aspeli



Tres Seaver wrote:
 
 Before we look at optimizing the use of the product dispatch mechanism,
 I'd like to propose deprecating it in favor of the factory-utility
 mechanism:  leaving the 'product' field blank in an FTI, and having the
 'factory' field be the name of a utility registered for
 'zope.component.interfaces.IFactory'.
 

+1, but I don't think the two need to be mutually exclusive.

At present, Archetypes-based content types cannot be used with a factory (I
tried hard, but there are some acquisition-related/factory related reasons);
I'd like to refactor this, but we can't for Plone 3.0 at least.

Given that Alec  co essentially had a patch which worked, I suggest that we
have a look at it, and include it if possible, and then encourage the use
factories in general. I'd hope we could avoid deprecating it outright until
we can fix up AT to use them, though.

Martin
-- 
View this message in context: 
http://www.nabble.com/Making-TypesTool-faster-tf3678114.html#a10290398
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: tools, utilities, and getToolByName

2007-04-22 Thread Martin Aspeli

Rocky wrote:

On Apr 19, 12:52 pm, Martin Aspeli [EMAIL PROTECTED] wrote:

 -1 to relying on five.localsitemanager, especially if it means other site
managers somewhere inside the CMF site will need to be five.lsm aware.


Not sure what relying on five.lsm means... because if we don't use
five.lsm, then having sub-ISite's beneath a CMF site will break the
site due to the fact that current Five doesn't produce __bases__'s
properly.  This was the primary reason for doing five.lsm, to make
sure sub-ISite's work.

In effect, having a cmf portal be an ISite but not having a working
__bases__ actually does more harm than good.


So are we saying we need a bugfix/monkey patch to Five?

By not using five.lsm I meant don't do the automatic acquisition 
wrapping.


I think I still don't quite understand why five.lsm breaks normal Zope 
3 site managers, but I was under the impression that if we kept on using 
such normal site managers ourselves, it should just work. I didn't 
realise Five needed its own implementation.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] unresolved site manager related issues

2007-04-15 Thread Martin Aspeli

Balazs Ree wrote:
Acquisition is raping Zope3, it seems. 


That must surely be quotation of the month. :)

Martin

___
Zope-CMF maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] unresolved site manager related issues

2007-04-15 Thread Martin Aspeli

Dieter Maurer wrote:

Alec Mitchell wrote at 2007-4-12 06:59 -0700:

...
... deprecation of getToolByName ...
which is that there's no practical reason other than
aesthetics to deprecate getToolByName at this point.


A very good point: let's deprecate deprecations done just for
aethetical reasons :-)


Aesthetics were not the original reason for moving down this route, so 
it's a little unfair to cast it in that light. The main drivers, as I 
recall, were to encourage API usage that would allow us to move tools 
out of content space eventually, and to make code depending on CMF tools 
more consistent with newer code which may depend on new utilities (at 
least in the Plone world, there is a general consensus that we'd rather 
not have any more content-space tools from now on).


Martin

___
Zope-CMF maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] unresolved site manager related issues

2007-04-15 Thread Martin Aspeli

Rob Miller wrote:

i'll add yet another me too to this chorus.  removing getToolByName has 
become considerably more trouble than it's worth.  currently, i see basically 
two options being suggested:


- adding (and then living with) yet more code in Five, which changes the 
behaviour of clean, well established Z3 idioms in order to support Z2 
components which require acquisition.


- undeprecating an extremely widely used, intended-to-be-future-proof Z2 
idiom, which would allow us to interact more simply and predictably with 
existing Z3 utility lookup code


i guess it's pretty clear which one i support.  ;-)


For the record, my personal preference was to *not* deprecate 
getToolByName (yet), but to allow the use of getUtility and to have 
getToolByName use getUtility internally. This would encourage a more 
consistent API (as we develop new proper utilities) and eventually 
we'd be able to move tools out of content space, with getToolByName 
providing a (perhaps eventually deprecated) backwards compatible alias 
for older tools that graduated to utilities.


When we first discussed this, no-one had thought about the acquisition 
dependency, I think. If it were so that no tools really dependent on 
acquiring things to function, I think that the above would have been a 
viable and forward-looking solution. It may yet be, but it seems the 
debate at this point is, can we make utilities be 
acquisition-independent and if not, do we go for a stopgap measure that 
may cause more problems than it solves, or do we need to wait.


Also, having used the new API (import interface, use getUtility) I much 
prefer it to getToolByName. But that's just a personal preference. :)


Martin

___
Zope-CMF maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] unresolved site manager related issues

2007-04-15 Thread Martin Aspeli

Tres Seaver wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Martin Aspeli wrote:

Kapil Thangavelu wrote:
On Thu, 12 Apr 2007 06:16:23 -0400, yuppie [EMAIL PROTECTED]  
wrote:



Hi!


Philipp von Weitershausen wrote:

yuppie wrote:
Kapil's also right when he says that utilities by principle are  
context-less components.
By principle all Zope 3 code might depend on setSite to work as  
expected. We just don't pass that 'site context' explicitly to the  
component as in Zope 2.


contextual lookup is very a different notion, that context implementation  
dependence. utilities don't have context implementation dependencies in  
zope3, the majority of cmf tools do.
Just so we are clear, can anyone point to a good example of a 
not-trivial-to-change place where CMF tools have inherent dependencies 
on acquisition?


Security is inherently placeful in Zope2:  it requires being able to
verify that the logged-in user is authenticated in a user folder which
is in the scope of the protected resource.

As far as I'm concerned, Zope3's model is *not* intrinsically superior:
 it doesn't support the use cases of the Zope2 model at all.  Let's just
forget the Zoep3 is better mantra and find a workable near-term
solution here:  if we have to re-implement / tweak some Zope3 machinery
to make it play nice in Zope2, then let us do so, rather than
distorting both in a misguided effort at Zope3 purity.



 - If that means continuing to use 'getToolByName' for traditional tools
  which need Zope2 security, fine;  folks who implement new utilities
  which don't need that compatibility can register them as pure
  utilities.

 - If it's easier to hack the LSM stuff to automagically wrap those
   returned  utilities which implement IAcquisitionWhatever, fine;  if
   that means in turn that folks must use the Zope2 LSM version in
   subsites, fine.


I guess the main worry is if we go down a route whereby we *always* need 
 a zope 2 version and a zope 3 version of some piece of code. Of 
course, this is often the case anyway, but that doesn't mean we have to 
make the situation worse. KSS, for example, had a set of components that 
worked well across both zopes, and now needs conditional imports for its 
base classes.



This is not rape by any stretch of the imagination;  this is
adaptation at its best.  Let's be pragmatic here, please.


The Hungarians have a colourful idea of language. :)

Martin

___
Zope-CMF maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [dev] unresolved site manager related issues

2007-04-15 Thread Martin Aspeli

Alec Mitchell wrote:

On 4/15/07, Martin Aspeli [EMAIL PROTECTED] wrote:

Dieter Maurer wrote:

Alec Mitchell wrote at 2007-4-12 06:59 -0700:

...
... deprecation of getToolByName ...
which is that there's no practical reason other than
aesthetics to deprecate getToolByName at this point.

A very good point: let's deprecate deprecations done just for
aethetical reasons :-)

Aesthetics were not the original reason for moving down this route, so
it's a little unfair to cast it in that light. The main drivers, as I
recall, were to encourage API usage that would allow us to move tools
out of content space eventually, and to make code depending on CMF tools
more consistent with newer code which may depend on new utilities (at
least in the Plone world, there is a general consensus that we'd rather
not have any more content-space tools from now on).


What is it about getToolByName that implies that tools are in content
space?  Consistency with newer code is an aesthetic concern as far
as I understand it.


I suppose it depends on how you look at it. If we agree that the way to 
get tools out of content space is to make them utilities, and we want to 
be able to promise the normal semantics for global and local utilities. 
In that case, moving to getUtility as the API and interfaces as keys 
seems to be a long term goal. As for consistency, call it aesthetics, 
but I know it's becoming quite hard to explain to new developers that 
various things are semantically similar, but there is an old way that 
applies to cases X, Y and Z, and then a new way that applies to all 
other cases.


Anyway, the point here is the consistency/flexibility/ease of migration 
in the future benefit vs. the cost of time/complexity and indeed whether 
it's possible to achieve all the benefits with the current tool 
implementations.


This was all nice and pretty when no-one had thought that 
tools-as-utilities needed to be wrapped at all. If that'd been the case, 
we'd just be having a deprecation warning discussion. :)


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] getToolByName depreciation, getUtility, and five.lsm

2007-03-29 Thread Martin Aspeli



Tres Seaver wrote:
 
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 Philipp von Weitershausen wrote:
 Hanno Schlichting wrote:
 I would say that all of Acquisition is dark implicit magic and something
 I expect when developing in Zope 2. When using Zope 3 concepts in Zope 2
 I also expect the need to make the Zope 3 code Acquisition aware. One
 prime example are browser views, which I need to mix in Acquisition in
 order for them to work.
 
 But Products.Five.BrowserView hides that particular detail from you, as 
 much as getToolByName could hide the acquisition detail when looking up 
 tools.
 
 You're suggesting to introduce yet another package that's destined to go 
 a way at some point, while the same functionality is already available, 
 it only needs to be un-deprecated...
 
 +1 for removing the across-the-board deprecation of 'getToolByName';
 I find Kapil's argument convincing here.  I think leaving the
 deprecation for the case where the API has to fall back to raw
 acquisition to find the tool is pretty reasonable, as it shows the user
 where the missing registrations are in her site.
 
 I'm not sure what impact that would have for the already-converted code
 which used to use the API.  I can see value both in leaving it
 converted, as showing the Zope3-ish way, as well as in reverting some or
 all of it.  For instance, perhaps we should consider reverting just
 those changes which look up acquisition-dependent tools, since the call
 site has now become required to manage the wrapper itself.
 

Do we have any idea *which* tools are acquisition-dependent and which ones
are not? By this, I mean which tools expect to be able to acquire things
from 'self', for example, not so much acquisition-dependent security around
tools being accessed TTW.

Martin
-- 
View this message in context: 
http://www.nabble.com/getToolByName-depreciation%2C-getUtility%2C-and-five.lsm-tf3483581.html#a9735489
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: getToolByName depreciation, getUtility, and five.lsm

2007-03-28 Thread Martin Aspeli

Kapil Thangavelu wrote:
A few of us (Alec Mitchell, Godefroid Chapelle, Balazs Ree, Rocky Burt,  
Daniel Nouri, Rob Miller, Vincenzo Di Somma, and myself) have been  
discussing this in depth at the Sorrento Sprint. We've reached consensus  
on how we hope to resolve the issues arising from the recent introduction  
of five.localsitemanager and the deprecation of getToolByName.


We believe that these recent changes have introduced implicit magic into a  
standard Zope3 api to fit Zope2 acquisition. There should be an explicit  
separate api if we want acquisition wrapped context-aware utilities. As an  
example of a symptom caused by the implicit implementation, KSS (which was  
developed as a pure zope 3 component) breaks when used with Plone, even  
though it is a perfectly valid z3 component. Once we return to using  
getToolByName for tool lookup, the KSS/Plone3 issue disappears, because  
the magic wrapping of things stops. This KSS/Plone3 issue arises because  
the five.lsm acquisition breaks down when you add in non five.lsm  
component registries. If you need Zope2 acquisition, you should use an  
accessor api to get things wrapped.


In addition, getToolByName is the most fundamental and widely used api in  
all of CMF, and we're going to be issuing hundreds of deprecating warnings  
for every single cmf application extant.


As a solution, we propose

* The five.localsitemanager code should *NOT* be dealing with acquisition,  
it should be restricted to setting up a bases chain for persistent  
components that does parent lookup.


* getToolByName deprecation should be reverted. Its internal mechanisms  
should be kept the same as in the current CMF 2.1 release, using  
getUtility, *AND* it should be the one doing acquisition wrapping.


So instead of doing implicit magic in the getUtility call stack, let's be  
explicit, while still allowing the flexibility that registered components  
provide. Which in turn results in an untouched zope3 getUtility execution  
path for looking up utilities.


getToolByName should return acquisition wrapped utilities via name  
mapping, and become un-deprecated.  Context for wrapping would be the  
context passed as an argument to getToolByName, as it always has been. It  
would issue deprecation warnings when it has to lookup a tool via aq_get  
instead of getUtility. The mechanism for registering tool names would  
raise an error when anyone tries to register a component which does not  
support Acquisition.


The getToolByInterfaceName method would no longer be necessary as  
getToolByName can be called from restricted code.  However if needed it  
could remain and use the result of getSite() as the context for wrapping  
the tool resulting from the utility lookup.


These are good arguments, I think. I'm not sure anyone quite could've 
predicted the trouble we had with five.lsm (is it even needed anymore if 
all of this is acted upon?), so it's good to get some fresh thinking on 
this.


The one thing I don't see here explicitly is the forward migration path. 
I think it would be worthwhile to work towards a future where we have no 
tools or other programmer-support-mechanisms in content space. I suspect 
that all context-less tools today could be rewritten to be regular 
global utilities, and all persitence-needing tools could be changed to 
be standard local utilities that if needed did getUtility(ISiteRoot) to 
get hold of the site root and acquire things from there (except, how 
does the site root then get an acquisition context? Maybe it doesn't 
need to?).


However, if we still promote and use getToolByName() then people will 
not start using getUtility() and importing interfaces and we will find 
it more difficult to deprecate (eventually) and then move to a world 
where we can have real utilities (where possible/sensible).


Going back to square one, the reason why we (and I'm very guilty in 
this) pushed for something at the framework level (spawning five.lsm) 
was that originally we ended up with calling code needing to do:


  from Products.CMFCore.interfaces import IWorkflowTool
  from zope.component import getUtility
  wftool = getUtility(IWorkflowTool).__of__(context)

Such explicit wrapping is black magic voodoo to most people and would 
probably lead to lots of hard-to-debug errors. Requiring people to know 
*when* to wrap and when it's not necessary is tantamount to requiring 
them to know the implementation details of each tool.


I would agree, though, that it's not worth breaking the way local 
component registries work in Zope 3 by imposing arbitrary acquisition on 
them if that is indeed what we're doing. I don't think it was anyone's 
intention to do so, and the five.lsm implementation was never 100% 
finished was it?


One thing I'd like to ask, is that someone asks Philipp (I've CC'd him, 
since I know he's not reading lists in detail right now) for comment, 
since he as usual had various useful insights into the original 

[Zope-CMF] Re: Delete trouble

2007-03-26 Thread Martin Aspeli

Philipp von Weitershausen wrote:


Martin Aspeli wrote:

Philipp von Weitershausen wrote:
*sigh* Chapter XYZ in my book explains the process :). Whenever you 
traverse over a site, its site manager becomes the active component 
registry. So if you haven't traversed over that site yet, the utilities 
in that site won't be found. It's that simple.

So specifically, when I'm in the root of the ZMI, tick a CMF/Plone site and
press Delete, will I be traversing over it or not?


Of course not. Your URL doesn't reach as far as the CMF/Plone site.


Well, then that'd be our problem, wouldn't it. If I'm understanding this 
problem correctly, no code in CMF or Plone that could potentially 
execute during deletion can ever assume local components will be 
available (unless explicitly passing a context parameter, I suppose).


Correct?

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Five's local sitemanager, CMF, etc

2007-03-04 Thread Martin Aspeli

Jens Vagelpohl wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


On 26 Feb 2007, at 17:03, Martin Aspeli wrote:

To get to the portal root / CMF site, I suggest a pattern that is
sometimes used in Zope3: We register the CMF site object as a utility
providing ICMFSite (or whatever). Then whichever code that's executed
below the portal (and that includes CMF tools) can do
getUtility(ICMFSite) to get to the site.

+1 - in fact, we already have  
Products.CMFCore.interfaces.ISiteRoot. I use

it all the time. :)


This is now completed on the branch. I did not try to locate every  
single place in the code where the site is looked up, though. I  
patched a couple specific places pointed out by Yuppie, and the main  
URLTool.getPortalObject method to use the utility.


Fantastic :)

Thanks!

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Five's local sitemanager, CMF, etc

2007-02-26 Thread Martin Aspeli



Philipp von Weitershausen wrote:
 
 Rocky wrote:
 On Feb 23, 3:50 pm, Martin Aspeli [EMAIL PROTECTED] wrote:
 yuppie wrote:
 Maybe I'm missing something. But wasn't a major goal of
 five.localsitemanager to return acquisition wrapped tools?
 That was my understanding, too. I thought this would just mean
 aq_base'ing the utility and aq-wrapping it back into the context (the
 portal root). Without this, we start requiring users of the interface to
 know when aq wrapping is needed and do it explicitly with __of__() which
 I think we agreed was unacceptably detailed and ugly. :)
 
 Alright, I've gone ahead and put code in place for this (albeit a bit
 naively) with r72810.  The next question is whether we should be doing
 the same with adapters and subscribers as well (even though this
 doesn't affect the whole tools-getting-acquired-properly issue).
 
 One more thing: This acquisition wrapping should clearly be marked (with 
 comments) as something that's done to for BBB because some tools happen 
 to want acquisition. I think in the future, it should be discouraged to 
 expect acquisition in CMF tools.
 
 To get to the portal root / CMF site, I suggest a pattern that is 
 sometimes used in Zope3: We register the CMF site object as a utility 
 providing ICMFSite (or whatever). Then whichever code that's executed 
 below the portal (and that includes CMF tools) can do 
 getUtility(ICMFSite) to get to the site.
 

+1 - in fact, we already have Products.CMFCore.interfaces.ISiteRoot. I use
it all the time. :)

Martin

-- 
View this message in context: 
http://www.nabble.com/Five%27s-local-sitemanager%2C-CMF%2C-etc-tf3219557.html#a9161398
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Five's local sitemanager, CMF, etc

2007-02-23 Thread Martin Aspeli

Jens Vagelpohl wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


On 23 Feb 2007, at 00:39, Rocky wrote:

So... what's next?


Figuring out how to deal with existing sites that need to be modified  
on the fly somehow so they don't break completely.


Does CMF core not have any kind of migration infrastructure?

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Re: Five's local sitemanager, CMF, etc

2007-02-23 Thread Martin Aspeli



Jens Vagelpohl wrote:
 
 After reading Phillip's book I really like Zope 3 generations, but I  
 have no idea if that mechanism could be used at all.
 

I had a look at it and started thinking about a CMFish version. The main
challenge is that generates just get the app root as a handle, so you can't
do migrations per-site, and you have to traverse the ZODB looking for CMF
sites to migrate.

For Plone, the portal_migrations tool manages migrations. They are
explicitly invoked by the user.

Martin
-- 
View this message in context: 
http://www.nabble.com/Five%27s-local-sitemanager%2C-CMF%2C-etc-tf3219557.html#a9117904
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Five's local sitemanager, CMF, etc

2007-02-23 Thread Martin Aspeli

yuppie wrote:

Hi Rocky!


Rocky wrote:

Done.  five.localsitemanager is now included with CMFCore on the jens
branch.  There aren't any CMF specific tests in place for any of this,
but the CMFCore tests all run fine with sys.path stuff setup (they
failed when I misconfigured things).

So... what's next?


Maybe I'm missing something. But wasn't a major goal of 
five.localsitemanager to return acquisition wrapped tools?


That was my understanding, too. I thought this would just mean 
aq_base'ing the utility and aq-wrapping it back into the context (the 
portal root). Without this, we start requiring users of the interface to 
know when aq wrapping is needed and do it explicitly with __of__() which 
I think we agreed was unacceptably detailed and ugly. :)


I can't find any code in five.localsitemanager that deals with that 
issue. So we now have support for nested sites, but still no support for 
utilities that need acquisition wrapping?


Hopefully, doing so would be pretty easy. :)

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Five's local sitemanager, CMF, etc

2007-02-22 Thread Martin Aspeli



yuppie-3 wrote:
 
 Jens Vagelpohl wrote:
 
 On 22 Feb 2007, at 09:03, Wichert Akkerman wrote:
 Hey Rocky, any progress? Haven't heard and loud yelling from Wichert
 yet, but I think he's getting close to the Plone 3.0 beta by now...

 I'm hoping for upcoming monday..
 
 Merging the branch into the trunk is going to be a bit of work. I'm 
 volunteering to do it, but I really need something from Rocky today or 
 tomorrow to meet your Monday deadline.
 
 IIRC existing CMF sites stop working with that branch. That has to be 
 resolved before releasing a beta.
 
 In general I'm no fan of last minute merges. There should be several 
 days between merging a big branch like that and releasing a beta.
 

In my opinion only: I'm sure we can release a Plone beta 1 that depends on a
CMF alpha if that needs to be. It's not ideal, but we can synchronise a
little later if it's impractical for everyone involved.

So, Rocky - progress?

Martin
-- 
View this message in context: 
http://www.nabble.com/Five%27s-local-sitemanager%2C-CMF%2C-etc-tf3219557.html#a9098256
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Tools as local utilities

2007-02-08 Thread Martin Aspeli

Jens Vagelpohl wrote:

Let's get this discussion back from generic pie-in-the-sky to the  
simple situation where we just need this one package integrated into  
CMF 2.1, and quickly.


+1

Wichert wants a Plone 3 beta very very soon, there is no time to  
switch the CMF to any other packaging/buildout mechanism before that.  
What happens on the trunk after the 2.1 branch is cut, I don't care.  
I do care about getting the 2.1 beta out quickly. All that's missing  
is merging the tool/utility stuff, which depends on having this new  
component registry.


Taking this into account, how should the five.localsitemanager thing  
be packaged?


My preference would be to ship CMF 2.1 as two tarballs - one for 
lib/python and one for Products, or one tarball containing Products/* 
and lib/python/* (i.e. to be extracted into the Zope instance root).


If that's unacceptable, Rocky can make localsitemanager use only 
relative imports and thus function as both a product and a package, 
though I don't know if anything needs to refer to 
Products.localsitemanager, which in turn makes it painful to use it as a 
regular python package.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Tools as local utilities

2007-02-08 Thread Martin Aspeli

Jens Vagelpohl wrote:


I'm not convinced that anything which is this tightly coupled to Zope
needs to be a package, rather than a product.  I don't think the
package zealots get the fact that purity is not a win if we have to
distort the rest of the application to satisfy it.


Amen to that.


I guess you could argue that if it's fairly close to Zope 3, then it 
should follow Zope 3's conventions. :)


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


Re: [Zope-CMF] Re: Tools as local utilities

2007-02-07 Thread Martin Aspeli



Jens Vagelpohl wrote:
 
 I won't grace the uncalled-for sarcasm with an answer. You  
 misunderstand my point. I simply don't want the existing dead-simple  
 way of creating quick sandboxes be replaced by some mechanism where I  
 need to start writing configuration files or learn some wondrous  
 framework, just because it's been decreed the technology du jour.
 

Would you be ok if you had a tarball or svn:externals to place blanket into
lib/python instead of Products? That's achiveable now (you end up with
lib/python/Products/CMFCore etc, but potentially also
lib/python/five/localsitemanager or lib/python/plone/memoize if you guys
wanted to use that).

In terms of sandboxes, I agree that zc.buildout (which is the only one of
the tools that uses a config file) can be a bit heavy for quick prototyping
(but equally useful for tightly controlled, repeatable deployments,
potentially shared by multiple developers having identical local sandboxes). 

Any workingenv-based solution will be pretty quick, though. The example I
showed for 'ploneenv' is really just calling workingenv and installing the
Plone egg. If there was a CMF egg then (a) Plone would just depend on it and
(b) any dependencies (products or otherwise) that this egg depended on would
be automatically fetched. Of course, if you have it once, it's a single
directory (or zip file), that you could lump into lib/python directly.

At the moment, Zope isn't terribly happy running tests out of eggs that are
deployed as eggs (as opposed to ones you may copy/symlink to lib/python
directly, which it runs fine). Basically, you need to do this:

$ bin/zopectl test -m my.package --test-path src/my.package

presuming the egg is in src/my.package. Various people are getting annoyed
by this, so I expect it'll be fixed fairly soon, possibly by using Zope 3's
testrunner directly (but it may require a bit more un-majikifying of the
Products namespace first).

Martin
-- 
View this message in context: 
http://www.nabble.com/Tools-as-local-utilities-tf2245411.html#a8843224
Sent from the Zope - CMF list2 mailing list archive at Nabble.com.

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Tools as local utilities

2007-02-06 Thread Martin Aspeli

Jens Vagelpohl wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


On 7 Feb 2007, at 00:36, Martin Aspeli wrote:
Eggs make your life easier, especially if you want to use tools  
like workingenv.py or zc.buildout.


Well, for simple work with the CMF like setting up a quick instance  
for hacking and development *I do not want to use any tools*. I want  
to retain the same ease I currently have where all I need to do is  
either copy or link a few directories into the instance Products  
folder. It's intuitive and very fast for a Zope 2 developer. If you  
can offer the same ease and speed with a different approach, fine.  
But I don't see it with those wondrous tools.


For Plone 3 development, we have two solutions (depending on which one 
you prefer). I'll explain them briefly to give you a flavour of how they 
may work.


The first is called ploneout, and is a zc.buildout. We had to create a 
couple of recipes to play nice with Zope 2, but these would work fine 
with CMF. Basically, all ploneout is, is a particular buildout.cfg that 
references Plone's eggs and products via svn:externals, in development 
mode (as opposed to as dependencies). This also downloads builds Zope 
2.10 and all other dependencies, in a single command (though if you want 
to point to an existing Zope install to save space, you can).


 $ svn co https://svn.plone.org/svn/plone/ploneout/trunk plone3
 $ cd plone3
 $ python boostrap.py # only needed once
 $ bin/buildout # needed each time you change buildout.cfg
 $ bin/instance fg # start zope

What's nice is that we can point new developers at this and they have a 
fully replicable environment for proper development on Plone 3 itself. 
The plone eggs are in src/ and products in products/, via svn:externals, 
so you can work on them and then commit changes.


If you were using this for your own project and you wanted to Plone, CMF 
and all the eggs only as a dependency, maybe with your own eggs and 
products in development mode, you can create a buildout.cfg by answering 
a couple of questions (or accepting the defaults) from paster.


 $ easy_install ZopeSkel # gets Zope/Plone templates for paster
 $ paster create -t plone3_buildout  myproject
 $ cd myproject
 $ python bootstrap.py
 $ bin/buildout

The buildout.cfg file contains a list of the eggs you want, and you tend 
to put development eggs for your project in src/ and reference them in 
buildout.cfg.


Daniel Nouri has a slightly different approach, using workingenv.py. 
Whereas buildout.cfg is a single-file configuration for the eggs, 
downloads and other build steps you want in your environment, his 
ploneenv approach creates a more traditional Zope instance. It's more 
for projects using Plone as dependency again, because it basically 
installs the Plone egg, which in turn keeps track of all the various 
eggs we have as dependencies and all the products. There could be a CMF 
meta-egg that'd work similarly.


 $ easy_install ploneenv
 $ ploneenv -m /path/to/zope/utilities/mkzopeinstance.py myproject
 $ bin/zopectl fg # as usual

The workingenv approach lets you install eggs into it, not interfering 
with global site-packages, using the local bin/easy_install. If you 
prefer, you can source bin/activate and it'll set your PATH and 
PYTHONPATH as necessary so that your shell is always in the local 
environment. decativate (or quitting your shell) turns that off again.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: Tools as local utilities

2007-02-06 Thread Martin Aspeli

Charlie Clark wrote:

Am 07.02.2007 um 00:36 schrieb Martin Aspeli:

Why? Is it the ability to specify sensible version restrictions?  
Have multiple versions of the same package as different  
dependencies for different dependents? Automatic downloading of  
dependencies where possible/desired? Standardised package metadata?  
Standardised location to find and search for add-on libraries?


You mean the existing approach didn't support this? Ever heard of  
sys.path?


Sure, I mean, that's all they do, manage sys.path for you. But it's way 
easier to be more declarative about your dependencies and their 
versions, and having automatic downloads of dependencies (even indirect 
ones) can save a lot of time and make it easier to try things out.


Sorry, I don't want to waste bandwidth on the CMF list on a  
flame war. Eggs are there and I will have to learn to live with them  
but I don't have to like them.


I'm not quite sure it's wasted bandwidth in the sense that I believe 
moving to distribution using eggs could benefit CMF and its dependents 
greatly. This pressure is coming from both sides: Zope (3) and Plone. 
I'm pretty sure the Silva guys are fairly enthusiastic about eggs, too.


I know what's driving it and I know  it's unfortunately almost  
unavoidable but I don't have to like it.  I've never had a problem  
with using Products especially since the  introduction of local  
Products with Zope 2.7.
Meanwhile, the rest of the Python world came up with something  
better and more widely accepted. Until Zope 2.10 and Plone 3, the  
whole Plone and CMF stack depended on no library that was re-usable  
outside of Zope (apart from PIL, and unless you count parts of Zope  
3 shipped with Zope 2.8+). Eggs make your life easier, especially  
if you want to use tools like workingenv.py or zc.buildout.


This is guff. Why should Zope add-ons *necessarily* be available as  
third-party libraries? But if this is required it's no big deal to  
put the Zope specific stuff in a Products folder and the library  
in ../lib/python. Works fine for mxODBC


Managing lib/python manually is quite painful. For example, we have a 
lot of things we want to keep in the plone.* namespace. These are 
developed by different people. When people had to symlink things in 
(before we got eggs) or we were building bundles, merging multiple 
packagings of libraries into lib/python/plone/ and lib/python/plone/app 
became difficult, time-consuming and really, really hard to explain to 
newbies.


Mostly, I'm basing this on empirical evidence, though. In the latter 
part of the Plone 3 development cycle, we started pushing eggs pretty 
hard. We got familiar with tools like paster, setuptools and 
easy_install which help make this fairly painless. Before Plone 3, we 
made no use of external, non-Zope specific libraries (apart from PIL); 
to be honest, we hardly even looked for them, because of the 
distribution headache (Plone at that point was a tarball for Products/). 
Now, we've got half a dozen or so packages that other people (primarily 
Zope 3 people for now, but as Zope 3 becomes eggified as well it gets 
easier to re-use things outside Zope entirely) can use (grok is playing 
with our AJAX infrastructure, for example). We also know that we can 
find, try and ultimately declare dependencies for packages quite easily.


I don't think eggs/setuptools are perfect. But I don't think they're 
useless either, and on the whole, so far, they've brought more benefits 
than problems. By playing with eggs, we're playing better with the rest 
of the Python community (and things like entry points are very cool). We 
start being able to re-use some of their tools (workingenv, buildout, 
paster) and participate more meaningfully by sharing code.


In any case, I don't mean this to be acrimonious in any way. I'm justing 
saying that depending on a non-Products package (be it egg-distributed 
or not) shouldn't be a problem (because there will only be more and more 
of these).


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-09 Thread Martin Aspeli

Dieter Maurer wrote:


 - It's an explicit declaration of support


As is the definition of __of__.


Well, not in a formal sense. I could have some non-Zope python object 
that I wanted to register as a local utility (to override a global one, 
say) that could have __of__() for some other reason.


IAcquirer is an explicit, formalised statement of support for some 
particular behaviour.


I doubt it matters in this case (I'd guess __of__() is not a very common 
method name outside Zope, and this would be pretty localised code), but 
in general, having code be conditional on hasattr() something can lead 
to spaghetti code and unintended side effects.




 - It may not be desirable to wrap everything that *could* be wrapped.


Could you explain?

In the Zope 2 world, non acquisition wrapped objects behave very strange
(as indicated in an earlier message).
Do you want to introduce special cases only that you can use Zope 3 magic?


It's pretty pointless to argue aesthetics, but I wanted to point out 
what was the more accepted Zope 3 pattern (in my understanding and 
opinion), i.e. relying on a formalised definition of some behaviour 
rather than the implication that if something has a particular method it 
must be what you think it is and must want a particular type of behaviour.


What if the method wasn't __of__() but get_size() or something in a 
different context?


Also, I think it's perfectly reasonable that some local utilities, even 
in a Zope 2 context, will not be acquisition wrapped. They may just be 
local overrides of global ones, for instance, or local utilities to gain 
persistence, but not for any other reason.


Of course, if you want things to behave in a Zope 2 like way 
(containment by acquisition, security by acquisition, role manager 
behaviour, whatever else) then you also want to aq wrapped in a Zope 2 
like way.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-09 Thread Martin Aspeli

Tres Seaver wrote:


Or, to paraphrase the Beatles:  All you need is __of__ ... DAH dah,
dadda dum...  __of__ is all you need.


LOL! :)

Knock yourselves out, I don't feel as strongly about this as I like a 
good argument. ;)


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-07 Thread Martin Aspeli

Jens Vagelpohl wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


On 6 Jan 2007, at 23:03, Martin Aspeli wrote:
In light of what we're seeing here, and because there is *so* much  
third party code using getToolByName(), perhaps a  
DeprecationWarning (and worse, speedy deprecation) is a bit  
premature? I don't think we can get rid of getToolByName() for a  
long time, practically, but new code should be encouraged from  
using the new utility based lookup.


I'm getting a bit annoyed that things already decided back in  
September are now being questioned. Please go back and read the  
thread Tools as local utilities, which you started, coincidentally.  
I have spent days and days going down this route. This is a very  
large piece of work and I took it over voluntarily because everyone  
thought it was a good idea.


I'm sorry if I caused offense; I am very, very happy that you decided 
this was worth your time, and I think it will be a very important 
stepping stone in making CMF 2.1+ better and easier to integrate with.


I didn't realise we would fully deprecate getToolByName() quite yet, 
though. I must admit I haven't been following your checkins, for lack of 
time (and since you're surely more qualified than me in this work in any 
case).


However, surely, if we agree that it's premature to do so, commenting 
out the line that sends a DeprecationWarning won't be much of a change?


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-07 Thread Martin Aspeli

Hi Jens,

A warning is a warning is a warning, there's no lower level, and  
people won't see anything if it isn't in their faces. The usage of  
something like a debug error message is unprecedented,  
counterintuitive and will not compel anyone to fix their product. We  
finally have a _workable_ deprecation policy with accepted ways to  
signal deprecation and accepted deprecation periods, I'm against  
creating special precedents for no other reason other than to give  
anyone, be it Plone users or third party coders or anyone else, a  
_false_ sense of security.


We do have precedent in Zope 3 as well as Plone where deprecation 
periods were extended because the breakage was unrealistic.


A warning is of course one thing. If getToolByName() is gone entirely in 
a year (I don't know if that was your intention or not) it's pretty 
scary. Surely, some things deserve longer deprecation periods than 
others, and getToolByName() is used in pretty much every third party 
product (certainly every one I've written).


The task isn't rocket science, it's just dull work. I know that  
because I've spent a long time doing it on that branch. Besides, a  
deprecation warning will only show up once for every specific call if  
I remember correctly.


That's good - I was going to suggest something like that. :)

Keep in mind that the only tools which will cause the  
DeprecationWarning to show are those defined in the CMF package. No  
third-party portal_foobar tool would cause it.


Right.

If you consider the relatively glacial speed of CMF releases you'll  
see there's nothing quick when the normal policy of removal two  
releases down the line is applied. The earliest time getToolByName  
could possible go away would be 2.3, and I strongly doubt it will  
happen then. We will warn people that it *might* happen, though.


Cool.

I do appreciate your desire to be conservative, but it's a bit hard  
to understand when I hear so many voices from the upper echelon of  
Plone developers wanting to completely revamp (for very good reasons)  
large parts of it.


I completely agree that this is the right direction and I will certainly 
want to use this in my own code and promote it as widely as possible.


I guess I'm a bit wary by some of the experience from Zope 3 (or Zope 2) 
where for a time the desire to tidy got a bit strong and things were 
removed because the policy said so, but which caused a lot of breakage 
that wasn't really necessary.


So long as tools remain and remain in content space, getToolByName() can 
continue to exist and work (and warn, I guess); it's only a couple of 
lines of code, even. The deprecation serves a purpose in terms of 
allowing better local overrides and allowing us to eventually move the 
tools out of content space. It also helps avoid a dependency on CMFCore 
where products were only importing getToolByName() to use tools.


I would argue that removing it wouldn't be better than keeping it in 
(with a warning), practically speaking, until tools are removed from 
content space, say.


Once again, I think we agree on direction, perhaps disagreeing on speed.

Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-07 Thread Martin Aspeli

Hanno Schlichting wrote:


Maybe a compromise would be to only return those utilities back
acquisition wrapped that where registered as tools?


That sounds sensible to me; most new local utilities wouldn't really 
behave the same way, I'm guessing.



Jens added a new function to CMFCore.utils called registerToolInterface
that registers a tools name and the interface that tool implements in a
global registry (a simple module level dict). The primary purpose is to
let getToolByName look up known tools by interface instead of using
Acquisition.


Nice.


While I'm not too proud of my persistent component registry proposed
earlier in this thread it could be extended easily to only return those
utilities back AQ-wrapped that are registered in the global tools registry.

See my attached aq-components.py file for a sample implementation.

Personally I think AQ-wrapping every utility is a bit too much as well.
I've written a number of new utilities for Plone 3.0 that while having
some persistent configuration don't need any Acquisition context.
Magically wrapping those might indeed lead to unexpected behavior.


That is my worry too. Worse, if people start *depending* on that aq 
wrapping, we are going two steps forward and one step back. :)


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-06 Thread Martin Aspeli

Hanno Schlichting wrote:


Yep, you are wrong ;)


Fair enough. Out of curiosity, does the object have a __parent__?

In any case, I think your original suggestion is a good one. Let's take 
this opportunity to diagnose the problem and not the symptom: True 
tools should be singletons and act much like utilities. Stuff like 
self.REQUEST is pretty nasty. Maybe some tools will need some internal 
cleanup in that respect; my feeling is that in most cases, that cleanup 
should be reasonably easy, and where it's not perhaps we wait to put 
those methods into the corresponding utility interfaces and think about 
using adapters instead.


As Tres points out, you need aq context for security and in case 
something is contained in the tool and needs proper containment 
acquisition. portal_factory is such an example. I don't know if 
portal_actions would be now as well; portal_types probably too.


These are not really utilities, though, they are magic singleton 
containers for specific things. Whereas a tool that is converted to a 
utility may one day be deprecated out of content space, these ones may 
not, I don't know.


Also, getToolByName remains and is almost certainly the way forward for 
all TTW code still, because it lets us aq wrap, it removes the need to 
make all interfaces importable in untrusted code, and it can do any 
additional security related things. In filesystem code, though, I think 
the security aspect won't matter in most cases.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-06 Thread Martin Aspeli

Hanno Schlichting wrote:


PhiliKON some time ago suggested that Five should wrap the utilities
eventually but nobody followed up on that idea. 


Philipp also has some ideas (not too far off completion, I believe) that 
may remove some of the acquisition intermingling. I'm not sure they'd 
apply here.



Personally I have no
clue how Acquisition and security are intermingled in Zope 2, so cannot
suggest any reasonable behavior here.


Spend some time in AccessControl/ImplPython.py. :)


Ah yep, you are of course right. My main point was probably that it
shouldn't rely on the request (unless passed in explicitly as a method
argument).


And sometimes we have methods that can legitimately take a 'context' 
parameter. Quite often, this is because we were really after a view, 
though. For example, most of PloneTool.py is a hodge-podge of random 
things that were needed in page templates and Script (Python)'s but that 
people wanted in filesystem code.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-06 Thread Martin Aspeli

Hanno Schlichting wrote:


The idea is to use a specialized persistent component registry, that
does the needed AQ-wrapping.

This will however only give us AQ-wrapped local utilities, whereas those
registered with the global component registry wouldn't be wrapped. I
think this might be an acceptable trade-off.


Are you sure? Does *every* local utility want an aq wrapper?

I'm not even sure if tools that are well-written (do not rely on 
acquiring things from 'self') need to do so except for security when 
called TTW, in which case getToolBy(Interface)Name will do the trick.


Bluntly adding acquisition like this seems like a step in the wrong 
direction, imho.


If we *know* that *every* local utility needs this, then it's a pretty 
elegant solution. I would like some assurances from Tres, Philipp or 
others for that, though.


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


[Zope-CMF] Re: [CMF 2.1] FSPageTemplate Unicode

2007-01-06 Thread Martin Aspeli
Okay, spoke to Philipp on IRC and he asked me to relay his opinions on 
some of this:


 - CMF tools ought not to depend on acquiring things from 'self' if at 
all possible.


 - TTW code will need aq contexts for security. However, it makes sense 
for getToolBy(Interface)Name() to handle this.


 - Non-TTW code probably shouldn't need aq contexts.

 - Registering the portal as a utility that can be obtained by 
getUtility(IPortalRoot) is pretty good practice; in my estimation, that 
should solve all the use cases for utilities where acquisition is used 
now and where we're not really after an adapter, view.


 - Using component registries would be bad in terms of maintenance; in 
my own opinion, aq-wrapping when it may not be needed may lead to 
headaches later as well.


Also, in my own opinion, why don't we keep getToolByName() (since it's 
so incredibly prevalent) and just let it handle dotted interface names 
as well? The chances of a name clash are minute, and we can at a later 
stage deprecate the non-dotted names. I say this because (a) 
getToolByInterfaceName() is long :) and (b) it's one more thing to 
remember and (c) everyone's already using getToolByName().


Martin

___
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests


  1   2   >