From 8c75e01a4bc8f64268784535040c312c4a197ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sat, 26 May 2018 21:29:21 +0200 Subject: [PATCH] general: add support for using templates to prefill fields (#24094) --- tests/test_admin_pages.py | 43 +++++++++++++++++++++++++++++++++++++++ tests/test_form_pages.py | 16 +++++++++++++++ wcs/fields.py | 18 ++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py index 0a8415bf..d2ad9504 100644 --- a/tests/test_admin_pages.py +++ b/tests/test_admin_pages.py @@ -1129,6 +1129,49 @@ def test_form_edit_field_advanced(pub): assert resp.body.index('Additional parameters') > \ resp.body.index('') +def test_form_prefill_field(pub): + create_superuser(pub) + create_role() + + FormDef.wipe() + formdef = FormDef() + formdef.name = 'form title' + formdef.fields = [fields.StringField(id='1', label='1st field', type='string')] + formdef.store() + + app = login(get_app(pub)) + + resp = app.get('/backoffice/forms/1/fields/1/') + resp.form['prefill$type'] = 'String' + resp.form['prefill$value_string'] = 'test' + resp = resp.form.submit('submit').follow() + assert FormDef.get(formdef.id).fields[0].prefill == {'type': 'string', 'value': 'test'} + + resp = app.get('/backoffice/forms/1/fields/1/') + resp.form['prefill$type'] = 'Formula (Python)' + resp.form['prefill$value_formula'] = 'True' + resp = resp.form.submit('submit').follow() + assert FormDef.get(formdef.id).fields[0].prefill == {'type': 'formula', 'value': 'True'} + + resp = app.get('/backoffice/forms/1/fields/1/') + resp.form['prefill$type'] = 'Template' + resp.form['prefill$value_template'] = '{{form_var_toto}}' + resp = resp.form.submit('submit').follow() + assert FormDef.get(formdef.id).fields[0].prefill == {'type': 'template', 'value': '{{form_var_toto}}'} + + # check error handling + resp = app.get('/backoffice/forms/1/fields/1/') + resp.form['prefill$type'] = 'Formula (Python)' + resp.form['prefill$value_formula'] = ':' + resp = resp.form.submit('submit') + assert 'invalid expression: unexpected EOF while parsing' in resp.body + + resp = app.get('/backoffice/forms/1/fields/1/') + resp.form['prefill$type'] = 'Template' + resp.form['prefill$value_template'] = '{% if %}' + resp = resp.form.submit('submit') + assert 'syntax error in Django template: Unexpected end of expression' in resp.body + def test_form_edit_item_field(pub): create_superuser(pub) create_role() diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py index f7f95f39..ea94ee53 100644 --- a/tests/test_form_pages.py +++ b/tests/test_form_pages.py @@ -88,6 +88,7 @@ def create_user(pub): PasswordAccount.wipe() user = pub.user_class() + user.name = 'User Name' user.email = 'foo@localhost' user.store() account = PasswordAccount(id='foo') @@ -1806,6 +1807,21 @@ def test_form_page_formula_prefill(pub): assert 'widget-prefilled' in resp.body assert 'Value has been automatically prefilled.' in resp.body +def test_form_page_template_prefill(pub): + user = create_user(pub) + formdef = create_formdef() + formdef.data_class().wipe() + formdef.fields = [ + fields.StringField(id='0', label='string', + prefill={'type': 'template', 'value': '{{session_user_display_name}}'})] + formdef.store() + + app = login(get_app(pub), username='foo', password='foo') + resp = app.get('/test/') + assert resp.form['f0'].value == 'User Name' + assert 'widget-prefilled' in resp.body + assert 'Value has been automatically prefilled.' in resp.body + def test_form_page_query_string_prefill(pub): user = create_user(pub) formdef = create_formdef() diff --git a/wcs/fields.py b/wcs/fields.py index 3de418a7..cf3bdce7 100644 --- a/wcs/fields.py +++ b/wcs/fields.py @@ -34,6 +34,7 @@ from qommon import _ from qommon import evalutils from qommon.form import * from qommon.misc import localstrftime, strftime, date_format, ellipsize +from qommon.template import Template, TemplateError from qommon import get_cfg, get_logger import data_sources @@ -50,6 +51,7 @@ class PrefillSelectionWidget(CompositeWidget): options = [('none', _('None')), ('string', _('String')), + ('template', _('Template')), ('formula', _('Formula (Python)')), ('user', _('User Field')), ('geolocation', _('Geolocation')),] @@ -74,6 +76,10 @@ class PrefillSelectionWidget(CompositeWidget): value=value.get('value') if value.get('type') == 'string' else None, attrs={'data-dynamic-display-child-of': 'prefill$type', 'data-dynamic-display-value': prefill_types.get('string')}) + self.add(StringWidget, 'value_template', size=80, + value=value.get('value') if value.get('type') == 'template' else None, + attrs={'data-dynamic-display-child-of': 'prefill$type', + 'data-dynamic-display-value': prefill_types.get('template')}) self.add(StringWidget, 'value_formula', size=80, value=value.get('value') if value.get('type') == 'formula' else None, attrs={'data-dynamic-display-child-of': 'prefill$type', @@ -133,6 +139,11 @@ class PrefillSelectionWidget(CompositeWidget): compile(values.get('value', ''), '', 'eval') except (SyntaxError, TypeError), e: self.set_error(_('invalid expression: %s') % e) + if values and values['type'] == 'template' and values.get('value'): + try: + Template(values.get('value'), raises=True) + except TemplateError as e: + self.set_error(str(e)) def render_content(self): r = TemplateIO(html=True) @@ -296,6 +307,13 @@ class Field(object): if t == 'string': return (self.prefill.get('value'), False) + elif t == 'template': + context = get_publisher().substitutions.get_context_variables() + try: + return (Template(self.prefill.get('value'), autoescape=False).render(context), False) + except TemplateError: + return (None, False) + elif t == 'user' and user: x = self.prefill.get('value') if x == 'email': -- 2.17.0