Skip to content

Commit

Permalink
3005: adding a banner snippet in the header that appears on every pag…
Browse files Browse the repository at this point in the history
…e of the site (#2144)

* Add notification - semi working

* format models

* Format migration

* banner works

* format migration

* format

* Remove console output

* fix

* comments for close button sizing and placement
  • Loading branch information
collinpreston authored Mar 28, 2024
1 parent cd457e4 commit 2c79e46
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 13 deletions.
29 changes: 29 additions & 0 deletions cms/migrations/0035_sitebanner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.23 on 2024-03-27 14:37

from django.db import migrations, models
import wagtail.fields


class Migration(migrations.Migration):

dependencies = [
("cms", "0034_add_search_image_to_course_and_program_page"),
]

operations = [
migrations.CreateModel(
name="SiteBanner",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("message", wagtail.fields.RichTextField(max_length=255)),
],
),
]
15 changes: 15 additions & 0 deletions cms/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from wagtail.models import Page
from wagtail.search import index
from wagtailmetadata.models import MetadataPageMixin
from wagtail.snippets.models import register_snippet

from cms.blocks import (
CourseRunCertificateOverrides,
Expand Down Expand Up @@ -1682,3 +1683,17 @@ def serve(self, request, *args, **kwargs):
designed to be viewed on their own so we raise a 404 if someone tries to access their slug.
"""
raise Http404


@register_snippet
class SiteBanner(models.Model):
"""Snippet model for showing site banner."""

message = RichTextField(
max_length=255, features=["bold", "italic", "link", "document-link"]
)

panels = [FieldPanel("message")]

def __str__(self):
return str(self.message)
50 changes: 50 additions & 0 deletions frontend/public/scss/banner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.banners {
position: relative;
z-index: 1;

// HACK: Using this rule to get around styling issues with <p> elements in the
// notification content (notification content in Wagtail is configured to be HTML,
// and Wagtail wraps content in a <p> tag by default when you use the editor).
&.site-wide {
p {
margin: 0;
}
}

// Django-rendered implementation
.banner {
background: $primary;
text-align: center;
color: white;
height: 60px;
padding: 15px 20px 15px 20px;
background: linear-gradient(180deg, #A31F34 0%, #700934 100%);

font-family: Inter;
font-size: 18px;
font-weight: 500;

p a {
color: white;
text-decoration: underline;
background-color: transparent;
}

}

.close-banner {
text-decoration: none;
color: white;
float: right;
height: 30px;
display: flex;
align-items: center;
justify-content: center;

&:after {
content: "cancel";
font-family: Material Icons;
font-size: 30px;
}
}
}
1 change: 1 addition & 0 deletions frontend/public/scss/layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
@import "home-page/home-page-contact-row";
@import "product-page/program-courses.scss";
@import "cards.scss";
@import "banner";

body {
font-family: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
Expand Down
22 changes: 22 additions & 0 deletions frontend/public/src/banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*eslint-env jquery*/
/*eslint semi: ["error", "always"]*/

function renderSiteBanner() {
const bannerId = $(".banner").data("banner-id");
if (bannerId) {
if (localStorage.getItem("dismissedbanner") !== bannerId.toString()) {
$(".banners").removeClass("d-none");
}
}
}

export default function banner() {
renderSiteBanner();

$(".banners").on("click", ".close-banner", function(e) {
e.preventDefault();
const $banner = $(this).closest(".banner");
localStorage.setItem("dismissedbanner", $banner.data("banner-id"));
$banner.remove();
});
}
5 changes: 5 additions & 0 deletions frontend/public/src/entry/django.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import "video.js"
import "videojs-youtube/dist/Youtube"
import "slick-carousel"
import $ from "jquery"
import banner from "../banner.js"

document.addEventListener("DOMContentLoaded", function() {
banner()
})
$(document).ready(function() {
$(".dates-tooltip").popover({
sanitize: false,
Expand Down
11 changes: 6 additions & 5 deletions main/templates/base.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load static hijack_tags js_interop %}
{% load wagtailcore_tags startswith noindex_meta %}
{% load wagtailcore_tags startswith noindex_meta banner %}
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html lang="en">
Expand Down Expand Up @@ -35,10 +35,11 @@
{% include "partials/gtm_body.html" %}
{% hijack_notification %}
{% if not request.path|startswith:'/certificate/' %}
{% block headercontent %}
<div id="header"></div>
{% render_bundle 'header' %}
{% endblock %}
{% banner %}
{% block headercontent %}
<div id="header"></div>
{% render_bundle 'header' %}
{% endblock %}
{% endif %}
{% block content %}
{% block banner %}
Expand Down
8 changes: 8 additions & 0 deletions main/templates/partials/banner.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="banners site-wide d-none">
{% if banner %}
<div class="banner" data-banner-id="{{ banner.id }}">
<a href="#" class="close-banner"></a>
{{ banner|safe }}
</div>
{% endif %}
</div>
8 changes: 0 additions & 8 deletions main/templates/partials/notifications.html

This file was deleted.

16 changes: 16 additions & 0 deletions main/templatetags/banner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""Templatetags for rendering site banner"""

from django import template
from cms.models import SiteBanner

register = template.Library()


@register.inclusion_tag("../templates/partials/banner.html", takes_context=True)
def banner(context):
"""Return request context and banner."""

return {
"banner": SiteBanner.objects.order_by("-id").first(),
"request": context["request"],
}

0 comments on commit 2c79e46

Please sign in to comment.