Skip to content
Snippets Groups Projects
Commit 07818d3c authored by Todd Dembrey's avatar Todd Dembrey
Browse files

Create the mailchimp newsletter form

parent 8bd91a64
No related branches found
No related tags found
No related merge requests found
Showing
with 249 additions and 42 deletions
from django.apps import AppConfig
class MailchimpConfig(AppConfig):
name = 'mailchimp'
from django import forms
class NewsletterForm(forms.Form):
email = forms.EmailField(label='Email Address')
fname = forms.CharField(label='First Name', required=False)
lname = forms.CharField(label='Last Name', required=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
class_name = 'input--secondary'
if field.required:
class_name += ' input__secondary--required'
field.widget.attrs = {'class': class_name}
from django.db import models
# Create your models here.
<h4>Get the latest internet freedom news</h4>
<form class="form" action="{% url "newsletter:subscribe" %}" method="post">
<div>
{% for field in newsletter_form %}
<label for="{{ field.id_for_label }}"{% if field.field.required %} required{% endif %}>
<span>{{ field.label }}</span>
{% if field.field.required %}
<span class="form__required">*</span>
{% endif %}
{{ field }}
{% endfor %}
<div class="form-actions form-wrapper">
<input type="submit" value="Sign up" class="form-submit link link--button-transparent link--footer-signup">
</div>
</div>
</form>
from unittest import mock
import re
from django.test import override_settings, TestCase
from django.urls import reverse
import responses
class TestNewsletterView(TestCase):
url = reverse('newsletter:subscribe')
def setUp(self):
self.origin = 'https://testserver/'
self.client.defaults = {'HTTP_ORIGIN': self.origin}
def test_redirected_home_if_get(self):
response = self.client.get(self.url, secure=True, follow=True)
request = response.request
self.assertRedirects(response, '{}://{}/'.format(request['wsgi.url_scheme'], request['SERVER_NAME']))
def test_can_subscribe(self):
response = self.client.post(self.url, data={'email': 'email@email.com'}, secure=True, follow=True)
self.assertRedirects(response, self.origin)
messages = list(response.context['messages'])
self.assertEqual(len(messages), 1)
self.assertIn('Thank you', str(messages[0]))
def test_error_in_form(self):
response = self.client.post(self.url, data={'email': 'email_is_bad.com'}, secure=True, follow=True)
self.assertRedirects(response, self.origin)
messages = list(response.context['messages'])
self.assertEqual(len(messages), 1)
self.assertIn('errors with', str(messages[0]))
@override_settings(
MAILCHIMP_API_KEY='a' * 32,
MAILCHIMP_LIST_ID='12345'
)
@responses.activate
@mock.patch('opentech.public.mailchimp.views.logging')
def test_error_with_mailchimp(self, logging):
any_url = re.compile(".")
# Copied from the mailchimp playground
response_data = {
"title": "Invalid Resource",
"status": 400,
"detail": "Please provide a valid email address.",
}
responses.add(responses.POST, any_url, json=response_data, status=400)
response = self.client.post(self.url, data={'email': 'email@email.com'}, secure=True, follow=True)
self.assertRedirects(response, self.origin)
messages = list(response.context['messages'])
self.assertEqual(len(messages), 1)
self.assertIn('problem', str(messages[0]))
logging.info.assert_called_once_with(response_data)
from django.urls import path
from .views import MailchimpSubscribeView
app_name = 'newsletter'
urlpatterns = [
path('subscribe/', MailchimpSubscribeView.as_view(), name='subscribe')
]
import logging
from django.conf import settings
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import RedirectView
from django.views.generic.edit import FormMixin
from mailchimp3 import MailChimp
from .forms import NewsletterForm
logging.getLogger('opentech')
@method_decorator(csrf_exempt, name='dispatch')
class MailchimpSubscribeView(FormMixin, RedirectView):
form_class = NewsletterForm
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_invalid(self, form):
messages.error(self.request, _('Sorry, there were errors with your form.') + str(form.errors))
return HttpResponseRedirect(self.get_success_url())
def form_valid(self, form):
mailchimp_enabled = settings.MAILCHIMP_API_KEY and settings.MAILCHIMP_LIST_ID
dummy_key = 'a' * 32
client = MailChimp(mc_api=settings.MAILCHIMP_API_KEY or dummy_key, timeout=5.0, enabled=mailchimp_enabled)
data = form.cleaned_data.copy()
email = data.pop('email')
data = {
k.upper(): v
for k, v in data.items()
}
try:
client.lists.members.create(settings.MAILCHIMP_LIST_ID, {
'email_address': email,
'status': 'pending',
'merge_fields': data,
})
except Exception as e:
messages.warning(self.request, _('Sorry, there has been an problem. Please try again later.'))
logging.info(e.args[0])
else:
messages.success(self.request, _('Thank you for subscribing'))
return super().form_valid(form)
def get_success_url(self):
# Go back to where you came from
return self.request.META['HTTP_ORIGIN']
def get_redirect_url(self):
# We don't know where you came from, go home
return '/'
from django.urls import path
from django.urls import include, path
from .esi import views as esi_views
from .search import views as search_views
from .mailchimp import urls as newsletter_urls
urlpatterns = [
path('esi/<slug>/', esi_views.esi, name='esi'),
path('search/', search_views.search, name='search'),
path('newsletter/', include(newsletter_urls))
]
from opentech.apply.home.models import ApplyHomePage
from opentech.public.home.models import HomePage
from opentech.public.mailchimp.forms import NewsletterForm
def global_vars(request):
return {
'APPLY_SITE': ApplyHomePage.objects.first().get_site(),
'PUBLIC_SITE': HomePage.objects.first().get_site(),
'newsletter_form': NewsletterForm()
}
......@@ -29,6 +29,7 @@ INSTALLED_APPS = [
'opentech.public.esi',
'opentech.public.funds',
'opentech.public.home',
'opentech.public.mailchimp',
'opentech.public.navigation',
'opentech.public.news',
'opentech.public.people',
......@@ -371,3 +372,7 @@ if 'REDIS_URL' in env:
CELERY_BROKER_URL = env.get('REDIS_URL')
else:
CELERY_TASK_ALWAYS_EAGER = True
MAILCHIMP_API_KEY = env.get('MAILCHIMP_API_KEY')
MAILCHIMP_LIST_ID = env.get('MAILCHIMP_LIST_ID')
......@@ -155,7 +155,7 @@
input[type='text']:not(.input--secondary),
input[type='date'],
input[type='time'],
input[type='email'],
input[type='email']:not(.input--secondary),
input[type='number'],
input[type='password'],
input[type='datetime-local'] {
......
.messages {
position: relative;
right: 50%;
left: 50%;
width: 100vw;
margin-right: -50vw;
margin-left: -50vw;
&__text {
position: relative;
max-height: 1000px;
padding: 15px;
padding-right: 35px;
border: solid 1px;
&--info , &--success {
background: $color--mint;
border-color: darken($color--mint, 20%);
}
&--warning {
font-weight: bold;
color: $color--white;
background: $color--error;
border-color: darken($color--error, 20%);
}
&--hide {
max-height: 0;
padding-top: 0;
padding-bottom: 0;
border: 0 none;
transition: all $transition; // sass-lint:disable-line no-transition-all
transform-origin: top;
}
}
&__close {
position: absolute;
top: 15px;
right: 15px;
}
}
......@@ -45,16 +45,18 @@
}
}
input[type='text'] {
width: 100%;
max-width: 390px;
margin-bottom: 1rem;
color: $color--white;
background: transparent;
border-top: 0;
border-right: 0;
border-bottom: 4px solid $color--light-blue;
border-left: 0;
input{
&[type='text'], &[type='email'] {
width: 100%;
max-width: 390px;
margin-bottom: 1rem;
color: $color--white;
background: transparent;
border-top: 0;
border-right: 0;
border-bottom: 4px solid $color--light-blue;
border-left: 0;
}
}
label {
......
......@@ -28,6 +28,7 @@
@import 'components/list';
@import 'components/listing';
@import 'components/media-box';
@import 'components/messages';
@import 'components/nav';
@import 'components/responsive-object';
@import 'components/rich-text';
......@@ -40,4 +41,3 @@
@import 'layout/sidebar';
// Pages
......@@ -153,34 +153,7 @@
<footer class="footer">
<div class="grid grid--two wrapper wrapper--large">
<div class="footer__inner">
<h4>Get the latest internet freedom news</h4>
<form class="form">
<div>
<div class="mailchimp-signup-subscribe-form-description"></div>
<div id="mailchimp-newsletter-32632431e3-mergefields" class="mailchimp-newsletter-mergefields">
<div class="form-item form-type-textfield form-item-mergevars-EMAIL">
<label for="edit-mergevars-email">Email Address <span class="form-required" title="This field is required.">*</span></label>
<input type="text" id="edit-mergevars-email" name="mergevars[EMAIL]" value="" size="25" maxlength="128" class="form-text required input--secondary">
</div>
<div class="form-item form-type-textfield form-item-mergevars-FNAME">
<label for="edit-mergevars-fname">First Name </label>
<input type="text" id="edit-mergevars-fname" name="mergevars[FNAME]" value="" size="25" maxlength="128" class="form-text input--secondary">
</div>
<div class="form-item form-type-textfield form-item-mergevars-LNAME">
<label for="edit-mergevars-lname">Last Name </label>
<input type="text" id="edit-mergevars-lname" name="mergevars[LNAME]" value="" size="25" maxlength="128" class="form-text input--secondary">
</div>
</div>
<input type="hidden" name="form_build_id" value="form-2Dy9x5istHLUmufjcHabtyuZ_niL-RlfSoHBIq39hpI">
<input type="hidden" name="form_id" value="mailchimp_signup_subscribe_block_otf_newsletter_form">
<div class="form-actions form-wrapper" id="edit-actions--3">
<input type="submit" id="edit-submit--3" name="op" value="Sign up" class="form-submit link link--button-transparent link--footer-signup">
</div>
</div>
</form>
{% include "mailchimp/newsletter_signup.html" %}
</div>
<div class="footer__inner">
......
......@@ -18,7 +18,7 @@ celery==4.2.1
factory_boy==2.9.2
# wagtail_factories - waiting on merge and release form master branch
git+git://github.com/mvantellingen/wagtail-factories.git#egg=wagtail_factories
responses == 0.9.0
responses==0.9.0
flake8
......@@ -33,3 +33,4 @@ whitenoise==2.0.4
uwsgi==2.0.15
ConcurrentLogHandler==0.9.1
raven==6.9.0
mailchimp3==3.0.4
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment