扩展敏捷添加表单而不扩展类型

时间:2015-01-29 10:20:39

标签: forms plone dexterity

对于自定义敏捷类型,我想在(自动生成的)添加表单中添加一个复选框,询问用户是否还要创建一些关联的子内容。

在表单提交后,定制工厂将根据需要创建内容,删除自定义字段并让默认灵巧工厂完成其余工作。不存储自定义字段值。

我认为可以通过覆盖additionalSchemata来扩展表单。这是架构扩展:

from zope import schema
from zone.interface import alsoProvides
from plone.supermodel import model
from plone.autoform.interfaces import IFormFieldProvider 

class SchemaExtension(model.Schema):

   createcontent = schema.Bool(
      title=u'Create default content',
      default=True,
      required=False
   )

alsoProvides(SchemaExtension, IFormFieldProvider)

形式:

class ExtendedAddForm(add.DefaultAddForm):
   portal_type = 'customdexteritytype' 
   additionalSchemata = (SchemaExtension,)

然而,出于某种原因,只有字符串'无'并且自定义字段显示在添加表单上,因此出现了问题。此外,提交后,会抛出错误信息:

TypeError: ('Could not adapt', <Acquisition.ImplicitAcquisitionWrapper object at 0x83e48c0>, <SchemaClass SchemaExtension>)

如何扩展表格?最好没有图片中的grok。

2 个答案:

答案 0 :(得分:3)

这是一种您可能会觉得更容易的方法。像往常一样声明您的架构,然后指定您的createcontent字段显示在添加表单上,并在编辑表单中省略。

from plone.autoform import directives as form
from z3c.form.interfaces import IAddForm

class ISampleSchema(model.Schema):
...
    createcontent = schema.Bool(
        title=u'Create default content',
        default=True,
        required=False
    )
    form.omitted('createcontent')
    form.no_omit(IAddForm, 'createcontent')
...

(对于通过XML定义的模式,这是可能的,甚至可能更容易一些。参见 http://docs.plone.org/external/plone.app.dexterity/docs/reference/dexterity-xml.html#omitted

这会将createcontent存储在您的对象实例中,但您真的关心吗?

现在,为zope.lifecycleevent.interfaces.IObjectAddedEvent创建一个处理程序,以执行您需要执行的任何操作。

答案 1 :(得分:2)

+1 @ SteveM的回答。

但我只是有了另一个想法,更通用,所以你可以在不修改表格的情况下将其重复用于其他DX内容。

  1. 你必须写一个简单的行为。

    默认情况下,您可以在新行为的属性存储和注释存储之间进行选择。 Checkout the docs

    您的行为重新注册可能如下所示

  2. <plone:behavior
        title="title"
        description="description"
        provides=".some.Interface"
        factory="plone.behavior.AnnotationStorage"
        marker=".marker.Interface"
        />
    
    1. 而不是使用Annotation存储。

          factory="plone.behavior.AnnotationStorage"
      

      你可以写一个NullStorage,它实际上不存储任何东西。

      在以下代码中,我修改了plone.behavior的注释storage code

    2. class NullFactoryImpl(object):
          """Null storage for behaviors
          """
      
          def __init__(self, context, schema):
              pass
      
          def __getattr__(self, name):
              return None
      
          def __setattr__(self, name, value):
              pass
      
      class NullStorage(object):
          """Behavior adapter factory class for storing nothing :-).
          """
      
          def __init__(self):
              pass
      
          def __call__(self, context):
              return NullFactoryImpl(context)
      
      1. 现在您可以将行为工厂更改为..

        factory="your.package.behavior.NullStorage"
        
      2. 我没有测试过这个解决方案,但它应该/可以解决你的问题。