From e8b1055abcb6e0a4be6e438e55c3dbe1fdf02853 Mon Sep 17 00:00:00 2001 From: Alex Gibson Date: Tue, 1 Oct 2024 16:12:25 +0100 Subject: [PATCH] Add newsletter form to nothing-personal page (Fixes #15218) (#15223) --- .../includes/browser-macro.html | 3 ++- .../firefox/nothing-personal/index.html | 18 ++++++++++++++++++ bedrock/newsletter/forms.py | 11 +++++++++-- bedrock/newsletter/templatetags/helpers.py | 3 ++- bedrock/newsletter/tests/test_footer_form.py | 17 +++++++++++++++++ .../css/firefox/nothing-personal/_browser.scss | 2 +- .../css/firefox/nothing-personal/_header.scss | 8 +++++++- .../firefox/nothing-personal/_primary-cta.scss | 2 +- .../firefox/nothing-personal/_sticky-note.scss | 4 ++-- media/css/firefox/nothing-personal/styles.scss | 2 +- 10 files changed, 60 insertions(+), 10 deletions(-) diff --git a/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html b/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html index 2168cc53b87..45aa055cfe6 100644 --- a/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html +++ b/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html @@ -5,11 +5,12 @@ #} {% macro browser_border( + id=None, class=None, heading=None, aria_label=None ) -%} -
+
{% if heading and aria_label %}

{{ heading }}

diff --git a/bedrock/firefox/templates/firefox/nothing-personal/index.html b/bedrock/firefox/templates/firefox/nothing-personal/index.html index 9e4af0d4342..21b276d53b8 100644 --- a/bedrock/firefox/templates/firefox/nothing-personal/index.html +++ b/bedrock/firefox/templates/firefox/nothing-personal/index.html @@ -12,6 +12,7 @@ {% block page_css %} {{ css_bundle('firefox-nothing-personal') }} + {{ css_bundle('protocol-newsletter') }} {% endblock %} {% block page_title_prefix %}Nothing Personal{% endblock %} @@ -181,6 +182,22 @@
Ok, what’s the privacy-catch?
{% endcall %} + + {% call browser_border(id="newsletter-signup", class='mzp-l-content mzp-t-content-md mzp-t-content-nospace', heading='Newsletter') %} +
+

Sign up for our newsletter

+ + {{ email_newsletter_form( + include_title=False, + include_language=False, + include_country=False, + newsletters='mozilla-and-you, nothing-personal-college-interest', + multi_opt_in_required=True + )}} + +

By subscribing, you’ll receive Mozilla updates, plus exclusive college-related content if you opt in. You may unsubscribe from either at any time.

+
+ {% endcall %}
@@ -219,4 +236,5 @@
Ok, what’s the privacy-catch?
{% block js %} {{ js_bundle('firefox-nothing-personal') }} + {{ js_bundle('newsletter') }} {% endblock %} diff --git a/bedrock/newsletter/forms.py b/bedrock/newsletter/forms.py index e1413e91f58..010a760e3a4 100644 --- a/bedrock/newsletter/forms.py +++ b/bedrock/newsletter/forms.py @@ -175,6 +175,7 @@ class NewsletterFooterForm(forms.Form): choice_labels = { "mozilla-foundation": ftl("multi-newsletter-form-checkboxes-label-mozilla"), "mozilla-and-you": ftl("multi-newsletter-form-checkboxes-label-firefox"), + "nothing-personal-college-interest": "Exclusive college-related content", # issue 15218. } email = forms.EmailField(widget=EmailInput(attrs={"required": "required", "data-testid": "newsletter-email-input"})) @@ -188,7 +189,7 @@ class NewsletterFooterForm(forms.Form): # has to take a newsletters argument so it can figure # out which languages to list in the form. - def __init__(self, newsletters, locale, data=None, *args, **kwargs): + def __init__(self, newsletters, locale, data=None, multi_opt_in_required=False, *args, **kwargs): regions = product_details.get_regions(locale) regions = sorted(iter(regions.items()), key=itemgetter(1)) @@ -201,6 +202,7 @@ def __init__(self, newsletters, locale, data=None, *args, **kwargs): # form validation will work with submitted data newsletters = ["mozilla-and-you"] + is_multi_newsletter = len(newsletters) > 1 lang = locale.lower() if "-" in lang: lang, country = lang.split("-", 1) @@ -231,7 +233,12 @@ def __init__(self, newsletters, locale, data=None, *args, **kwargs): lang_label = ftl_lazy("newsletter-form-select-language", fallback="newsletter-form-available-languages") self.fields["lang"] = forms.TypedChoiceField(widget=lang_widget, choices=lang_choices, initial=lang, required=False, label=lang_label) self.fields["newsletters"].choices = [(n, self.choice_labels.get(n, n)) for n in newsletters] - self.fields["newsletters"].initial = newsletters + + # Automatically check newsletter choices unless opt-in is explicitly required. + if is_multi_newsletter and multi_opt_in_required: + self.fields["newsletters"].initial = None + else: + self.fields["newsletters"].initial = newsletters def clean_newsletters(self): return validate_newsletters(self.cleaned_data["newsletters"]) diff --git a/bedrock/newsletter/templatetags/helpers.py b/bedrock/newsletter/templatetags/helpers.py index cefe879311a..54a7d1fe0df 100644 --- a/bedrock/newsletter/templatetags/helpers.py +++ b/bedrock/newsletter/templatetags/helpers.py @@ -38,6 +38,7 @@ def email_newsletter_form( spinner_color=None, email_label=None, email_placeholder=None, + multi_opt_in_required=False, # switches multi-newsletter forms to be opt-in rather than pre-checked. ): request = ctx["request"] context = ctx.get_all() @@ -49,7 +50,7 @@ def email_newsletter_form( form = ctx.get("newsletter_form", None) if not form: - form = NewsletterFooterForm(newsletters, get_locale(request)) + form = NewsletterFooterForm(newsletters, get_locale(request), multi_opt_in_required=multi_opt_in_required) if isinstance(newsletters, list): newsletters = ", ".join(newsletters) diff --git a/bedrock/newsletter/tests/test_footer_form.py b/bedrock/newsletter/tests/test_footer_form.py index 9406077b460..12ddce20add 100644 --- a/bedrock/newsletter/tests/test_footer_form.py +++ b/bedrock/newsletter/tests/test_footer_form.py @@ -60,3 +60,20 @@ def test_language_selected(self): resp = self.client.get(reverse(self.view_name)) doc = pq(resp.content) assert doc('#id_lang option[selected="selected"]').val() == "" + + @override_settings(DEV=True) + def test_newsletters_selected(self): + """ + By default both newsletters should be checked. + """ + with self.activate_locale("en-US"): + resp = self.client.get(reverse(self.view_name)) + doc = pq(resp.content) + assert doc('#id_newsletters_0[checked="checked"]').length == 1 + assert doc('#id_newsletters_1[checked="checked"]').length == 1 + + with self.activate_locale("en-US"): + resp = self.client.get(reverse("firefox.nothing-personal.index")) + doc = pq(resp.content) + assert doc('#id_newsletters_0[checked="checked"]').length == 0 + assert doc('#id_newsletters_1[checked="checked"]').length == 0 diff --git a/media/css/firefox/nothing-personal/_browser.scss b/media/css/firefox/nothing-personal/_browser.scss index fea36598d6f..6623945f840 100644 --- a/media/css/firefox/nothing-personal/_browser.scss +++ b/media/css/firefox/nothing-personal/_browser.scss @@ -102,10 +102,10 @@ .c-browser-window-top { h2 { - @include text-title-xl; line-height: 1; margin: 0; padding-right: $spacing-lg; + @include text-title-xl; } &::after { diff --git a/media/css/firefox/nothing-personal/_header.scss b/media/css/firefox/nothing-personal/_header.scss index c48f2207dd8..cae144544c0 100644 --- a/media/css/firefox/nothing-personal/_header.scss +++ b/media/css/firefox/nothing-personal/_header.scss @@ -2,6 +2,12 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. +@media (prefers-reduced-motion: no-preference) { + html { + scroll-padding-top: 120px; /* height of sticky header */ + } +} + .c-page-header { background-color: $browser-background; border-bottom: $border-black; @@ -56,11 +62,11 @@ justify-self: end; p { - @include text-body-lg; display: block; font-family: 'Fira Mono', 'Andale Mono', monospace; font-weight: 500; margin: 0 $spacing-md 0 0; + @include text-body-lg; } } } diff --git a/media/css/firefox/nothing-personal/_primary-cta.scss b/media/css/firefox/nothing-personal/_primary-cta.scss index 67182c7276d..68b7a5410d6 100644 --- a/media/css/firefox/nothing-personal/_primary-cta.scss +++ b/media/css/firefox/nothing-personal/_primary-cta.scss @@ -121,7 +121,6 @@ html.android { .mzp-c-button, #protocol-nav-download-firefox > .mzp-c-button { - @include text-body-lg; padding: $spacing-sm $spacing-lg; background-color: $color-yellow-20; background-image: linear-gradient(to right,$color-yellow-20, $color-orange-50, $color-yellow-20, $color-yellow-20); @@ -130,6 +129,7 @@ html.android { color: $color-black; border-color: $color-black; transition: all 0.3s ease-out; + @include text-body-lg; @media (prefers-reduced-motion: reduce) { background-image: linear-gradient(to right,$color-yellow-20, $color-orange-50); diff --git a/media/css/firefox/nothing-personal/_sticky-note.scss b/media/css/firefox/nothing-personal/_sticky-note.scss index 7f7f9fe7fb1..483dcef66ca 100644 --- a/media/css/firefox/nothing-personal/_sticky-note.scss +++ b/media/css/firefox/nothing-personal/_sticky-note.scss @@ -3,7 +3,6 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. .c-sticky-note { - @include text-body-lg; background-image: url('/media/img/firefox/nothing-personal/sticky-note-bg.svg'); background-repeat: no-repeat; background-size: contain; @@ -13,6 +12,7 @@ padding: $spacing-xl; transform: rotate(11deg); text-align: center; + @include text-body-lg; &.c-detached-sticky { position: relative; @@ -67,11 +67,11 @@ margin-bottom: 0; a { - @include text-body-lg; border: 0; background: transparent; color: $color-black; padding: 0; + @include text-body-lg; &:hover, &:focus, diff --git a/media/css/firefox/nothing-personal/styles.scss b/media/css/firefox/nothing-personal/styles.scss index 4698656d81e..0bbb5fb412f 100644 --- a/media/css/firefox/nothing-personal/styles.scss +++ b/media/css/firefox/nothing-personal/styles.scss @@ -86,8 +86,8 @@ $mq-tad-smaller-sm: 455px; } .c-sign-off { - @include text-title-xs; margin: $layout-lg 0; + @include text-title-xs; .c-nothing-personal { padding: 12px;