A small integration of z3cform using grok magic on plone.
Project description
Introduction
This package enables the use of z3c forms in grok.View style inside a plone environment.
Using grok.View to display z3c.forms in plone
The goal of this package was to make a very minimal integration of z3c.form and plone. Far from plone.app.directive, my goal was to be light.
Do a simple naming schema
<<< 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')
The grok.View wrapping form can be looking like that
<<< class myview(collective.z3cform.grok.grok.FormWrapper): ... grok.context(zope.interface.Interface) ... form = MyForm
Note that this grok style class support those attributes:
layer: the Form Layer
Any grok directive (require, template, context, etc.)
form: The form class
Think that you can add some directives also on your form like ignoreContext
As we know how grok works, telling that we want an Interface as a context says that this form applys everywhere.
ignoreContext is used just to drop context mapping.
All that we have to do now is to instantiate and render our view and our form. And with grok magic, the view is already registered on our portal Note that its template will automaticly resolve to module_templates/lower_view_name.pt, and here: form_templates/bar.bt
>>> request = TestRequest(environ = {'SERVER_URL': 'http://nohost/@@myview'}) >>> 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> >>> 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'>
Verify the authenticity of our grok.View
>>> from zope.interface.verify import verifyObject >>> from grokcore.view.interfaces import IGrokView >>> pv.request is request True >>> verifyObject(IGrokView, pv) True
We can also test that all is in place through the web and that our view is registered and the switch_on cruft works.
>>> browser.open(portal.absolute_url()+"/@@myview") >>> print '\n'.join([a.rstrip() for a in browser.contents.split('\n') if a.strip()]) <!DOCTYPE html PUBLIC... <p>my grokky template</p> <p>The form is:</p> <form action="http://nohost/plone/@@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>...
Testing that the form submission & actions are working
>>> 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
Opening again with our StatusMessage cookie which has been set by previous request
>>> '<dd>me Grok NameField <> @name == foo</dd>' in browser.contents True
collective.z3cform.grok Installation
To install collective.z3cform.grok into the global Python environment (or a workingenv), using a traditional Zope 2 instance, you can do this:
When you’re reading this you have probably already run easy_install collective.z3cform.grok. Find out how to install setuptools (and EasyInstall) here: http://peak.telecommunity.com/DevCenter/EasyInstall
If you are using Zope 2.9 (not 2.10), get pythonproducts and install it via:
python setup.py install --home /path/to/instanceinto your Zope instance.
Create a file called collective.z3cform.grok-configure.zcml in the /path/to/instance/etc/package-includes directory. The file should only contain this:
<include package="collective.z3cform.grok" />
Alternatively, if you are using zc.buildout and the plone.recipe.zope2instance recipe to manage your project, you can do this:
Add collective.z3cform.grok to the list of eggs to install, e.g.:
[buildout] ... eggs = ... collective.z3cform.grokTell the plone.recipe.zope2instance recipe to install a ZCML slug:
[instance] recipe = plone.recipe.zope2instance ... zcml = collective.z3cform.grokRe-run buildout, e.g. with:
$ ./bin/buildout
You can skip the ZCML slug if you are going to explicitly include the package from another package’s configure.zcml file.
Changelog
1.2
handle better group forms and layers
1.1
bugfix: misunderstood something about the form.updateWidgets method.
1.0
Initial release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file collective.z3cform.grok-1.2dev-r99760.zip
.
File metadata
- Download URL: collective.z3cform.grok-1.2dev-r99760.zip
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a975a9dab8271db7341a5e0e59bc7dbb9c2a5c7178cc9c52891f5a2481be2bb6 |
|
MD5 | 9c98bd777b38f1d2d96b34098e34690f |
|
BLAKE2b-256 | 2059351cfb8a118f9b1d71c4b65fac8e86205d69d0059d93d0e1f7820d2aaee3 |