title: How can I use zope.schema to group portal types into categories?
body: <p>I need to create a Plone configlet that delivers this kind of structure:</p>
  
  <pre><code>types = {
      'News articles': ['NewsMediaType', 'News Item'], 
      'Images': ['Image'],
      'Pages': ['Page']
  }
  </code></pre>
  
  <p>I made a prototype to show what I was thinking to have in the form:</p>
  
  <p><img src="https://i.stack.imgur.com/bqyo5.png" alt="mockup"></p>
  
  <p>So I need to group some portal_types together and let the user assign a name for this group. How can I do that? Any ideas?</p>
  
  <p>edited:</p>
  
  <p>I made a great progress with the problem, but when save the form, validation give me an error</p>
  
  <p><img src="https://i.stack.imgur.com/pbDb0.png" alt="enter image description here"></p>
  
  <pre><code>    # -*- coding: utf-8 -*-
  from plone.theme.interfaces import IDefaultPloneLayer
  
  from z3c.form import interfaces
  
  from zope import schema
  from zope.interface import Interface
  
  from plone.registry.field import PersistentField
  
  class IThemeSpecific(IDefaultPloneLayer):
      """  """
  
  class PersistentObject(PersistentField, schema.Object):
      pass
  
  class IAjaxsearchGroup(Interface):
      """Global akismet settings. This describes records stored in the
      configuration registry and obtainable via plone.registry.
      """
      group_name = schema.TextLine(title=u"Group Name",
                                    description=u"Name for the group",
                                    required=False,
                                    default=u'',)
  
      group_types = schema.List(title=u"Portal Types",
                      description=u"Portal Types to search in this group",
                      value_type =schema.Choice(
                          title=u"Portal Types",
                          vocabulary=u"plone.app.vocabularies.ReallyUserFriendlyTypes",
                          required=False,
                      ),
                      required=False,)
  
  class IAjaxsearchSettings(Interface):
      """Global akismet settings. This describes records stored in the
      configuration registry and obtainable via plone.registry.
      """
      group_info = schema.Tuple(title=u"Group Info",
                                    description=u"Informations of the group",
                                    value_type=PersistentObject(IAjaxsearchGroup, required=False),
                                    required=False,)
  </code></pre>
  
  <p>-</p>
  
  <pre><code>from plone.app.registry.browser import controlpanel
  
  from collective.ajaxsearch.interfaces.interfaces import IAjaxsearchSettings
  from collective.ajaxsearch.interfaces.interfaces import IAjaxsearchGroup
  
  from z3c.form.object import registerFactoryAdapter
  
  class AjaxsearchSettingsEditForm(controlpanel.RegistryEditForm):
  
      schema = IAjaxsearchSettings
      label = u"Ajaxsearch settings"
      description = u""""""
  
      def updateFields(self):
          super(AjaxsearchSettingsEditForm, self).updateFields()
  
  
      def updateWidgets(self):
          super(AjaxsearchSettingsEditForm, self).updateWidgets()
  
  class AjaxsearchSettingsControlPanel(controlpanel.ControlPanelFormWrapper):
      form = AjaxsearchSettingsEditForm
  </code></pre>