WIP: génération de form_details en HTML dans mes mails HTML (#36626) #1055

Draft
fpeters wants to merge 2 commits from wip/36626-html-form-details into main
5 changed files with 90 additions and 72 deletions

View File

@ -28,7 +28,7 @@ from django.utils.html import strip_tags
from django.utils.timezone import localtime, make_naive
from quixote import get_publisher, get_request, get_session
from quixote.errors import RequestError
from quixote.html import htmltext
from quixote.html import TemplateIO, htmltext
from quixote.http_request import Upload
from wcs.sql_criterias import And, Contains, Equal, Intersects
@ -2018,6 +2018,63 @@ class FormData(StorableObject):
if on_page:
yield {'action': 'close-page'}
def get_html_summary(self, fields=None, form_url='', include_unset_required_fields=False):
r = TemplateIO(html=True)
for field_action in self.get_summary_display_actions(
fields, include_unset_required_fields=include_unset_required_fields
):
if field_action['action'] == 'close-page':
r += htmltext('</div>')
r += htmltext('</div>')
elif field_action['action'] == 'open-page':
r += htmltext('<div class="page">')
r += htmltext('<h3>%s</h3>') % field_action['value']
r += htmltext('<div>')
elif field_action['action'] == 'title':
r += htmltext('<div class="title %s"><h3>%s</h3></div>') % (
field_action['css'],
field_action['value'],
)
elif field_action['action'] == 'subtitle':
label_id = field_action.get('id')
if label_id:
r += htmltext('<div class="subtitle %s" id="%s"><h4>%s</h4></div>') % (
field_action['css'],
label_id,
field_action['value'],
)
else:
r += htmltext('<div class="subtitle %s"><h4>%s</h4></div>') % (
field_action['css'],
field_action['value'],
)
elif field_action['action'] == 'comment':
r += htmltext(
'<div class="comment-field %s">%s</div>' % (field_action['css'], field_action['value'])
)
elif field_action['action'] == 'open-field':
r += htmltext('<div class="%s">' % field_action['css'])
elif field_action['action'] == 'close-field':
r += htmltext('</div>')
elif field_action['action'] == 'label':
r += htmltext('<p id="%s" class="label">%s</p> ') % (
field_action['id'],
field_action['value'],
)
elif field_action['action'] == 'value':
value = field_action['value']
if value is None:
r += htmltext('<div class="value"><i>%s</i></div>') % _('Not set')
else:
r += htmltext('<div class="value">')
r += value
r += htmltext('</div>')
r += '\n'
return r.getvalue()
def get_rst_summary(self, form_url=''):
r = ''
@ -2075,13 +2132,19 @@ class FormDetails:
def __init__(self, formdata):
self.formdata = formdata
self._cache = None
self._rendering_mode = get_publisher().rendering_mode
def get_value(self):
if self._cache:
return self._cache
self._cache = (
self.formdata.formdef.get_detailed_email_form(self.formdata, self.formdata.get_url()) or ''
)
if self._rendering_mode == 'email-html' or self._rendering_mode is None:
from django.utils.safestring import mark_safe
self._cache = mark_safe(self.formdata.get_html_summary())
else:
self._cache = (
self.formdata.formdef.get_detailed_email_form(self.formdata, self.formdata.get_url()) or ''
)
return self._cache
def __str__(self):

View File

@ -548,74 +548,17 @@ class FormStatusPage(Directory, FormTemplateMixin):
{
'formdata': self.filled,
'should_fold_summary': self.should_fold_summary(mine, request_user),
'fields': self.display_fields(form_url=form_url),
'fields': self.filled.get_html_summary(form_url=form_url),
'view': self,
'user': user,
},
)
def display_fields(self, fields=None, form_url='', include_unset_required_fields=False):
r = TemplateIO(html=True)
for field_action in self.filled.get_summary_display_actions(
fields, include_unset_required_fields=include_unset_required_fields
):
if field_action['action'] == 'close-page':
r += htmltext('</div>')
r += htmltext('</div>')
elif field_action['action'] == 'open-page':
r += htmltext('<div class="page">')
r += htmltext('<h3>%s</h3>') % field_action['value']
r += htmltext('<div>')
elif field_action['action'] == 'title':
r += htmltext('<div class="title %s"><h3>%s</h3></div>') % (
field_action['css'],
field_action['value'],
)
elif field_action['action'] == 'subtitle':
label_id = field_action.get('id')
if label_id:
r += htmltext('<div class="subtitle %s" id="%s"><h4>%s</h4></div>') % (
field_action['css'],
label_id,
field_action['value'],
)
else:
r += htmltext('<div class="subtitle %s"><h4>%s</h4></div>') % (
field_action['css'],
field_action['value'],
)
elif field_action['action'] == 'comment':
r += htmltext(
'<div class="comment-field %s">%s</div>' % (field_action['css'], field_action['value'])
)
elif field_action['action'] == 'open-field':
r += htmltext('<div class="%s">' % field_action['css'])
elif field_action['action'] == 'close-field':
r += htmltext('</div>')
elif field_action['action'] == 'label':
r += htmltext('<p id="%s" class="label">%s</p> ') % (
field_action['id'],
field_action['value'],
)
elif field_action['action'] == 'value':
value = field_action['value']
if value is None:
r += htmltext('<div class="value"><i>%s</i></div>') % _('Not set')
else:
r += htmltext('<div class="value">')
r += value
r += htmltext('</div>')
r += '\n'
return r.getvalue()
def backoffice_fields_section(self):
backoffice_fields = self.formdef.workflow.get_backoffice_fields()
if not backoffice_fields:
return
content = self.display_fields(backoffice_fields, include_unset_required_fields=True)
content = self.filled.get_html_summary(backoffice_fields, include_unset_required_fields=True)
if not content:
return
r = TemplateIO(html=True)

View File

@ -133,6 +133,7 @@ class WcsPublisher(QommonPublisher):
tracking_code_class = TrackingCode
unpickler_class = UnpicklerClass
rendering_mode = None
complex_data_cache = None
@classmethod

View File

@ -370,6 +370,12 @@ class QommonPublisher(Publisher):
if lang not in self._i18n_catalog:
self._i18n_catalog[lang] = TranslatableMessage.load_as_catalog(lang)
@contextmanager
def with_rendering_mode(self, mode):
restore_mode, self.rendering_mode = self.rendering_mode, mode
yield True
self.rendering_mode = restore_mode
@contextmanager
def with_language(self, language):
if language == 'default':

View File

@ -286,15 +286,20 @@ class SendmailWorkflowStatusItem(WorkflowStatusItem):
subject = get_publisher().translate(subject)
body = get_publisher().translate(body)
try:
mail_body = template_on_formdata(
formdata, self.compute(body, render=False), autoescape=body.startswith('<')
)
except TemplateError as e:
get_publisher().record_error(
_('Error in body template, mail could not be generated'), formdata=formdata, exception=e
)
return
rendering_mode = 'email-html' if body.startswith('<') else 'rst'
with get_publisher().with_rendering_mode(rendering_mode):
try:
mail_body = template_on_formdata(
formdata,
self.compute(body, render=False),
autoescape=bool(rendering_mode == 'email-html'),
)
except TemplateError as e:
get_publisher().record_error(
_('Error in body template, mail could not be generated'), formdata=formdata, exception=e
)
return
try:
mail_subject = template_on_formdata(