Forms 扩展灵活性添加表单而不扩展类型

Forms 扩展灵活性添加表单而不扩展类型,forms,plone,dexterity,Forms,Plone,Dexterity,对于自定义敏捷类型,我想在(自动生成的)add表单中添加一个复选框,询问用户是否还要创建一些关联的子元素 表单提交后,定制工厂将根据需要创建内容,删除定制字段,并让默认的敏捷工厂完成其余工作。不存储自定义字段值 我假设可以通过覆盖附加模式来扩展表单。以下是模式扩展: from zope import schema from zone.interface import alsoProvides from plone.supermodel import model from plone.autofo

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

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

我假设可以通过覆盖
附加模式
来扩展表单。以下是模式扩展:

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,)
然而,出于某种原因,在add表单上只显示字符串“None”和自定义字段,因此出现了一些问题。此外,提交时会抛出一个错误:

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

如何扩展表单?最好不要在图片中使用grok。

这里有一种方法,您可能会发现更简单一些。像往常一样声明您的模式,然后指定您的
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定义的模式来说可能更容易一些。请参阅 )

这将使
createcontent
存储在对象实例上,但您真的在乎吗


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

这里有一种方法,您可能会发现更简单一些。像往常一样声明您的模式,然后指定您的
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定义的模式来说可能更容易一些。请参阅 )

这将使
createcontent
存储在对象实例上,但您真的在乎吗

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

+1@SteveM的答案

但我刚刚有了另一个想法,更通用一些,这样你就可以在其他DX内容上重用它,而无需修改表单

  • 你必须写一个简单的行为

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

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

  • 您可以编写一个空存储,它实际上不存储任何内容

    在下面截取的代码中,我修改了plone.behavior的注释

    类NullFactoryImpl(对象):
    “”“行为的空存储”
    """
    定义初始化(自身、上下文、模式):
    通过
    def _ugetattr _;(self,name):
    一无所获
    定义设置属性(自身、名称、值):
    通过
    类NullStorage(对象):
    “”“不存储任何内容的行为适配器工厂类:-”)。
    """
    定义初始化(自):
    通过
    定义调用(自身、上下文):
    返回NullFactoryImpl(上下文)
    
  • 现在可以将行为工厂更改为

    factory="your.package.behavior.NullStorage"
    
  • 我没有测试这个解决方案,但它应该/可以工作并解决您的问题

    +1@SteveM的答案

    但我刚刚有了另一个想法,更通用一些,这样你就可以在其他DX内容上重用它,而无需修改表单

  • 你必须写一个简单的行为

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

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

  • 您可以编写一个空存储,它实际上不存储任何内容

    在下面截取的代码中,我修改了plone.behavior的注释

    类NullFactoryImpl(对象):
    “”“行为的空存储”
    """
    定义初始化(自身、上下文、模式):
    通过
    def _ugetattr _;(self,name):
    一无所获
    定义设置属性(自身、名称、值):
    通过
    类NullStorage(对象):
    “”“不存储任何内容的行为适配器工厂类:-”)。
    """
    定义初始化(自):
    通过
    定义调用(自身、上下文):
    返回NullFactoryImpl(上下文)
    
  • 现在可以将行为工厂更改为

    factory="your.package.behavior.NullStorage"
    

  • 我没有测试这个解决方案,但它应该/可以工作并解决您的问题

    通过自定义模板的某些部分(或一部分),手动将复选框添加到模板中如何?这个问题向你展示了如何操作模板你不只是做一个自定义添加表单有什么原因吗?这也是我的意思:-)是的,我希望有一个通用的解决方案,可以应用于任何灵活的内容类型。想想看,模板似乎确实是通用的。。。我会试试。通过自定义模板的某些部分(或一部分),手动将复选框添加到模板中如何?这个问题向你展示了如何操作模板你不只是做一个自定义添加表单有什么原因吗?这也是我的意思:-)是的,我希望有一个通用的解决方案,可以应用于任何灵活的内容类型。想想看,模板似乎确实是通用的。。。我会试试看。谢谢Steve,好主意-事实上,不存储字段的意义在于事后不以任何方式向用户显示它。谢谢Steve,好主意-事实上不存储字段的意义在于事后不以任何方式向用户显示它。谢谢你的想法,+1用于防止字段被存储。感谢您的想法,+1用于防止字段被存储。