forms: switch comment field to render using a template (#30530)

This commit is contained in:
Frédéric Péters 2019-02-11 12:25:50 +01:00
parent e986bf93d8
commit 798934d531
6 changed files with 58 additions and 36 deletions

View File

@ -4255,7 +4255,7 @@ def test_backoffice_formdata_named_wscall(http_requests, pub):
app = login(get_app(pub))
resp = app.get('/backoffice/submission/test/')
assert '<p data-field-id="7" class="comment-field ">XbarY</p>' in resp.body
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
# check with publisher variable in named webservice call
if not pub.site_options.has_section('variables'):
@ -4270,13 +4270,13 @@ def test_backoffice_formdata_named_wscall(http_requests, pub):
wscall.store()
resp = app.get('/backoffice/submission/test/')
assert '<p data-field-id="7" class="comment-field ">XbarY</p>' in resp.body
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
# django-templated URL
wscall.request = {'url': '{{ example_url }}json'}
wscall.store()
resp = app.get('/backoffice/submission/test/')
assert '<p data-field-id="7" class="comment-field ">XbarY</p>' in resp.body
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
# webservice call in django template
formdef.fields = [
@ -4285,7 +4285,7 @@ def test_backoffice_formdata_named_wscall(http_requests, pub):
formdef.store()
formdef.data_class().wipe()
resp = app.get('/backoffice/submission/test/')
assert '<p data-field-id="7" class="comment-field ">dja-bar-ngo</p>' in resp.body
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'dja-bar-ngo'
def test_backoffice_session_var(pub):
open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w').write('''[options]
@ -4309,7 +4309,7 @@ query_string_allowed_vars = foo,bar
resp = app.get('/backoffice/submission/test/?session_var_foo=bar')
assert resp.location.endswith('/backoffice/submission/test/')
resp = resp.follow()
assert '<p data-field-id="7" class="comment-field ">XbarY</p>' in resp.body
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
# django template
formdef.fields = [
@ -4320,7 +4320,7 @@ query_string_allowed_vars = foo,bar
resp = app.get('/backoffice/submission/test/?session_var_foo=jang')
assert resp.location.endswith('/backoffice/submission/test/')
resp = resp.follow()
assert '<p data-field-id="7" class="comment-field ">django</p>' in resp.body
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'django'
def test_backoffice_display_message(pub):
user = create_user(pub)

View File

@ -3,6 +3,7 @@
import re
import shutil
from bs4 import BeautifulSoup
import pytest
from quixote import cleanup
@ -155,43 +156,43 @@ def test_comment():
field = fields.CommentField(label='Foobar')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p data-field-id="None" class="comment-field ">Foobar</p>' in str(form.render())
assert BeautifulSoup(str(form.render())).find('div').text.strip() == 'Foobar'
field = fields.CommentField(label='Foo\n\nBar\n\nBaz')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p>Foo</p>\n<p>Bar</p>\n<p>Baz</p>' in str(form.render())
assert '<div data-field-id="None" class="comment-field "' in str(form.render())
assert re.match( # regex to handle different beautifulsoup behaviours
'<div class="comment-field\s?">\n<p>Foo</p>\n<p>Bar</p>\n<p>Baz</p>\n</div>',
str(BeautifulSoup(str(form.render())).find('div')))
# test for variable substitution
pub.substitutions.feed(MockSubstitutionVariables())
field = fields.CommentField(label='{{ bar }}')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p data-field-id="None" class="comment-field ">Foobar</p>' in str(form.render())
assert BeautifulSoup(str(form.render())).find('div').text.strip() == 'Foobar'
field = fields.CommentField(label='[bar]')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p data-field-id="None" class="comment-field ">Foobar</p>' in str(form.render())
assert BeautifulSoup(str(form.render())).find('div').text.strip() == 'Foobar'
# test for proper escaping of substitution variables
field = fields.CommentField(label='{{ foo }}')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p data-field-id="None" class="comment-field ">1 &lt; 3</p>' in str(form.render())
assert '1 &lt; 3' in str(form.render())
field = fields.CommentField(label='[foo]')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p data-field-id="None" class="comment-field ">1 &lt; 3</p>' in str(form.render())
assert '1 &lt; 3' in str(form.render())
# test for html content
field = fields.CommentField(label='<p>Foobar</p>')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p>Foobar</p>' in str(form.render())
assert '<div data-field-id="None" class="comment-field "' in str(form.render())
assert field.unhtmled_label == 'Foobar'
field = fields.CommentField(label='<p>Foobar&eacute;</p>')

View File

@ -5476,13 +5476,13 @@ def test_field_unicode_condition_in_array(pub):
required=True, varname='baz',
condition={'type': 'django', 'value': '"Pêche" in form_var_foo'}),
fields.CommentField(type='comment', id='4', label='{{form_var_foo}}'),
fields.CommentField(type='comment', id='5', label='{% if "Pêche" in form_var_foo %}OK{% endif %}'),
fields.CommentField(type='comment', id='5', label='{% if "Pêche" in form_var_foo %}CHECK OK{% endif %}'),
]
workflow = Workflow(name='test')
st1 = workflow.add_status('Status1', 'st1')
display1 = DisplayMessageWorkflowStatusItem()
display1.message = 'Message {% if "Pêche" in form_var_foo %}OK{% endif %}'
display1.message = 'Message {% if "Pêche" in form_var_foo %}CHECK OK{% endif %}'
display1.to = []
st1.items.append(display1)
display1.parent = st1
@ -5503,11 +5503,11 @@ def test_field_unicode_condition_in_array(pub):
assert 'f3' in resp.form.fields # check it's ok in field condition
resp.form['f3'] = 'hop'
assert '>Poire, Pêche<' in resp.body # check it's displayed correctly
assert '>OK<' in resp.body # check it's ok in template condition
assert 'CHECK OK' in resp.body # check it's ok in template condition
resp = resp.form.submit('submit')
assert 'Check values then click submit.' in resp.body
resp = resp.form.submit('submit').follow()
assert '<p>Message OK</p>' in resp.body # check it's ok in workflow template
assert '<p>Message CHECK OK</p>' in resp.body # check it's ok in workflow template
def test_field_live_condition(pub):
FormDef.wipe()

View File

@ -607,23 +607,13 @@ class CommentField(Field):
key = 'comment'
description = N_('Comment')
def add_to_form(self, form, value = None):
tag_attributes = 'data-field-id="%s" class="comment-field %s"' % (
self.id, self.extra_css_class or '')
label = self.get_html_content()
def add_to_form(self, form, value=None):
import wcs.workflows
label = self.get_html_content()
label = wcs.workflows.template_on_html_string(label)
enclosing_tag = 'p'
for block_level in ('p', 'div', 'ul', 'ol', 'hr'):
if '<' + block_level in label:
enclosing_tag = 'div'
break
widget = HtmlWidget(htmltext('<%s %s>%s</%s>' % (
enclosing_tag, tag_attributes, label, enclosing_tag)))
widget = CommentWidget(
content=label,
extra_css_class=self.extra_css_class)
form.widgets.append(widget)
return widget
@ -631,9 +621,15 @@ class CommentField(Field):
pass
def get_html_content(self):
if self.label and '\n\n' in self.label and self.label[0] != '<':
return '<p>' + re.sub('\n\n+', '</p>\n<p>', self.label) + '</p>'
return self.label
if not self.label:
return ''
if self.label.startswith('<'):
return self.label
if '\n\n' in self.label:
# blank lines to paragraphs
label = '</p>\n<p>'.join([str(htmlescape(x)) for x in re.split('\n\n+', self.label)])
return '<p>' + label + '</p>'
return '<p>%s</p>' % str(htmlescape(self.label))
def fill_admin_form(self, form):
if self.label and (self.label[0] != '<' and '[end]' in self.label):

View File

@ -431,6 +431,25 @@ class HtmlWidget(object):
def clear_error(self, request=None):
pass
class CommentWidget(Widget):
template_name = 'qommon/forms/widgets/comment.html'
def __init__(self, content, extra_css_class):
super(CommentWidget, self).__init__(name='')
self.content = content
self.extra_css_class = extra_css_class
def has_error(self, request):
return False
def parse(self, *args, **kwargs):
pass
def clear_error(self, request=None):
pass
class CompositeWidget(quixote.form.CompositeWidget):
def render_as_thead(self):
r = TemplateIO(html=True)

View File

@ -0,0 +1,6 @@
<div {% if widget.field.id %}data-field-id="{{ widget.field.id }}"{% endif %}
class="comment-field {{widget.extra_css_class|default_if_none:"" }}">
{% block widget-content %}
{{ widget.content|safe }}
{% endblock %}
</div>