如何覆盖或继承z3c.form小部件?

时间:2017-01-25 13:13:22

标签: widget override plone dexterity z3c.form

我需要覆盖分配给z3c.form上的字段的窗口小部件的行为(特别是用于schema.Bool字段的窗口小部件,如下面声明的那个),以更改窗口小部件模式的工作方式在不同的条件下:

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

@provider(IFormFieldProvider)
class IGoogleNews(model.Schema):
    """Behavior interface to add some Google News features."""

    standout_journalism = schema.Bool(
        title=_(u'Standout Journalism'),
        required=False,
    )

    news_keywords = schema.Tuple(
        title=_(u'Keywords'),
        value_type=schema.TextLine(),
        required=False,
    )

1 个答案:

答案 0 :(得分:2)

这是从ftw.datepicker小部件派生的示例代码。

在widget.py中:

# This widget has a plone integration, so we take this one as base
from plone.z3cform.widget import SingleCheckBoxWidget
from z3c.form.interfaces import DISPLAY_MODE
from z3c.form.interfaces import ISingleCheckBoxWidget
from zope.interface import implementsOnly
from zope.component import adapter
from z3c.form.interfaces import IFormLayer
from z3c.form.interfaces import IFieldWidget
from z3c.form.widget import FieldWidget


class IMyBoolWidget(ISingleCheckBoxWidget):
    """Marker interface"""


class MyBoolWidget(SingleCheckBoxWidget)
    implementsOnly(IMyBoolWidget)

    display_template = ViewPageTemplateFile('templates/keyword_display.pt')
    input_template = ViewPageTemplateFile('templates/keyword_input.pt')
    hidden_template = ViewPageTemplateFile('templates/keyword_hidden.pt')
    disabled_template = ViewPageTemplateFile('templates/disabled_hidden.pt') 

    def update(self):
       super(MyBoolWidget, self).update()

    if self.disable_widget():
        # Change widget to display mode
        self.mode = 'my_own_disabled_mode'

    def disable_widget(self):
        # Figure out if the widget should enabled or not.

   def render(self):
       if self.mode == INPUT_MODE:
            return self.input_template(self)
        elif self.mode == DISPLAY_MODE:
            return self.display_template(self)
        elif self.mode == HIDDEN_MODE:
            return self.hidden_template(self)
        elif self.mode == 'my_own_disabled_mode'
            return self.disabled_template(self)
        raise NotImplementedError(
            'Mode: "{0}" not supported'.format(self.mode))

# Following the patterns of z3c widget and create a widget factory.
# This is not necessary in this case, since there are no additional params.

@adapter(IMyBoolWidget, IFormLayer)
@implementer(IFieldWidget)
def MyBoolWidgetFactory(field, request, config=None):
    """IFieldWidget factory for..."""
    return FieldWidget(field, MyBoolWidget(request))

MyBoolFieldWidget = MyBoolWidgetFactory

使用zcml(configure.zcml)注册:

    <adapter factory=".widget.MyBoolWidgetFactory" />

将小部件用于布尔字段。

from plone.autoform.interfaces import IFormFieldProvider
from plone.supermodel import model
from zope import schema
from zope.interface import provider
from plone.directives import form
from wherever.the.widget.is import widget MyBoolFieldWidget


@provider(IFormFieldProvider)
class IGoogleNews(model.Schema):
    """Behavior interface to add some Google News features."""

    form.widget('standout_journalism', MyBoolFieldWidget)
    standout_journalism = schema.Bool(
        title=_(u'Standout Journalism'),
        required=False,
    )

    news_keywords = schema.Tuple(
        title=_(u'Keywords'),
        value_type=schema.TextLine(),
        required=False,
    )

按照这种方法,我创建了几个小部件, 例如,还有一个KeywordWidget

好的一面:

  • 通常小而简约
  • 易于使用

海棠:

  • 您需要在任何地方手动应用它。

该示例不包含任何模板,您可以获取它们from z3c.form或plone.z3cform。*

这种方法非常简单,不会使用小部件通常所做的所有组件。就像为每种模式注册一个小部件模板等