use Django/ezt templates in messages (email, sms, journal) (#19442)

This commit is contained in:
Thomas NOËL 2017-10-18 00:02:29 +02:00
parent 7d92cf296e
commit 18c9258e9f
15 changed files with 179 additions and 140 deletions

View File

@ -165,12 +165,22 @@ def test_comment():
# 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 class="comment-field ">Foobar</p>' in str(form.render())
field = fields.CommentField(label='[bar]')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p class="comment-field ">Foobar</p>' in str(form.render())
# test for proper escaping of substitution variables
field = fields.CommentField(label='{{ foo }}')
form = Form(use_tokens=False)
field.add_to_form(form)
assert '<p class="comment-field ">1 &lt; 3</p>' in str(form.render())
field = fields.CommentField(label='[foo]')
form = Form(use_tokens=False)
field.add_to_form(form)

View File

@ -45,10 +45,16 @@ def test_get_html_subst():
# test for variable substitution
TextsDirectory.register('foo4', 'Foo', default='Foo...')
pub.substitutions.feed(MockSubstitutionVariables())
pub.cfg['texts'] = {'text-foo4': '[bar]'}
pub.cfg['texts'] = {'text-foo4': 'dj{{ bar }}'}
pub.write_cfg()
assert TextsDirectory.get_html_text('foo4') == '<div class="text-foo4"><p>Foobar</p></div>'
assert TextsDirectory.get_html_text('foo4') == '<div class="text-foo4"><p>djFoobar</p></div>'
pub.cfg['texts'] = {'text-foo4': 'ezt[bar]'}
pub.write_cfg()
assert TextsDirectory.get_html_text('foo4') == '<div class="text-foo4"><p>eztFoobar</p></div>'
pub.cfg['texts'] = {'text-foo4': '[foo]'}
pub.cfg['texts'] = {'text-foo4': 'dj{{ foo }}'}
pub.write_cfg()
assert TextsDirectory.get_html_text('foo4') == '<div class="text-foo4"><p>1 &lt; 3</p></div>'
assert TextsDirectory.get_html_text('foo4') == '<div class="text-foo4"><p>dj1 &lt; 3</p></div>'
pub.cfg['texts'] = {'text-foo4': 'ezt[foo]'}
pub.write_cfg()
assert TextsDirectory.get_html_text('foo4') == '<div class="text-foo4"><p>ezt1 &lt; 3</p></div>'

View File

@ -587,22 +587,46 @@ def test_register_comment(pub):
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<div>Hello world</div>'
item.comment = '{{ test }}'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == ''
item.comment = '[test]'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<p>[test]</p>'
item.comment = '{{ bar }}'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<p>Foobar</p>'
item.comment = '[bar]'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<p>Foobar</p>'
item.comment = '<p>{{ foo|safe }}</p>'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<p>1 &lt; 3</p>'
item.comment = '{{ foo|safe }}'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<p>1 &lt; 3</p>'
item.comment = '[foo]'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<p>1 &lt; 3</p>'
item.comment = '<div>{{ foo|safe }}</div>'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
assert formdata.evolution[-1].display_parts()[-1] == '<div>1 &lt; 3</div>'
item.comment = '<div>[foo]</div>'
item.perform(formdata)
formdata.evolution[-1]._display_parts = None
@ -633,20 +657,32 @@ def test_register_comment_attachment(pub):
formdata.store()
assert len(os.listdir(os.path.join(get_publisher().app_dir, 'attachments'))) == 1
item.comment = '[attachments.testfile.url]'
item.comment = '{{ attachments.testfile.url }}'
pub.substitutions.feed(formdata)
item.perform(formdata)
url1 = formdata.evolution[-1].parts[-1].content
pub.substitutions.feed(formdata)
item.comment = '[form_attachments.testfile.url]'
item.comment = '{{ form_attachments.testfile.url }}'
item.perform(formdata)
url2 = formdata.evolution[-1].parts[-1].content
assert len(os.listdir(os.path.join(get_publisher().app_dir, 'attachments'))) == 1
assert url1 == url2
pub.substitutions.feed(formdata)
item.comment = '[attachments.testfile.url]'
item.perform(formdata)
url3 = formdata.evolution[-1].parts[-1].content
assert url1 == url3
pub.substitutions.feed(formdata)
item.comment = '[form_attachments.testfile.url]'
item.perform(formdata)
url4 = formdata.evolution[-1].parts[-1].content
assert url1 == url4
def test_email(pub, emails):
pub.substitutions.feed(MockSubstitutionVariables())
@ -695,9 +731,31 @@ def test_email(pub, emails):
assert emails.count() == 1
assert emails.get('foobar')
assert emails.get('foobar')['email_rcpt'] == ['foo@localhost']
assert 'baz' in emails.get('foobar')['payload']
# template for subject or body (Django)
emails.empty()
item.subject = '{{ bar|safe }}'
item.body = '{{ foo|safe }}'
item.perform(formdata)
get_response().process_after_jobs()
assert emails.count() == 1
assert emails.get('Foobar')
assert '1 < 3' in emails.get('Foobar')['payload']
# template for subject or body (ezt)
emails.empty()
item.subject = '[bar]'
item.body = '[foo]'
item.perform(formdata)
get_response().process_after_jobs()
assert emails.count() == 1
assert emails.get('Foobar')
assert '1 < 3' in emails.get('Foobar')['payload']
# two recipients
emails.empty()
item.subject = 'foobar'
item.to = [role1.id, role2.id]
item.perform(formdata)
get_response().process_after_jobs()
@ -1586,28 +1644,41 @@ def test_sms(pub, sms_mocking):
item.to = ['000']
item.body = 'XXX'
assert len(sms_mocking.sms) == 0
item.perform(formdata) # nothing
item.perform(formdata)
assert len(sms_mocking.sms) == 1
assert sms_mocking.sms[0]['destinations'] == ['000']
assert sms_mocking.sms[0]['text'] == 'XXX'
# check None as recipient is not passed to the SMS backend
item.to = [None]
item.perform(formdata) # nothing
item.perform(formdata) # nothing
assert len(sms_mocking.sms) == 1
item.to = ['000', None]
item.perform(formdata) # nothing
item.perform(formdata)
assert len(sms_mocking.sms) == 2
assert sms_mocking.sms[1]['destinations'] == ['000']
assert sms_mocking.sms[1]['text'] == 'XXX'
pub.substitutions.feed(MockSubstitutionVariables())
item.body = 'dj{{ bar }}'
item.perform(formdata)
assert len(sms_mocking.sms) == 3
assert sms_mocking.sms[2]['destinations'] == ['000']
assert sms_mocking.sms[2]['text'] == 'djFoobar'
item.body = 'ezt[bar]'
item.perform(formdata)
assert len(sms_mocking.sms) == 4
assert sms_mocking.sms[3]['destinations'] == ['000']
assert sms_mocking.sms[3]['text'] == 'eztFoobar'
# disable SMS system
pub.cfg['sms'] = {'mode': 'none'}
item.to = ['000']
item.body = 'XXX'
item.perform(formdata) # nothing
assert len(sms_mocking.sms) == 2
item.perform(formdata) # nothing
assert len(sms_mocking.sms) == 4
def test_sms_with_passerelle(pub):
pub.cfg['sms'] = {'mode': 'passerelle',
@ -1815,13 +1886,21 @@ def test_workflow_display_message(pub):
display_message.message = 'test'
assert display_message.get_message(formdata) == 'test'
display_message.message = '{{ number }}'
assert display_message.get_message(formdata) == str(formdata.id)
display_message.message = '[number]'
assert display_message.get_message(formdata) == str(formdata.id)
display_message.message = '{{ bar }}'
assert display_message.get_message(formdata) == 'Foobar'
display_message.message = '[bar]'
assert display_message.get_message(formdata) == 'Foobar'
# makes sure the string is correctly escaped for HTML
display_message.message = '{{ foo }}'
assert display_message.get_message(formdata) == '1 &lt; 3'
display_message.message = '[foo]'
assert display_message.get_message(formdata) == '1 &lt; 3'

View File

@ -4,7 +4,7 @@ import pytest
from StringIO import StringIO
from wcs.qommon.http_request import HTTPRequest
from wcs.qommon.ezt import Template
from wcs.qommon.template import Template
from wcs.wscalls import NamedWsCall
from utilities import create_temporary_pub, clean_temporary_pub, http_requests
@ -121,15 +121,14 @@ def test_wscall_ezt(pub):
pub.substitutions.feed(NamedWsCall)
variables = pub.substitutions.get_context_variables()
template = Template()
template.parse('<p>[webservice.hello_world.foo]</p>')
output = StringIO()
template.generate(output, variables)
assert output.getvalue() == '<p>bar</p>'
template = Template('<p>{{ webservice.hello_world.foo }}</p>')
assert template.render(variables) == '<p>bar</p>'
template = Template('<p>[webservice.hello_world.foo]</p>')
assert template.render(variables) == '<p>bar</p>'
# undefined webservice
template = Template()
template.parse('<p>[webservice.hello.foo]</p>')
output = StringIO()
template.generate(output, variables)
assert output.getvalue() == '<p>[webservice.hello.foo]</p>'
template = Template('<p>{{ webservice.hello.foo }}</p>')
assert template.render(variables) == '<p></p>'
template = Template('<p>[webservice.hello.foo]</p>')
assert template.render(variables) == '<p>[webservice.hello.foo]</p>'

View File

@ -44,7 +44,6 @@ from qommon.afterjobs import AfterJob
from qommon import emails
import qommon.sms
from qommon import errors
from qommon import ezt
from qommon import ods
from qommon.form import *
from qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or,
@ -153,7 +152,7 @@ class SendCodeFormdefDirectory(Directory):
tracking_code = get_publisher().tracking_code_class()
tracking_code.formdata = formdata # this stores both objects
msg = form.get_widget('text').parse()
message = form.get_widget('text').parse()
data = {
'form_tracking_code': formdata.tracking_code,
'tracking_code': formdata.tracking_code,
@ -161,17 +160,11 @@ class SendCodeFormdefDirectory(Directory):
}
data.update(self.formdef.get_substitution_variables(minimal=True))
msg_template = ezt.Template(compress_whitespace=False)
msg_template.parse(msg)
fd = cStringIO.StringIO()
msg_template.generate(fd, data)
msg_body = fd.getvalue()
if sms_class and form.get_widget('method').parse() == 'sms':
# send sms
sitename = get_cfg('misc', {}).get('sitename') or 'w.c.s.'
sender = sms_cfg.get('sender', sitename)[:11]
message = msg_body
message = Template(message).render(data)
try:
sms_class.send(sender, [form.get_widget('sms').parse()], message)
except errors.SMSError, e:
@ -179,7 +172,7 @@ class SendCodeFormdefDirectory(Directory):
get_session().message = ('info', _('SMS with tracking code sent to the user'))
else:
# send mail
emails.ezt_email(mail_subject, msg_body,
emails.template_email(mail_subject, message,
mail_body_data=data,
email_rcpt=form.get_widget('email').parse())
get_session().message = ('info', _('Email with tracking code sent to the user'))

View File

@ -19,7 +19,6 @@ import copy
import datetime
import json
import re
from cStringIO import StringIO
import sys
import time
@ -29,9 +28,9 @@ from quixote.http_request import Upload
from qommon import _
from qommon.storage import StorableObject, Intersects, Contains
import qommon.misc
from qommon import ezt
from qommon.evalutils import make_datetime
from qommon.substitution import Substitutions
from qommon.template import Template
from roles import Role
from fields import FileField
@ -376,13 +375,10 @@ class FormData(StorableObject):
self.evolution = [evo]
def set_auto_display_id(self):
processor = ezt.Template(compress_whitespace=True)
processor.parse(self.formdef.get_display_id_format().strip())
fd = StringIO()
ctx = self.get_substitution_variables(minimal=True)
ctx['formdef_id'] = self.formdef.id
processor.generate(fd, ctx)
self.id_display = fd.getvalue()
template = self.formdef.get_display_id_format().strip()
context = self.get_substitution_variables(minimal=True)
context['formdef_id'] = self.formdef.id
self.id_display = Template(template).render(context)
# criticality levels are stored as [0, 101, 102, 103...], this makes it
# easier to group "uncritical" formdatas (=0) together when sorting.

View File

@ -160,7 +160,7 @@ class TrackingCodeDirectory(Directory):
'email': email
}
data.update(self.formdef.get_substitution_variables(minimal=True))
emails.custom_ezt_email('tracking-code-reminder', data,
emails.custom_template_email('tracking-code-reminder', data,
email, fire_and_forget=True)
return redirect('./load')

View File

@ -15,7 +15,6 @@
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import os
from cStringIO import StringIO
from quixote import redirect, get_publisher
from quixote.html import TemplateIO, htmltext
@ -25,6 +24,7 @@ from qommon import _
from qommon.form import *
from qommon import misc, get_cfg, ezt
from qommon.backoffice.menu import html_top
from qommon.template import Template
class TextsDirectory(Directory):
@ -51,11 +51,7 @@ class TextsDirectory(Directory):
if vars:
subst_vars.update(vars)
text_template = ezt.Template(compress_whitespace=False)
text_template.parse(text, base_format=ezt.FORMAT_HTML)
fd = StringIO()
text_template.generate(fd, subst_vars)
text = fd.getvalue()
text = Template(text, ezt_format=ezt.FORMAT_HTML).render(subst_vars)
if get_publisher().get_backoffice_root() and \
get_publisher().get_backoffice_root().is_accessible('settings'):

View File

@ -31,7 +31,6 @@ import smtplib
import socket
from cStringIO import StringIO
import ezt
try:
import docutils
@ -50,48 +49,31 @@ from publisher import get_cfg, get_logger
import errors
import tokens
from admin.emails import EmailsDirectory
from template import Template
Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')
def custom_ezt_email(key, mail_body_data, email_rcpt, **kwargs):
def custom_template_email(key, mail_body_data, email_rcpt, **kwargs):
if not EmailsDirectory.is_enabled(key):
return
mail_subject = EmailsDirectory.get_subject(key)
mail_body = EmailsDirectory.get_body(key)
if not mail_body_data:
mail_body_data = {}
if not mail_body_data.get('sitename'):
mail_body_data['sitename'] = get_cfg('misc', {}).get('sitename')
return template_email(mail_subject, mail_body, mail_body_data, email_type=key,
email_rcpt=email_rcpt, **kwargs)
return ezt_email(mail_subject, mail_body, mail_body_data, email_type = key,
email_rcpt = email_rcpt, **kwargs)
def ezt_email(subject, mail_body, mail_body_data, email_rcpt, email_type = None, **kwargs):
mail_subject_template = ezt.Template(compress_whitespace = False)
mail_subject_template.parse(subject)
def template_email(subject, mail_body, mail_body_data, email_rcpt, email_type=None, **kwargs):
data = get_publisher().substitutions.get_context_variables()
if mail_body_data:
data.update(mail_body_data)
fd = StringIO()
mail_subject_template.generate(fd, data)
real_mail_subject = fd.getvalue()
mail_body_template = ezt.Template(compress_whitespace = False)
mail_body_template.parse(mail_body)
fd = StringIO()
mail_body_template.generate(fd, data)
real_mail_body = fd.getvalue()
return email(real_mail_subject, real_mail_body, email_rcpt = email_rcpt,
email_type = email_type, **kwargs)
real_subject = Template(subject).render(data)
real_mail_body = Template(mail_body).render(data)
return email(real_subject, real_mail_body, email_rcpt=email_rcpt,
email_type=email_type, **kwargs)
def data_as_octet_stream(data, filename, **kwargs):
msg = MIMEApplication(data, **kwargs)

View File

@ -72,7 +72,6 @@ from qommon import _, ngettext
import misc
from .misc import strftime
from publisher import get_cfg
from . import ezt
QuixoteForm = Form

View File

@ -64,7 +64,7 @@ def notify_admins_user_registered(account):
'email': user.email,
}
emails.custom_ezt_email('new-registration-admin-notification', data,
emails.custom_template_email('new-registration-admin-notification', data,
admin_emails, fire_and_forget = True)
@ -368,7 +368,7 @@ class MethodDirectory(Directory):
}
try:
emails.custom_ezt_email('change-password-request', data,
emails.custom_template_email('change-password-request', data,
user.email, exclude_current_user = False)
except errors.EmailError:
form.set_error('username', _('Failed to send email (server error)'))
@ -470,7 +470,7 @@ class MethodDirectory(Directory):
'hostname': get_request().get_server(),
}
emails.custom_ezt_email('new-generated-password', data,
emails.custom_template_email('new-generated-password', data,
user.email, exclude_current_user = False)
return self.forgotten_token_end_page()
@ -619,7 +619,7 @@ class MethodDirectory(Directory):
'username': account.id,
'password': password,
}
emails.custom_ezt_email('new-account-generated-password', data,
emails.custom_template_email('new-account-generated-password', data,
user.email, fire_and_forget = True)
# XXX: display a message instead of immediate redirect ?
@ -677,7 +677,7 @@ class MethodDirectory(Directory):
'admin_email': passwords_cfg.get('admin_email', ''),
}
emails.custom_ezt_email('password-subscription-notification', data, user.email)
emails.custom_template_email('password-subscription-notification', data, user.email)
ADMIN_TITLE = N_('Username / Password')
@ -994,7 +994,7 @@ class MethodAdminDirectory(Directory):
for account in self.accounts:
if not account.get('email'):
continue
emails.custom_ezt_email('new-account-generated-password',
emails.custom_template_email('new-account-generated-password',
account, account['email'],
fire_and_forget=False)
@ -1125,7 +1125,7 @@ class MethodUserDirectory(Directory):
'password': password
}
emails.custom_ezt_email(email_key, data, self.user.email)
emails.custom_template_email(email_key, data, self.user.email)
class PasswordAuthMethod(AuthMethod):
key = 'password'
@ -1285,7 +1285,7 @@ class AccountDirectory(Directory):
if password:
data['password'] = password
emails.custom_ezt_email('new-account-approved', data, user.email)
emails.custom_template_email('new-account-approved', data, user.email)
return redirect('..')
@ -1645,7 +1645,7 @@ def handle_unused_accounts(publisher):
'username': account.id,
}
if user.email:
emails.custom_ezt_email('warning-about-unused-account', data, user.email)
emails.custom_template_email('warning-about-unused-account', data, user.email)
# XXX: notify admin too
account.warned_about_unused_account = True
account.store()
@ -1663,7 +1663,7 @@ def handle_unused_accounts(publisher):
'username': account.id,
}
if user.email:
emails.custom_ezt_email('notification-of-removed-account', data, user.email)
emails.custom_template_email('notification-of-removed-account', data, user.email)
# XXX: notify admin too

View File

@ -450,7 +450,7 @@ def ezt_raises(exception, on_parse=False):
class Template(object):
def __init__(self, value, raises=False):
def __init__(self, value, raises=False, ezt_format=ezt.FORMAT_RAW):
'''Guess kind of template (Django or ezt), and parse it'''
self.value = value
self.raises = raises
@ -469,7 +469,7 @@ class Template(object):
self.render = self.ezt_render
self.template = ezt.Template(compress_whitespace=False)
try:
self.template.parse(value)
self.template.parse(value, base_format=ezt_format)
except ezt.EZTException as e:
if raises:
ezt_raises(e, on_parse=True)

View File

@ -30,12 +30,12 @@ from quixote.html import htmltext
from qommon import _
from qommon import get_logger
from qommon import ezt
from qommon.form import (SingleSelectWidget, WidgetList, CheckboxWidget,
StringWidget, UploadWidget, WysiwygTextWidget, Upload,
UploadedFile, UploadValidationError, VarnameWidget,
RadiobuttonsWidget, PicklableUpload)
from qommon.errors import PublishError
from qommon.template import TemplateError
import qommon
from wcs.fields import SubtitleField, TitleField, CommentField, PageField
@ -402,25 +402,13 @@ class ExportToModel(WorkflowStatusItem):
return outstream
def apply_rtf_template_to_formdata(self, formdata):
process = None
if self.model_file.base_filename.endswith('.rtf'):
process = rtf_process
try:
return StringIO(template_on_formdata(formdata,
self.model_file.get_file().read(),
process=process))
except ezt.UnknownReference, e:
return StringIO(template_on_formdata(formdata, self.model_file.get_file().read(),
process=rtf_process))
except TemplateError as e:
url = formdata.get_url()
get_logger().error('error in template for export to model [%s], '
'unknown reference %s' % (url, str(e)))
raise TemplatingError(_('Error in the template, reference %s is '
'unknown') % str(e))
except ezt.EZTException, e:
url = formdata.get_url()
get_logger().error('error in template for export to model [%s], '
'model could not be generated' % url)
raise TemplatingError(_('Unknown error in the '
'template: %s') % str(e))
get_logger().error('error in template for export to model [%s]: %s' % (url, str(e)))
raise TemplatingError(_('Error in template: %s') % str(e))
def apply_od_template_to_formdata(self, formdata):
context = get_formdata_template_context(formdata)

View File

@ -18,7 +18,7 @@ import cgi
from qommon import _
from qommon.form import *
from qommon import ezt
from qommon.template import TemplateError
from qommon import get_logger
from wcs.workflows import WorkflowStatusItem, register_item_class, template_on_formdata
@ -38,7 +38,7 @@ class JournalEvolutionPart: #pylint: disable=C1001
escape_function = escape
else:
escape_function = None
self.content = template_on_formdata(formdata, message, escape_function)
self.content = template_on_formdata(formdata, message, process=escape_function)
def view(self):
if not self.content:
@ -81,9 +81,10 @@ class RegisterCommenterWorkflowStatusItem(WorkflowStatusItem):
try:
formdata.evolution[-1].add_part(JournalEvolutionPart(formdata, self.comment))
formdata.store()
except ezt.EZTException:
except TemplateError as e:
url = formdata.get_url()
get_logger().error('error in template for comment [%s], comment could not be generated' % url)
get_logger().error('error in template for comment [%s], '
'comment could not be generated: %s' % (url, str(e)))
register_item_class(RegisterCommenterWorkflowStatusItem)

View File

@ -140,7 +140,6 @@ class NamedAttachmentsSubstitutionProxy(object):
return getattr(self[0], name)
def __getitem__(self, i):
assert isinstance(i, int)
attachment = self.get_attachments()[i]
return AttachmentSubstitutionProxy(self.formdata, attachment)
@ -2158,14 +2157,16 @@ class SendmailWorkflowStatusItem(WorkflowStatusItem):
url = formdata.get_url()
try:
mail_body = template_on_formdata(formdata, self.compute(self.body, render=False))
except ezt.EZTException:
get_logger().error('error in template for email body [%s], mail could not be generated' % url)
except TemplateError as e:
get_logger().error('error in template for email body [%s], '
'mail could not be generated: %s' % (url, str(e)))
return
try:
mail_subject = template_on_formdata(formdata, self.compute(self.subject, render=False))
except ezt.EZTException:
get_logger().error('error in template for email subject [%s], mail could not be generated' % url)
except TemplateError as e:
get_logger().error('error in template for email subject [%s], '
'mail could not be generated: %s' % (url, str(e)))
return
users_cfg = get_cfg('users', {})
@ -2281,31 +2282,25 @@ def get_formdata_template_context(formdata=None, process=None):
return ctx
def template_on_html_string(template, process=None):
return template_on_formdata(None, template, process=process,
base_format=ezt.FORMAT_HTML)
def template_on_html_string(template):
return template_on_formdata(None, template, ezt_format=ezt.FORMAT_HTML)
def template_on_formdata(formdata=None, template=None, process=None,
base_format=ezt.FORMAT_RAW):
ezt_format=ezt.FORMAT_RAW):
assert template is not None
if not '[' in template:
if not Template.is_template_string(template):
# no tags, no variables: don't even process formdata
return template
context = get_formdata_template_context(formdata, process=process)
return template_on_context(context, template, process=process,
base_format=base_format)
return template_on_context(context, template, ezt_format=ezt_format)
def template_on_context(context=None, template=None, process=None,
base_format=ezt.FORMAT_RAW):
def template_on_context(context=None, template=None, ezt_format=ezt.FORMAT_RAW):
assert template is not None
if not '[' in template:
if not Template.is_template_string(template):
return template
processor = ezt.Template(compress_whitespace=False)
processor.parse(template or '', base_format=base_format)
fd = StringIO()
processor.generate(fd, context)
return fd.getvalue()
return Template(template, ezt_format=ezt_format).render(context)
class SendSMSWorkflowStatusItem(WorkflowStatusItem):
@ -2359,9 +2354,10 @@ class SendSMSWorkflowStatusItem(WorkflowStatusItem):
try:
sms_body = template_on_formdata(formdata, self.compute(self.body, render=False))
except ezt.EZTException:
except TemplateError as e:
url = formdata.get_url()
get_logger().error('error in template for sms [%s], sms could not be generated' % url)
get_logger().error('error in template for sms [%s], '
'sms could not be generated' % (url, str(e)))
return
import qommon.sms
@ -2412,9 +2408,6 @@ class DisplayMessageWorkflowStatusItem(WorkflowStatusItem):
else:
return ''
tmpl = ezt.Template()
tmpl.parse(self.message, base_format=ezt.FORMAT_HTML)
dict = {}
dict.update(get_publisher().substitutions.get_context_variables())
dict['date'] = misc.localstrftime(filled.receipt_time)
@ -2423,11 +2416,8 @@ class DisplayMessageWorkflowStatusItem(WorkflowStatusItem):
if handling_role and handling_role.details:
dict['receiver'] = handling_role.details.replace('\n', '<br />')
fd = StringIO()
tmpl.generate(fd, dict)
msg = fd.getvalue()
return Template(self.message, ezt_format=ezt.FORMAT_HTML).render(dict)
return msg
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
if 'message' in parameters: