[Zope3-dev] alternate format for configuration files
Jeremy Hylton
jeremy@zope.com
Fri, 22 Mar 2002 14:49:58 -0500
I've been noodling with a different way to write Zope3 configuration
files, and I'd like to get some feedback.
We had a Sprint this week were PythonLabs & friends spent some time
writing a simple product. It was the first time I really looked at
the .zcml files and tried to understand what they do. I found a few
things difficult:
- There is a lot repetition in zcml. I often type the same name
over and over again. Fred showed me how to use an XML entity
reference (a macro) but that doesn't seem like a good solution.
- The names of tags don't have obvious meanings.
- There is no structure to the configurations. It's just a
sequence of directives at the same level and in an arbitrary
order. We found that we had many duplicate entries in different
files, because there was no obvious place to put some things.
- I think that the use of attributes makes for a lot of extra
punctuation that is hard on the eyes. This, of course, is a
very subjective thing.
I find that EJB deployment descriptors, which are also based on XML.
I like these descriptors better because they are organized
hierarchically. All the directives pertaining to a particular entity
bean are contained within the entity bean's top-level tag.
The use of hierarchy means that redundant typing is avoided and that
the names can be simpler and easier to understand.
I've also made the simplifying assumption that a Python dotted path
name is relative to ZopeProducts when it's used inside a Product
directive.
I've included two files below. The first is my proposed new syntax.
It's a rough cut. I probably have the hierarchy wrong and I may not
being doing the XML right. The second is the existing zcml it's based
on.
Any comments? Is it worth pursuing this approach?
Jeremy
<Zope>
<Product>
<Name>JobBoard</Name>
<Description>
A JobBoard is a moderated collection of job postings.
</Description>
<Interface>
<Class>JobBoardEx.IJobList</Class>
<View>
<Type>Browser</Type>
<Name>traverse</Name>
<Factory>JobBoardEx.JobList.JobListTraverse</Factory>
</View>
<View>
<Type>Browser</Type>
<Default/>
<Name>summary</Name>
<Factory>JobBoardEx.JobList.JobListTraverse</Factory>
<Protect>
<Permission>Zope.Public</Permission>
<Methods>index, getApprovedJobs</Methods>
</Protect>
</View>
<View>
<Type>Browser</Type>
<Name>NewJob</Name>
<Factory>JobBoardEx.NewJob.NewJob</Factory>
<Protect>
<Permission>Zope.View</Permission>
<Methods>index, preview, waiting, getJobView, cancel,
home, submit</Methods>
</Protect>
</View>
<View>
<Type>Browser</Type>
<Name>ApproveJobs</Name>
<Factory>JobBoardEx.ApproveJobs.ApproveJobs</Factory>
<Protect>
<Permission>Zope.View</Permission>
<Methods>index, cancel, submit</Methods>
</Protect>
</View>
</Interface>
<Content>
<Name>JobList</Name>
<Class>JobBoardEx.JobList.JobList</Class>
<ZMI-Factory>
<Permission>Zope.Public</Permission>
</ZMI-Factory>
<Protect>
<Permission>Zope.Public</Permission>
<Methods>query</Methods>
</Protect>
</Content>
<Content>
<Name>Job</Name>
<Class>JobBoardEx.Job.Job</Class>
<Protect>
<Permission>Zope.Public</Permission>
<Methods>*</Methods>
</Protect>
<View>
<Type>Browser</Type>
<Name>JobView</Name>
<Factory>JobBoardEx.JobView.JobView</Factory>
<Protect>
<Permission>Zope.Public</Permission>
<Methods>index, simpleView, getSubmitter,
getSummary, getDescription, getContact
</Methods>
</Protect>
</View>
</Content>
</Product>
-----------------------------------------------------------------------
The actual config this is based on:
<zopeConfigure
xmlns='http://namespaces.zope.org/zope'
xmlns:zmi='http://namespaces.zope.org/zmi'
xmlns:security='http://namespaces.zope.org/security'
xmlns:browser='http://namespaces.zope.org/browser'
>
<!-- *** Content classes *** -->
<!-- JobList -->
<zmi:factoryFromClass
name=".JobBoardEx.JobList."
permission_id="Zope.Public"
title="JobList"
/>
<security:protectClass
name=".JobBoardEx.JobList."
permission_id="Zope.Public"
methods="query"
/>
<!-- Job -->
<!-- This doesn't need a factory, since jobs are always created by
Python code. -->
<security:protectClass
name=".JobBoardEx.Job."
permission_id="Zope.Public"
/>
<!-- *** Views *** -->
<!-- JobListTraverser -->
<browser:view
for=".JobBoardEx.IJobList."
name="_traverse"
factory=".JobBoardEx.JobList.JobListTraverser"
/>
<!-- JobListSummaryView -->
<browser:defaultView
for=".JobBoardEx.IJobList."
name="summary"
factory=".JobBoardEx.JobListView.JobListSummaryView"
/>
<security:protectClass
name=".JobBoardEx.JobListView.JobListSummaryView"
permission_id="Zope.Public"
methods="index, getApprovedJobs"
/>
<!-- JobView -->
<browser:view for=".JobBoardEx.IJob."
name="JobView"
factory=".JobBoardEx.JobView."
/>
<security:protectClass
name=".JobBoardEx.JobView."
permission_id="Zope.View"
methods="index, simpleView, getSubmitter, getSummary,
getDescription, getContact"
/>
<!-- *** Actions *** -->
<!-- NewJob -->
<browser:view
for=".JobBoardEx.IJobList."
name="NewJob"
factory=".JobBoardEx.NewJob."
/>
<security:protectClass
name=".JobBoardEx.NewJob."
permission_id="Zope.View"
methods="index, preview, waiting, getJobView, cancel, home, submit"
/>
<!-- ApproveJobs -->
<browser:view
for=".JobBoardEx.IJobList."
name="ApproveJobs"
factory=".JobBoardEx.ApproveJobs."
/>
<security:protectClass
name=".JobBoardEx.ApproveJobs."
permission_id="Zope.View"
methods="index, cancel, submit"
/>
</zopeConfigure>