mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-08 23:23:12 -04:00
Add a prototype email template
If the templates page contains text messages and emails then there’s two ways it could be structured: - into two sections, all text messages first, then all emails - emails and text messages interleaved, sorted by date I think the second one is better. Imagine a situation where you mostly do emails but have a few text messages. You’d have to scroll past the text messages to get to your emails. Every time. I reckon that the most commonly accessed templates will be the most recent ones.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from flask import Flask, session, Markup, render_template
|
from flask import Flask, session, Markup, escape, render_template
|
||||||
from flask._compat import string_types
|
from flask._compat import string_types
|
||||||
from flask.ext.sqlalchemy import SQLAlchemy
|
from flask.ext.sqlalchemy import SQLAlchemy
|
||||||
from flask_login import LoginManager
|
from flask_login import LoginManager
|
||||||
@@ -47,6 +47,7 @@ def create_app(config_name, config_overrides=None):
|
|||||||
|
|
||||||
application.add_template_filter(placeholders)
|
application.add_template_filter(placeholders)
|
||||||
application.add_template_filter(replace_placeholders)
|
application.add_template_filter(replace_placeholders)
|
||||||
|
application.add_template_filter(nl2br)
|
||||||
|
|
||||||
application.after_request(useful_headers_after_request)
|
application.after_request(useful_headers_after_request)
|
||||||
register_errorhandlers(application)
|
register_errorhandlers(application)
|
||||||
@@ -108,6 +109,14 @@ def placeholders(value):
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def nl2br(value):
|
||||||
|
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
|
||||||
|
|
||||||
|
result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', Markup('<br>\n'))
|
||||||
|
for p in _paragraph_re.split(escape(value)))
|
||||||
|
return Markup(result)
|
||||||
|
|
||||||
|
|
||||||
def replace_placeholders(template, values):
|
def replace_placeholders(template, values):
|
||||||
if not template:
|
if not template:
|
||||||
return template
|
return template
|
||||||
|
|||||||
24
app/assets/stylesheets/components/email-message.scss
Normal file
24
app/assets/stylesheets/components/email-message.scss
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.email-message {
|
||||||
|
|
||||||
|
margin-bottom: $gutter;
|
||||||
|
border: 1px solid $border-colour;
|
||||||
|
|
||||||
|
&-subject {
|
||||||
|
border-bottom: 1px solid $border-colour;;
|
||||||
|
padding: 10px;
|
||||||
|
@include bold-19;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body {
|
||||||
|
border-bottom: 1px solid white;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: 103px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-name {
|
||||||
|
@include bold-19;
|
||||||
|
margin: 50px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
&-name {
|
&-name {
|
||||||
@include bold-19;
|
@include bold-19;
|
||||||
margin: 0 0 5px 0;
|
margin: 50px 0 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
@import 'components/browse-list';
|
@import 'components/browse-list';
|
||||||
@import 'components/management-navigation';
|
@import 'components/management-navigation';
|
||||||
@import 'components/dropdown';
|
@import 'components/dropdown';
|
||||||
|
@import 'components/email-message';
|
||||||
|
|
||||||
@import 'views/job';
|
@import 'views/job';
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,39 @@
|
|||||||
sms_templates = [
|
templates = [
|
||||||
{
|
{
|
||||||
|
'type': 'sms',
|
||||||
|
'name': 'Confirmation',
|
||||||
|
'body': 'Lasting power of attorney: We’ve received your application. Applications take between 8 and 10 weeks to process.' # noqa
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'type': 'sms',
|
||||||
'name': 'Reminder',
|
'name': 'Reminder',
|
||||||
'body': """
|
'body': 'Vehicle tax: Your vehicle tax for ((registration number)) expires on ((date)). Tax your vehicle at www.gov.uk/vehicle-tax' # noqa
|
||||||
Vehicle tax: Your vehicle tax for ((registration number)) expires on ((date)).
|
},
|
||||||
Tax your vehicle at www.gov.uk/vehicle-tax
|
{
|
||||||
|
'type': 'sms',
|
||||||
|
'name': 'Warning',
|
||||||
|
'body': 'Vehicle tax: Your vehicle tax for ((registration number)) has expired. Tax your vehicle at www.gov.uk/vehicle-tax' # noqa
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'type': 'email',
|
||||||
|
'name': 'Application alert 06/2016',
|
||||||
|
'subject': 'Your lasting power of attorney application',
|
||||||
|
'body': """Dear ((name)),
|
||||||
|
|
||||||
|
When you’ve made your lasting power of attorney (LPA), you need to register it \
|
||||||
|
with the Office of the Public Guardian (OPG).
|
||||||
|
|
||||||
|
You can apply to register your LPA yourself if you’re able to make your own decisions.
|
||||||
|
|
||||||
|
Your attorney can also register it for you. You’ll be told if they do and you can \
|
||||||
|
object to the registration.
|
||||||
|
|
||||||
|
It takes between 8 and 10 weeks to register an LPA if there are no mistakes in the application.
|
||||||
"""
|
"""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'Warning',
|
'type': 'sms',
|
||||||
'body': """
|
'name': 'Air quality alert',
|
||||||
Vehicle tax: Your vehicle tax for ((registration number)) has expired.
|
'body': 'Air pollution levels will be ((level)) in ((region)) tomorrow.'
|
||||||
Tax your vehicle at www.gov.uk/vehicle-tax
|
|
||||||
"""
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
email_templates = [
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ from app.main import main
|
|||||||
from app.main.forms import CsvUploadForm
|
from app.main.forms import CsvUploadForm
|
||||||
from app.main.uploader import s3upload
|
from app.main.uploader import s3upload
|
||||||
|
|
||||||
from ._templates import sms_templates
|
from ._templates import templates
|
||||||
|
|
||||||
|
sms_templates = [
|
||||||
|
template for template in templates if template['type'] == 'sms'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<int:service_id>/sms/send", methods=['GET', 'POST'])
|
@main.route("/services/<int:service_id>/sms/send", methods=['GET', 'POST'])
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from flask_login import login_required
|
|||||||
from app.main import main
|
from app.main import main
|
||||||
from app.main.forms import TemplateForm
|
from app.main.forms import TemplateForm
|
||||||
|
|
||||||
from ._templates import sms_templates, email_templates
|
from ._templates import templates
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<int:service_id>/templates")
|
@main.route("/services/<int:service_id>/templates")
|
||||||
@@ -13,8 +13,7 @@ def manage_templates(service_id):
|
|||||||
return render_template(
|
return render_template(
|
||||||
'views/manage-templates.html',
|
'views/manage-templates.html',
|
||||||
service_id=service_id,
|
service_id=service_id,
|
||||||
sms_templates=sms_templates,
|
templates=templates,
|
||||||
email_templates=email_templates
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -35,14 +34,14 @@ def add_template(service_id):
|
|||||||
return redirect(url_for('.manage_templates', service_id=service_id))
|
return redirect(url_for('.manage_templates', service_id=service_id))
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<int:service_id>/templates/<template_id>", methods=['GET', 'POST'])
|
@main.route("/services/<int:service_id>/templates/<int:template_id>", methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def edit_template(service_id, template_id):
|
def edit_template(service_id, template_id):
|
||||||
|
|
||||||
form = TemplateForm()
|
form = TemplateForm()
|
||||||
|
|
||||||
form.template_name.data = 'Reminder'
|
form.template_name.data = templates[template_id - 1]['name']
|
||||||
form.template_body.data = 'Vehicle tax: Your vehicle tax for ((registration number)) expires on ((date)). Tax your vehicle at www.gov.uk/vehicle-tax' # noqa
|
form.template_body.data = templates[template_id - 1]['body']
|
||||||
|
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
return render_template(
|
return render_template(
|
||||||
|
|||||||
19
app/templates/components/email-message.html
Normal file
19
app/templates/components/email-message.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{% macro email_message(subject, body, name=None, edit_link=None) %}
|
||||||
|
{% if name %}
|
||||||
|
<h3 class="email-message-name">
|
||||||
|
{% if edit_link %}
|
||||||
|
<a href="{{ edit_link }}">{{ name }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ name }}
|
||||||
|
{% endif %}
|
||||||
|
</h3>
|
||||||
|
{% endif %}
|
||||||
|
<div class="email-message">
|
||||||
|
<div class="email-message-subject">
|
||||||
|
{{ subject|placeholders }}
|
||||||
|
</div>
|
||||||
|
<div class="email-message-body">
|
||||||
|
{{ body|nl2br|placeholders }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
{% macro sms_message(body, recipient=None, name=None, edit_link=None) %}
|
{% macro sms_message(body, recipient=None, name=None, edit_link=None) %}
|
||||||
{% if name %}
|
{% if name %}
|
||||||
<h3 class="sms-message-name">
|
<h3 class="sms-message-name">
|
||||||
{{ name }}
|
|
||||||
{% if edit_link %}
|
{% if edit_link %}
|
||||||
<a href="{{ edit_link }}">Edit</a>
|
<a href="{{ edit_link }}">{{ name }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h3>
|
</h3>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<li><a href="{{ url_for('.sendsms', service_id=123) }}">Send text messages</a></li>
|
<li><a href="{{ url_for('.sendsms', service_id=123) }}">Send text messages</a></li>
|
||||||
<li><a href="{{ url_for('.sendemail', service_id=123) }}">Send emails</a></li>
|
<li><a href="{{ url_for('.sendemail', service_id=123) }}">Send emails</a></li>
|
||||||
<li><a href="{{ url_for('.showjobs', service_id=123) }}">Activity</a></li>
|
<li><a href="{{ url_for('.showjobs', service_id=123) }}">Activity</a></li>
|
||||||
<li><a href="{{ url_for('.manage_templates', service_id=123) }}">Manage templates</a></li>
|
<li><a href="{{ url_for('.manage_templates', service_id=123) }}">Templates</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('.apikeys', service_id=123) }}">API keys and documentation</a></li>
|
<li><a href="{{ url_for('.apikeys', service_id=123) }}">API keys and documentation</a></li>
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ GOV.UK Notify | Edit template
|
|||||||
{{ textbox(form.template_body, highlight_tags=True) }}
|
{{ textbox(form.template_body, highlight_tags=True) }}
|
||||||
{{ page_footer(
|
{{ page_footer(
|
||||||
'Save and continue',
|
'Save and continue',
|
||||||
back_link=url_for('.dashboard', service_id=service_id),
|
back_link=url_for('.manage_templates', service_id=service_id),
|
||||||
back_link_text='Back to manage templates'
|
back_link_text='Back to templates'
|
||||||
) }}
|
) }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
{% extends "withnav_template.html" %}
|
{% extends "withnav_template.html" %}
|
||||||
{% from "components/sms-message.html" import sms_message %}
|
{% from "components/sms-message.html" import sms_message %}
|
||||||
|
{% from "components/email-message.html" import email_message %}
|
||||||
|
{% from "components/browse-list.html" import browse_list %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
GOV.UK Notify | Manage templates
|
GOV.UK Notify | Manage templates
|
||||||
@@ -7,28 +9,41 @@ GOV.UK Notify | Manage templates
|
|||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
|
|
||||||
<h1 class="heading-xlarge">Manage templates</h1>
|
|
||||||
|
|
||||||
<h2 class="heading-medium">SMS templates</h2>
|
|
||||||
|
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="column-two-thirds">
|
<div class="column-two-thirds">
|
||||||
|
|
||||||
{% for template in sms_templates %}
|
<h1 class="heading-xlarge">Templates</h1>
|
||||||
{{ sms_message(
|
|
||||||
template.body,
|
{% for template in templates %}
|
||||||
name=template.name,
|
{% if template.type == 'sms' %}
|
||||||
edit_link=url_for('.edit_template', service_id=service_id, template_id=1)
|
{{ sms_message(
|
||||||
) }}
|
template.body,
|
||||||
|
name=template.name,
|
||||||
|
edit_link=url_for('.edit_template', service_id=service_id, template_id=loop.index)
|
||||||
|
) }}
|
||||||
|
{% elif template.type == 'email' %}
|
||||||
|
{{ email_message(
|
||||||
|
template.subject,
|
||||||
|
template.body,
|
||||||
|
name=template.name,
|
||||||
|
edit_link=url_for('.edit_template', service_id=service_id, template_id=loop.index)
|
||||||
|
) }}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="column-one-third">
|
||||||
|
{{ browse_list([
|
||||||
|
{
|
||||||
|
'title': 'New text message template',
|
||||||
|
'link': url_for('.add_template', service_id=service_id)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'New email template',
|
||||||
|
'link': url_for('.add_template', service_id=service_id)
|
||||||
|
}
|
||||||
|
]) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
|
||||||
<a class="button" href="{{ url_for('.add_template', service_id=service_id) }}" role="button">Add a new message template</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user