Jeff Shell wrote:
On 1/20/06, Shane Hathaway <[EMAIL PROTECTED]> wrote:
Chris Withers wrote:
FWIW, I still hate ZCML for the following reasons:
Everyone seems to agree on the direction suggested here:
I think that will resolve a lot of concerns.
But I'm really starting to get frustrated with a lot of the elements
in the ZCML browser: namespace. They do a lot behind the scenes and
maybe that's a good thing for new users to minimize the amount of code
they have to write or provide, but it gets frustrating (at least, it
has for me) when you start growing up beyond that.
To a large extent, they were failed experiments. Just stop using them.
Maybe the big base-class-mess of Zope 2 made it desirable to not even
require a base class for a Zope 3 view?
No, that was not the motivation.
> Some of those viewmeta
directives are doing a lot of crazy dynamic class and method creation
to provide IBrowserPublish, traversal to the default view, or
rendering a certain attribute or template automatically as the
default. As I was starting to use Zope 3 in earnest, I wouldn't
understand when I should use browser:page versus browser:view, and if
I did browser:page with both a template and a class if there was any
way I could refer to the template from the class's methods since the
template was stitched in by ZCML.
The management of templates was the reason we had to go down this road.
Some influential early Zope 3 reviewers (who will remain nameless to
protect their reputations :) complained that they didn't like to muck
up their Python code with template definitions. They didn't like
seeing things like:
foo = ViwPageTemplateFile("foo.pt")
in their Python code and prefered to relegate those definitions to
ZCML. This was the origin of the page directives. In retrospect,
it was a mistake.
The fact that we have both view and page had to do with an early
concept, multi-page-views that also hasn't terned out to remain useful.
Again, I'd be happy to see these directives fade from use.
Even though I've made a pro-ZCML case on the basis that most of the
directives and their attributes are reasonably well documented, what
the directives DO is another matter entirely. In theory, registering a
view is equivalent to zope.component.provideAdapter((ISomeObj,
ISomeSkinLayerOrRequest), provides, name). But the directives do so
much more than that. So while I'm often trying to stick with apidoc
for reference, I'm always going into Zope to see how things really
work and usually to ensure that I'm really doing things correctly. And
looking at some of the metaconfigure code is... Well, it's rough.
There's something defined in zope.app.publisher.browser.menumeta for
menuitems called 'extra'. I've been struggling to find out if I can
handlers. And I mean s-t-r-u-g-g-l-i-n-g. I finally find this 'extra'
thing. It's not defined in any schema interface. What is it? What form
does it take? It's in the argument list in the directive handlers, but
not in the metadirective's schema. Should I write my own menu system?
This is a very good example.
I like being able to declare menus in ZCML - keeps their order easy to
don't want to be writing new directives. I've been crawling through
this code all morning. It's very convenient until you can't do what
you want... So then the issue becomes "should I just do it in Python?
Is there a way I can do it but still have it all work out nicely at
I think so.
> I'm guessing there is if I write a custom
IBrowserMenu utility and write my own way of providing menus to it..."
Menus are an idea that, like the rest of the component architecture, has evolved
and simplified over time.
Menus are best understoood as a pattern!
The pattern goes like this: A menu us just a collection of
named components that provide some interface. The menu is the
menu item type. To define a new menu, define a new type.
To make the menu items context sensitive, look up the menu
items as adapters. (Well, you typically do that anyway, since
menu items generally adapt at least the request.) How you
display or order the items is up to you.
That's it. Simple. For our applications, we often create
mini menu frameworks to meet specialized needs. The existing
menu interfaces, including the ZCML directives implement this
simple pattern. Sadly, things designed to make things simpler
often take simple ideas and make them complex. :) The original
menu framework didn't implement this pattern, but was retrofitted
to do so.
If you want to define menus or menu items in Python, go ahead.
Just define interfaces and adapters and register the adapters
I like the approach taken in zope.formlib, which puts more trust in
the Python code and provides good but also simple / shallow base
classes (which aren't required, they just provide a lot of the common
functionality). Trying to do some custom forms with
zope.app.form.browser's forms in Zope 3.1 was challenging. Doable, but
challenging, especially as zope.app.form.browser's forms really wanted
to be built by ZCML. It's still very nice in theory from the "naked
objects" "scaffolding" "auto-admin" perspective: build add forms and
editforms automatically in 6 lines of ZCML! No programming required!
But the difficult step always comes when it's time to do just a bit of
programming from that, and then a bit more, and then a bit more. And
then you might think you provided a new custom form base class you can
use all over the place and get its template, only to find that ZCML
wrote over it for the subclass.
So I was happy to see zope.formlib, and to not see any meta.zcml
anywhere in that package.
Yup. BTW, did you notice formlib/page.txt?
... Lots of interesting stuff snipped
I really think that the core of the Zope 3 component architecture is
beautiful. I had that zen moment recently where I went "oh, it's all
adapters, utilities, and multi-adapters!"
We had that same zen moment a few months before 3.0. :)
> When I stay the closest to
it - writing code that uses adapters to turn a list of schema fields
into something nice for file system representation and back - I'm
really happy with Zope 3. When I'm writing core content classes and
basic adapters (INameChooser, ISearchableText, IReadFile/IWriteFile)
and it all just works, I'm happy. Even when I'm using ZCML to register
classes, security, adapters, and some extra marker interfaces, I'm
pretty happy (but it does start to tear at me - "how much or how
little should I declare here?").
But these days, when I'm working in my browser/configure.zcml type
files, I get real grumpy, real quick. That's become the part where I
kindof close my eyes and hope I get everything right.
OK, so you know the way to proceed. :)
Zope 3 should dominate not only quick'n'clean,
I'll note in passing that we won't be quick enough until we
provide an alternative to the "object file system" and make people
understand that, while it is often useful, it isn't necessary and
can make things harder. Many people have figured out how to use
Zope without the ofs, but there isn't an easy out of the box easy
way for people to do it. My Bobo project was aimed at that,
but, sadly, I haven't had time to pursue it.
quick'n'clean'n'grown-up - an architecture that's closer to the scope
of a J2EE type system, that brings a lot of powerful concepts into
Python without a lot of complexity and without being cavalier with the
language, can handle complexity as well as simplicity, and is governed
by a few basic principals that we believe give plenty of benefits.
Interfaces/Schema combined with a few helper functions empower design
by contract without being restrictive or unpythonic, and that contract
alone can be used for so many things: web form generation and
validation; SQL generation, validation, and import; XML import/export;
documentation; RPC formatting; and of course - adaptation (duck typing
And I think that unless ZCML is simplified and starts doing less
automation as promoted by Phillip, that message will be lost.
Fortunately, this trend is underway. I think your articulate
essays are helping a lot!
> Again -
I like what zope.formlib offers, and I like the IFormAPI interface and
concept. I'd like to see more of a move in that direction for the core
facilities. Instead of "write these n lines of ZCML to auto-generate
an edit form for a schema/interface", it should be "write these 5
lines of Python to generate that form, and 1-2 lines of ZCML to
register it, name it, and protect it." And then, as the user may need
to customize the form, they can add to this class instead of having to
span the two worlds of ZCML automation and Python. It's much easier to
go up a good and simple base class tree and read / understand the code
than it is to go through ZCML meta configurations. And it makes the
distance between the main doctest documentation and how things work a
Perhaps we should start actively deprecating many ZCML directives?
This will require some volunteer effort to do it well.
Jim Fulton mailto:[EMAIL PROTECTED] Python Powered!
CTO (540) 361-1714 http://www.python.org
Zope Corporation http://www.zope.com http://www.zope.org
Zope3-dev mailing list