--- a/src/pyams_default_theme/shared/form/__init__.py Wed Sep 04 16:10:10 2019 +0200
+++ b/src/pyams_default_theme/shared/form/__init__.py Tue Sep 17 12:00:26 2019 +0200
@@ -13,11 +13,13 @@
import requests
from pyramid.csrf import get_csrf_token
from z3c.form import button, field
+from z3c.form.browser.checkbox import SingleCheckBoxFieldWidget
from z3c.form.interfaces import HIDDEN_MODE
-from zope.interface import Interface, Invalid
-from zope.schema import TextLine
+from zope.interface import Interface, Invalid, alsoProvides
+from zope.schema import Bool, TextLine
from pyams_content.shared.form import IFormFieldContainer, IFormFieldContainerTarget, IWfForm
+from pyams_content.shared.form.interfaces import IFormFieldDataConverter
from pyams_default_theme.component.paragraph.interfaces import IParagraphContainerPortletRenderer
from pyams_default_theme.interfaces import IContentTitle
from pyams_default_theme.layer import IPyAMSDefaultLayer
@@ -31,6 +33,8 @@
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
from pyams_utils.interfaces import PUBLIC_PERMISSION, VIEW_PERMISSION
+from pyams_utils.interfaces.data import IObjectData
+from pyams_utils.text import text_to_html
from pyams_utils.url import relative_url
from pyams_viewlet.viewlet import ViewContentProvider, Viewlet, viewlet_config
@@ -42,6 +46,7 @@
CSRF_FIELD_NAME = 'csrf_token'
RECAPTCHA_FIELD_NAME = 'g-recaptcha-response'
+RGPD_CONSENT_FIELD_NAME = 'rgpd_consent'
MISSING_TOKEN_ERROR = _("Missing recaptcha token!")
INVALID_TOKEN_ERROR = _("Can't verify recaptcha token! Are you a robot?")
@@ -84,8 +89,18 @@
captcha.__name__ = RECAPTCHA_FIELD_NAME
yield captcha
yield from IFormFieldContainer(self.context).get_fields()
+ if self.context.rgpd_consent:
+ consent = Bool(title=II18n(self.context).query_attribute('rgpd_warning',
+ request=self.request),
+ required=True,
+ default=False)
+ consent.__name__ = RGPD_CONSENT_FIELD_NAME
+ yield consent
- return field.Fields(*tuple(get_fields()))
+ fields = field.Fields(*tuple(get_fields()))
+ if self.context.rgpd_consent:
+ fields[RGPD_CONSENT_FIELD_NAME].widgetFactory = SingleCheckBoxFieldWidget
+ return fields
def updateActions(self):
super(FormFieldContainerInputForm, self).updateActions()
@@ -103,6 +118,20 @@
elif widget.field.__name__ == RECAPTCHA_FIELD_NAME:
widget.name = RECAPTCHA_FIELD_NAME
widget.mode = HIDDEN_MODE
+ elif widget.field.__name__ == RGPD_CONSENT_FIELD_NAME:
+ widget.name = RGPD_CONSENT_FIELD_NAME
+ widget.required = False
+ user_rights = II18n(self.context).query_attribute('rgpd_user_rights',
+ request=self.request)
+ widget.after_widget_notice = '<div><br />{0}</div>'.format(
+ text_to_html(user_rights, 'oid_to_href'))
+ widget.object_data = {
+ 'ams-validate-messages': {
+ 'required': self.request.localizer.translate(
+ _("You can't submit this form without accepting data usage rules."))
+ }
+ }
+ alsoProvides(widget, IObjectData)
else:
field = IFormFieldContainer(self.context).get(widget.field.__name__)
if field is not None:
@@ -110,33 +139,44 @@
@button.buttonAndHandler('title', name='submit')
def update_content(self, action):
+ request = self.request
form = IWfForm(self.context)
handler = form.query_handler()
if handler is not None:
data, errors = self.extractData()
if errors:
- self.status = self.formErrorsMessage
+ self.status = request.localizer.translate(self.formErrorsMessage)
else:
# remove custom data fields from handler data
if CSRF_FIELD_NAME in data:
del data[CSRF_FIELD_NAME]
- if self.context.use_captcha:
+ if form.use_captcha:
if RECAPTCHA_FIELD_NAME not in data:
self.add_error(Invalid(MISSING_TOKEN_ERROR), RECAPTCHA_FIELD_NAME)
return
- proxies = {'https': self.context.captcha_proxy} if self.context.captcha_proxy else {}
- recaptcha_verify_api = self.request.registry.settings.get('pyams.recaptcha.verify')
+ proxies = {'https': form.captcha_proxy} if form.captcha_proxy else {}
+ recaptcha_verify_api = \
+ request.registry.settings.get('pyams.recaptcha.verify')
if not recaptcha_verify_api:
recaptcha_verify_api = 'https://www.google.com/recaptcha/api/siteverify'
verify = requests.post(recaptcha_verify_api, {
- 'secret': self.context.server_captcha_key,
+ 'secret': form.server_captcha_key,
'response': data[RECAPTCHA_FIELD_NAME]
}, proxies=proxies).json()
if not verify['success']:
self.add_error(INVALID_TOKEN_ERROR, RECAPTCHA_FIELD_NAME)
return
del data[RECAPTCHA_FIELD_NAME]
- handler.handle(form, data)
+ # convert form data
+ user_data = data.copy()
+ for field in IFormFieldContainer(form).get_fields():
+ converter = request.registry.queryMultiAdapter((field, request),
+ IFormFieldDataConverter)
+ if converter is not None:
+ user_data[field.__name__] = converter.convert(data.get(field.__name__))
+ output = handler.handle(form, data, user_data)
+ if output:
+ request.annotations['form.output'] = output
@adapter_config(context=(IFormFieldContainerTarget, IPyAMSLayer, FormFieldContainerInputForm),
--- a/src/pyams_default_theme/shared/form/templates/form-submit.pt Wed Sep 04 16:10:10 2019 +0200
+++ b/src/pyams_default_theme/shared/form/templates/form-submit.pt Tue Sep 17 12:00:26 2019 +0200
@@ -1,1 +1,8 @@
-<div>${structure:i18n:context.submit_message}</div>
\ No newline at end of file
+<tal:if define="output view.view.input_form.request.annotations.get('form.output')">
+ <tal:if condition="output">
+ ${structure:output}
+ </tal:if>
+ <tal:if condition="not:output">
+ <div>${structure:i18n:context.submit_message}</div>
+ </tal:if>
+</tal:if>
\ No newline at end of file