From 03296ef59e9900684193dfda243b96b291272fb5 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 | 15 ++++++++++++++ wcs/fields.py | 16 ++++++++++++++- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py index ab2658f5..606b620e 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'] = 'String' + resp.form['prefill$value_string'] = '{{form_var_toto}}' + resp = resp.form.submit('submit').follow() + assert FormDef.get(formdef.id).fields[0].prefill == {'type': 'string', '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'] = 'String' + resp.form['prefill$value_string'] = '{% 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 b567cf22..0b8376d0 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') @@ -1887,6 +1888,20 @@ def test_form_page_formula_prefill(pub): assert resp.forms[0]['f0'].value == 'HELLO WORLD' assert 'widget-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': 'string', '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 + 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 e38eefe5..e4f7c4a0 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 @@ -133,6 +134,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'] == 'string' and Template.is_template_string(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) @@ -294,7 +300,15 @@ class Field(object): # (that will therefore be marked as readonly etc.) t = self.prefill.get('type') if t == 'string': - return (self.prefill.get('value'), False) + value = self.prefill.get('value') + if not Template.is_template_string(value): + return (value, False) + + context = get_publisher().substitutions.get_context_variables() + try: + return (Template(value, autoescape=False).render(context), False) + except TemplateError: + return (None, False) elif t == 'user' and user: x = self.prefill.get('value') -- 2.17.1