跳转到主要内容

Makina Corpus使用grok魔法在Plone上对z3cform进行的小型集成。

项目描述

简介

此软件包使您能够在Plone环境中使用grok.View样式使用z3c forms。

请注意,您有两个包装和一个基本表单类

  • FormWrapper 用于使用基本的 z3c.form 模板

  • PloneFormWrapper 是一个基本的 z3c.form 包装器,具有一些 Plone 集成(字段集 & kss)(来自 plone.app.z3cform

  • PloneForm 是一个基本的 z3c.form,具有一些 Plone 集成(字段集 & 组)(来自 plone.app.z3cform)

  • 一个用于测试您的代码的 TestCase,可以使用 z3cform.grok 直接使用或通过子类化它

致谢

makinacom

基本用法

在‘foo.py’模块中声明表单

>>> import plone.z3cform.fieldsets.extensible.ExtensibleForm$
>>> import z3c.form.form.Form
>>> class Myform(plone.z3cform.fieldsets.extensible.ExtensibleForm, z3c.form.form.Form):
...    """A z3c.form"""
...    ingoreContext = True or False # override me

请注意,collective.z3cform.grok.grok.PloneForm 是先前声明的快捷方式,请参阅实现。

然后包装器

>>> from collective.z3cform.grok.grok import PloneFormWrapper
>>> class myview(PloneFormWrapper):
...     form = Myform

在 foo_templates/myview.py 中编写一个基本模板,例如

<tal metal:use-macro="context/main_template/macros/master">
  <html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:tal="http://xml.zope.org/namespaces/tal"
    xmlns:metal="http://xml.zope.org/namespaces/metal"
    xmlns:i18n="http://xml.zope.org/namespaces/i18n"
    i18n:domain="nmd.sugar.forms"
    xml:lang="en" lang="en"
    tal:define="lang language"
    tal:attributes="lang lang; xml:lang lang">
    <body>
      <metal:main fill-slot="body">
        <tal:block tal:content="structure python:view.render_form()"></tal:block>
      </metal:main>
    </body>
  </html>
</tal>

Et voila,您可以通过以下方式访问您的表单 @

第三方软件包中的基本 grok 测试

导入基本测试用例

>>> from collective.z3cform.grok.tests.test_doctests import DocTestCase as dt
>>> from collective.z3cform.grok.tests.test_doctests import collective_z3cform_grok_setUp
>>> from collective.z3cform.grok.tests.test_doctests import collective_z3cform_grok_tearDown

使用您喜欢的测试用例之一组合测试用例

>>> class DocTestCase(MyFunctionalTestCase, dt):
...    def setUp_hook(self, *args, **kwargs):
...        MyFunctionalTestCase.setUp(self)
...    def tearDown_hook(self, *args, **kwargs):
...        MyFunctionalTestCase.tearDown(self)
...    def afterSetUp(self):
...        """."""
...        MyFunctionalTestCase.afterSetUp(self)
...

制作整个文档套件的 doc_suite soap

   >>> def test_doctests_suite(directory=None, globs=None, suite=None, testklass=None):
   ...     if not testklass: testklass=DocTestCase
   ...     if not directory:
   ...         directory, _f = os.path.split(os.path.abspath(__file__))
   ...     elif os.path.isfile(directory):
   ...         directory = os.path.dirname(directory)
   ...     files = [os.path.join(directory, f) for f in os.listdir(directory)
   ...                                   if f.endswith('.txt')]
   ...     if not globs:
   ...         globs={}
   ...     g = globals()
   ...     for key in g:
   ...         globs.setdefault(key, g[key])
   ...     directory = directory
   ...
   ...     if not suite:
   ...         suite = unittest.TestSuite()
   ...     if files:
   ...         options = doctest.REPORT_ONLY_FIRST_FAILURE |\
   ...                   doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
   ...         for test in files:
   ...             ft = ztc.ZopeDocFileSuite(
   ...                 test,
   ...                 test_class=testklass,
   ...                 optionflags=options,
   ...                 globs=globs,
   ...                 setUp=collective_z3cform_grok_setUp,
   ...                 tearDown=collective_z3cform_grok_tearDown,
   ...                 module_relative = False,
   ...             )
   ...             suite.addTest(ft)
   ...     return suite
   >>> def test_suite():
   ...     """."""
   ...     suite = unittest.TestSuite()
   ...     return test_doctests_suite(suite=suite)


Et voila, all files ending with txt in the tests directory will be tested with that magic TestCase.

使用 grok.View 在 Plone 中显示 z3c.forms

此软件包的目标是将 z3c.form 和 Plone 进行非常最小的集成。与 plone.app.directive 相比,我的目标是轻量级。

创建一个简单的命名方案

<<< import collective;from five import grok
<<< import zope, z3c
<<< class IMyFormSchema(zope.interface.Interface):
...     name = zope.schema.Text(title=u"Name", description = u'Name', required=False)
<<< class MyForm(z3c.form.form.Form):
...     ignoreContext = True
...     fields = z3c.form.field.Fields(IMyFormSchema)
...     @z3c.form.button.buttonAndHandler(u'Ok', name='Ok')
...     def ok(self, action, *args, **kwargs):
...         msg = u'me Grok NameField <> @name == %s' % self.widgets['name'].value
...         from Products.statusmessages.interfaces import IStatusMessage
...         IStatusMessage(self.request).addStatusMessage(msg, type='info')

grok.View包装表单可以看起来像这样

<<< class myview(collective.z3cform.grok.grok.FormWrapper):
...     grok.context(zope.interface.Interface)
...     form = MyForm

请注意,此 grok 风格类支持以下属性

  • layer:表单层

  • 任何grok指令(require、template、context等)

  • 表单:表单类

  • 认为您也可以在表单上添加一些指令,例如ignoreContext

  • 正如我们所知,grok是如何工作的,告诉我们要一个接口作为上下文,这意味着这个表单适用于任何地方。

  • ignoreContext仅用于取消上下文映射。

  • 我们现在需要做的是实例化和渲染我们的视图和表单。通过grok的魔法,视图已经注册到我们的门户上。注意,它的模板将自动解析为module_templates/lower_view_name.pt,这里:form_templates/bar.bt

>>> request = make_request()
>>> interface.alsoProvides(request, z3c.form.interfaces.IFormLayer)
>>> interface.alsoProvides(request, zope.annotation.interfaces.IAttributeAnnotatable)
>>> pv = getMultiAdapter((portal, request), name='myview')
>>> pv.template.__grok_location__.endswith('form_templates/myview.pt')
True
>>> print open(pv.template.__grok_location__).read()
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:tal="http://xml.zope.org/namespaces/tal"
  xmlns:metal="http://xml.zope.org/namespaces/metal"
  xmlns:i18n="http://xml.zope.org/namespaces/i18n"
  lang="en" xml:lang="en"
  metal:use-macro="context/main_template/macros/master">
  <body>
    <metal:main fill-slot="main">
      <tal:main-macro metal:define-macro="main">
        <p>my grokky template</p>
        <p>The form is:</p>
        <tal:block tal:content="structure python:view.render_form()"></tal:block>
      </tal:main-macro>
    </metal:main>
  </body>
</html>
<BLANKLINE>

我们需要调用update方法来手动触发form.update()过程

>>> pv.compute_widgets()
>>> print '\n'.join([a.rstrip() for a in pv.render_form().split('\n') if a.strip()])
        <form action="http://nohost/@@myview" method="post"
           enctype="multipart/form-data">
                  <div class="row">
                      <div class="field">
                        <label for="form-widgets-name">
                          <span>Name</span>
                        </label>
                        <div class="formHelp">Name</div>
                        <div class="widget">
                          <textarea id="form-widgets-name" name="form.widgets.name"
              class="textarea-widget text-field"></textarea>
                        </div>
                      </div>
                  </div>
                <div class="action">
                  <input type="submit" id="form-buttons-Ok"
           name="form.buttons.Ok"
           class="submit-widget button-field" value="Ok" />
                </div>
        </form>
>>> pv.__class__
<class 'collective.z3cform.grok.tests.form.myview'>

验证我们的grok.View的真实性

>>> from zope.interface.verify import verifyObject
>>> from grokcore.view.interfaces import IGrokView
>>> pv.request is request
True
>>> verifyObject(IGrokView, pv)
True

我们也可以通过网页测试一切是否就绪,以及我们的视图是否已注册,switch_on垃圾文件是否工作。注意,它使用plone.app.z3cform的form.pt模板。

>>> browser.open(portal.absolute_url()+"/@@myview")
>>> print '\n'.join([a.rstrip() for a in browser.contents.split('\n') if a.strip()])
<...<p>my grokky template</p>...<p>The form is:</p>
...<p class="discreet"></p>
...<form class="rowlike enableUnloadProtection  kssattr-formname-@@myview"...action="http://nohost/plone/@@myview"...
...id="form-widgets-name"...
...id="form-buttons-Ok"...
...</form>...

测试表单提交和操作是否正常工作

>>> browser.handleErrors = False
>>> browser.open(portal.absolute_url()+"/@@myview")
>>> browser.getControl(name='form.widgets.name').value = 'foo'
>>> browser.getControl(name='form.buttons.Ok').click()
>>> browser.url
'http://nohost/plone/@@myview'
>>> 'class="textarea-widget text-field">foo</textarea>' in browser.contents
True

再次使用我们的StatusMessage cookie打开,该cookie由之前的请求设置

>>> '<dd>me Grok NameField &lt;&gt; @name == foo</dd>' in browser.contents
True

collective.z3cform.grok 安装

要将collective.z3cform.grok安装到全局Python环境(或工作环境)中,使用传统的Zope 2实例,您可以这样做

  • 当您阅读此内容时,您可能已经运行了easy_install collective.z3cform.grok。有关如何安装setuptools(和EasyInstall)的信息,请参阅:http://peak.telecommunity.com/DevCenter/EasyInstall

  • 如果您使用的是Zope 2.9(而非2.10),请获取pythonproducts并通过以下方式安装它

    python setup.py install --home /path/to/instance

    到您的Zope实例。

  • /path/to/instance/etc/package-includes目录中创建一个名为collective.z3cform.grok-configure.zcml的文件。该文件应只包含以下内容

    <include package="collective.z3cform.grok" />

或者,如果您使用zc.buildout和plone.recipe.zope2instance配方来管理您的项目,您可以这样做

  • collective.z3cform.grok添加到要安装的egg列表中,例如

    [buildout]
    ...
    eggs =
        ...
        collective.z3cform.grok
  • 告诉plone.recipe.zope2instance配方安装ZCML别名

    [instance]
    recipe = plone.recipe.zope2instance
    ...
    zcml =
        collective.z3cform.grok
  • 重新运行buildout,例如使用

    $ ./bin/buildout

如果您将从另一个包的configure.zcml文件中显式包含该包,则可以跳过ZCML别名

变更日志

1.15 (2012-08-08)

  • 修复utf-8头

  • 修复接口导入

  • 删除无用的依赖项

  • 在grok.py中将plone.z3cform.z2.decode改为反映现有的plone.z3cform - 可能是版本差异[miohtama]

1.10

  • 添加其他表单辅助程序(无上下文、子表单)

  • 外部化一些粘合剂以处理zope2请求,以便在其他代码中重用。

1.9

  • 删除无用的调用

1.6 - 1.7 - 1.8

  • 重新工作测试基础设施。

1.4-1.5

  • 修复打包和重新加载函数

1.3

  • 添加plone表单

  • 更好地支持层

1.2

  • 更好地处理分组表单和层

1.1

  • 错误修复:误解了关于form.updateWidgets方法的某些内容。

1.0

  • 初始版本

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

collective.z3cform.grok-1.15.zip (38.1 kB 查看哈希值)

上传时间

由以下支持

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误记录StatusPageStatusPage状态页面