AW: AW: [Zope3-dev] Re: AW: Re: edit view of a object unknown?

Roger ineichen dev at projekt01.ch
Sun Mar 7 07:41:52 EST 2004


Jim Fulton wrote:
> Roger ineichen wrote:
> >>jim wrote:
> >>
> >>>Jim, if you're lurking :-) could you fill in some of the
> >>
> >>pieces here?
> >>
> >>>We
> >>>had briefly covered some of the factory/initialization issues
> >>>surrounding the add form, but I've already forgotten the 
> details :-o
> >>
> >>I don't think they are relevent.
> >>
> >>Roger, I can't really tell what you want to do.  It seems as
> >>though you want to be able to create objects from Python 
> >>without knowing anything about their constructors.  This 
> >>really only works, in general if the constructors take no arguments.
> > 
> > 
> > Yes. But if somebody write a product this implementation is like a 
> > chief implementation and other write just a second implementation, 
> > because they don't whant to use the original. And in this way they 
> > have to relay on the contructors of them.
> 
> Sure, and they need to know how to call these constructors.
> 
> ...
> 
> >>Roger, could you explain what you are trying to do?
> > 
> > 
> > I try:
> > First I describe a uscase:
> > Let's say we whant use the Object(fields) for to store a class 
> > instance as a child of a content class. This child is also 
> a content 
> > class. Both classes have add and edit views. Let's call 
> they question 
> > and priority class.
> > 
> > example:
> > class IQuestion
> > ----
> > class IQuestion(Interface):
> >     """aDoc.."""
> >     
> >     priorities = Tuple(title=_(u'...'),
> >         value_type=Object(IPriority, title=u'...'))
> > ---
> > 
> > class Question
> > ---
> > class Question(Persistent, object):
> >     """aDoc.."""
> >     priorities = property(get_priorities, set_priorities, 
> None, 'list 
> > of
> > priorities') 
> > ---
> > 
> > class QuestionEditView
> > ---
> > priority_w = CustomWidgetFactory(ObjectWidget, Priority)
> > priorities_w = CustomWidgetFactory(SequenceWidget, 
> subwidget=priority_w)
> > 
> > class QuestionEditView(EditView):
> >     __used_for__ = IQuestion
> > 
> >     priorities_widget = priorities_w
> > ---
> > 
> > 
> > In this case we can't add a question in a python method, because we 
> > don't know which class is used for to add in the property 
> priorities 
> > as the value_type. In the example above declared with the interface 
> > IPriority.
> 
> You can add a question if you have an IPriority 
> implementation, The schema doesn't tell you what that is. 
> There is probably one stiiting around in the product that 
> provided wuestions, or you can write one.
> 
> > Let's do a little bit more and write a import/export
> > tool which is importing Questions to the Zope3 server
> > from a xml file. That's not possible with this information. 
> 
> Right, you need some sort of XML schema.
> 
> > You have to hard code Priority class in the import/export
> > tool.
> 
> Or you can make the tool pluggable, but, at some point,
> someone has to decide on a class, just like someone
> has to decide on a class when the define an add or edit
> form.
> 
> 
>  > Here we should call Zope and ask which content object
> > implements IPriority. But this could be more then one
> > implementation on this server. ???
> 
> Yes
> 
> > I think, this system configuration logic which should be defined in 
> > zcml.
> 
> It depends on the application, I suppose. We haven't needed 
> this so far.
> 
> You could define a factory that produces IPriority objects. 
> Your import code would then have to scan the registered 
> factories looking for one that produced the objects you want.
> 
> I can imagine some XML/Python conversion framework that could 
> require specialized registries for mapping xml node types to 
> Python objects.  You could certainly invent such a registry 
> and provide new ZCML directives for it.
> 
> > For me it's not a problem to implement and import the right 
> Priority 
> > class if I whould add a Question in a python method. But I whould 
> > write more general products and let other people decide if 
> the whould 
> > implement another Priority class. We declare just the interface of 
> > IPriority and implement a sample Priotity class.
> 
> Yes, so they implement a different priority class and used 
> it. What's the big deal?
> 
> 
> > I think if we don't solve this
> 
> I still don't know what "this" is. People can always provide 
> alternate implementations for classes.
> 
>  > we whant see many good
> > content objects/classes developed by other developer,
> > but they will have realy hardcoded relation to other
> > content classes if the use Object(fields).
> 
> No, object fields specify interface requirements. You can 
> supply any class you want as long as it satisfies the interface.
> 
>  > At least we
> > have to write new edit views with the own CustomWidgetFactory.
> 
> If you want to use a different class, yes.
> 
> > And also they have to implement a own import/export tool for
> > to create the right Priority class in the Question object.
> 
> I assume you are refering to XML import/export.  If there was 
> such an application, it would likely have to provide some 
> mapping between XML schema definitions and Python objects.  
> Certainly, Zope schemas would not be enough, you'd need 
> additional information. You might very well want a custom 
> registry for that purpose.
> 
> 
> 
> 
> > I'm shure if the scripters come to zope we get a lot of 
> nice products 
> > and the widget framework is really powerfull. They will do creazy 
> > things with different content classes in a custom widget or 
> in widget 
> > wizzards. But you don't have access to this information from python 
> > methods.
> 
> You are right. You won't. <shrug />
> 
> > A solution could be;
> 
> I still don't see a problem.
> 
> > ----------------
> > Define a interface
> > Define a class implementation
> > Define a edit and add factory
> > Define add/edit views (which use the add or edit factory)
> > ----------------
> > The add and view factories should be accessible from python
> > and TTW views. This way you can add or edit the object on each 
> > different implemenetation in a general way.
> 
> What is an "add and edit" factory? What would it mean?
> 
> In your example, would this be a factory for filling in the 
> question priority field? Or would it be a factory just for 
> creating priorities, to be used whenevery an IPriority is 
> expected?  What would you do if more than one factory could 
> be used to create IPriorities? Would you disallow that? Pick 
> the first one you find?

This is the point:
Right, it's possible to have more then one IPriotity implementation
on a server. And I don't whant to pick just the first one.

I don't find a example with a Object(field) at this moment, but
it's not just a problem of the Object(field). We always
don't know which object is used for if we declare on Interfaces.

A example of exactly this problem (declare on Interface) you can 
find in the workflow package in zope.app.workflow,
they use a import/export handler (ImportExportUtility) and create 
ProcessDefinitions. It's not possible to have more then one 
ProcessDefinitions on one server, except you don't know
which ProssessDefinition is used in the import/export utility
the wrote in zope.app.workflow.ImportExportUtility.
---
<utility
    component=".globalimportexport.globalImportExport" 
    provides="zope.app.interfaces.workflow.IProcessDefinitionImportExport"
    permission="zope.workflow.ManageProcessDefinitions" 
    />
---
In the ImportExprotUtility class you see the lines 46-52:
---
for iface, factory in self._importers.getRegisteredMatching():
    if iface.extends(IProcessDefinition):
        imp = factory()
        data.seek(0)
        if imp.canImport(context, data):
            data.seek(0)
            return imp.doImport(context, data)
---
This starts a for: and if the found the first implementation of
IProcessDefinition they return the first one.

Exactly here should we call a factory how gets the right implementation
of the IProcessDefinition.

It whould be nice to have a directive like.
---
<customObjects
    for="zope.app.interfaces.workflow.IGlobalProcessDefinitionImportExport"
    object="zope.app.interfaces.workflow.IProcessDefinition" 
    uses="zope.app.interfaces.workflow.ProcessDefinition"
    />
---
And I whould be happy if I can register:
---
<customObjects
    for="zope.app.interfaces.workflow.IGlobalProcessDefinitionImportExport"
    interface="zope.app.interfaces.workflow.IProcessDefinition" 
    object="mypackage.workflow.MyProcessDefinition"
    />
---
These means that we can call in the ImportExportUtility somthing like
for iface, factory in
zapi.getRegistredObjectsFor(IGlobalProcessDefinitionImportExport):
    if iface.extends(IProcessDefinition):
        imp = factory()
        data.seek(0)
        if imp.canImport(context, data):
            data.seek(0)
            return imp.doImport(context, data)
---
zapi.getRegistredObjectsFor(AInterface) whould give back all registred 
Objects for (AInterface). In the example above we get back just one Object 
(ProcessDefinition or MyProcessDefinition). In other classes we could
have:
---
<customObjects
    for="basic.IPerson">
    <customObject
       interface="basics.IAddress" 
       object="basics.Address"
       />
    <customObject
       interface="basics.IDeliveryAdress" 
       object="custom.MyDeliveryAddress"
       />
</customObjects>
--- 

Generaly I can say, if you declare a class or a factory on a Interface
it's sometimes not enough. We need additional information
which Implementation should be used. (If we have more then one
on a server) At least we run in this problem if scripters
setup servers and download different products. They don't
know how many classes implement a Interface. And we will
get a lot of troubles with this setups.
The example above with the workflow works very well until
a product is installed with a class which is implementing
(IProcessDefinition), exactly at this time you can't say which 
class is used. (it's the first class we get form the method
getRegisteredMatching()).

Declaring on Interfaces means for me, great flexibility.
But we loose this felxibility in the implementation.
And run into problems if the scripters setup servers 
and not exactly know what they do. In my option if we have 
to declare the (customObjects) we can anybody tell
which calss will be added if they run a method like
the (importProcessDefinition) method in the (ImportExportUtility)
because they have to declare it  in ZCML.

I don't hoppe that's a YAGNI. Otherwise sorry about the long mail
and my crazy wishes. But my wish is; if we use such a complex
mechanism like ZCML we should be able to support this (layer)
very well, otherwise we jump all the time between python class
coding and ZCML arround.

> Jim
> 
> -- 
> Jim Fulton           mailto:jim at zope.com       Python Powered!
> CTO                  (540) 361-1714            http://www.python.org
> Zope Corporation     http://www.zope.com       http://www.zope.org
> 
> 
> _______________________________________________
> Zope3-dev mailing list
> Zope3-dev at zope.org http://mail.zope.org/mailman/listinfo/zope3-dev
> 




More information about the Zope3-dev mailing list