aboutsummaryrefslogtreecommitdiff
path: root/layouts/partials/consent.html
diff options
context:
space:
mode:
authorFrank Blechschmidt <contact@frank-blechschmidt.com>2023-05-22 15:58:05 -0700
committerFrank Blechschmidt <contact@frank-blechschmidt.com>2023-05-22 16:03:20 -0700
commitd8bc79ad2dfb4d70bfe64fa2f349398073b1b0a2 (patch)
tree342032a176d9f0d88e11012b433e93e7f4c14af6 /layouts/partials/consent.html
parentbbc9b60f3ac541d1661f7447e1568d76c419d4f9 (diff)
Add support for cookie consent and with GA4
Diffstat (limited to 'layouts/partials/consent.html')
-rw-r--r--layouts/partials/consent.html170
1 files changed, 170 insertions, 0 deletions
diff --git a/layouts/partials/consent.html b/layouts/partials/consent.html
new file mode 100644
index 0000000..2f9181d
--- /dev/null
+++ b/layouts/partials/consent.html
@@ -0,0 +1,170 @@
+{{/* Based on https://hugocodex.org/add-ons/cookie-consent/ */}}
+
+<style>
+ #consent-notice {padding: 0.25rem 0; display: none; text-align: center; position: fixed; bottom: 0; width: 100%; background: #222;}
+ #consent-notice span {margin-right: 1rem; color: rgba(255,255,255,0.8);}
+ #consent-notice button {cursor: pointer; display: inline-block; width: auto; }
+ #consent-notice span a {color: inherit; text-decoration: underline; text-decoration-color: rgba(255,255,255,0.5);}
+ #consent-notice button.btn {margin-left: 0.5rem;}
+ #consent-notice button.btn.manage-consent {background: rgba(255,255,255,0.8); font-weight: normal;}
+ #consent-notice button.btn.deny-consent, #consent-notice button.btn.approve-consent {background: rgba(125,125,125,0.8); font-weight: normal; color: rgba(255,255,255,0.8);}
+
+ #consent-overlay {position: fixed; left: 0; top: 0; width: 100%; height: 100vh; display: none; background: rgba(0,0,0,0.75); z-index: 999999; overflow: auto; cursor: pointer;}
+ #consent-overlay.active {display: flex;}
+ #consent-overlay > div {background: white; width: 100%; max-width: 30rem; padding: 1.75rem; margin: auto; cursor: initial;}
+ #consent-overlay > div > div {display: flex; align-items: flex-start; margin-bottom: 1rem;}
+ #consent-overlay > div > div:last-child {margin: 0;}
+ #consent-overlay h5 {padding-top: 0;}
+ #consent-overlay input {margin: 0.4rem;}
+ #consent-overlay label {display: block;}
+ #consent-overlay .btn {margin-right: 0.5rem;}
+ #consent-overlay button.btn.save-consent {background: rgba(125,125,125,0.8); font-weight: normal; color: rgba(255,255,255,0.8);}
+ #consent-overlay button.btn.approve-all-consent {background: rgba(0,0,0,0.8); font-weight: normal; color: rgba(255,255,255,0.8);}
+
+ @media (max-width: 767px) {
+ #consent-overlay > div {padding: 1.75rem 1rem;}
+ #consent-notice span {display: block; padding-top: 3px; margin-bottom: 1.5rem;}
+ #consent-notice button.btn {position: relative; bottom: 4px;}
+ }
+</style>
+<div id="consent-notice"><span>This website would like to use <a class="manage-consent" href="#manage-consent">third party code</a> to improve its functionality.</span><button class="btn manage-consent">Manage preferences</button><button class="btn deny-consent">Deny</button><button class="btn approve-consent">Allow</button></div>
+<div id="consent-overlay">
+ <div>
+ {{ range $index, $item := .Site.Data.consent.items }}
+ <div>
+ <input type="checkbox" id="item{{ $index }}" value="1" name="item{{ $index }}" {{ if $item.is_functional }}checked disabled{{ end }} />
+ <label for="item{{ $index }}">
+ <h5>{{ $item.title }}</h5>
+ <p>{{ $item.description }}</p>
+ </label>
+ </div>
+ {{ end }}
+ <div>
+ <button id="save-consent" class="btn save-consent" data-consentvalue="{{ range $index, $item := .Site.Data.consent.items }}{{ if $item.is_functional}}{{ else }}0{{ end }}{{ end }}">Save preferences</button>
+ <button class="btn approve-all-consent">Allow all</button>
+ </div>
+ </div>
+</div>
+<script>
+
+ const scripts = [];{{ range $index, $item := (where .Site.Data.consent.items "is_functional" false) }}
+ scripts[{{ $index }}] = {{ cond (hasPrefix $item.script "http") $item.script (printf "/js/%s" $item.script) }};{{ end }}
+
+ function createCookie(name,value,days) {
+ var expires = "";
+ if (days) {
+ var date = new Date();
+ date.setTime(date.getTime() + (days*24*60*60*1000));
+ expires = "; expires=" + date.toUTCString();
+ }
+ document.cookie = name + "=" + value + expires + "; path=/";
+ }
+ function readCookie(name) {
+ var nameEQ = name + "=";
+ var ca = document.cookie.split(';');
+ for(var i=0;i < ca.length;i++) {
+ var c = ca[i];
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
+ }
+ return null;
+ }
+ function eraseCookie(name) {
+ createCookie(name,"",-1);
+ }
+ function denyAllConsentScripts() {
+ var consentValue = "";
+ scripts.forEach(function(){
+ consentValue = consentValue + "0";
+ });
+ acceptSomeConsentScripts(consentValue);
+ }
+ function acceptAllConsentScripts() {
+ var consentValue = "";
+ scripts.forEach(function(){
+ consentValue = consentValue + "1";
+ });
+ acceptSomeConsentScripts(consentValue);
+ }
+ function acceptSomeConsentScripts(consentValue) {
+ setConsentInputs(consentValue);
+ createCookie('consent-settings',consentValue,31);
+ document.getElementById('consent-notice').style.display = 'none';
+ document.getElementById('consent-overlay').classList.remove('active');
+ loadConsentScripts(consentValue);
+ }
+ function loadConsentScripts(consentValue) {
+ scripts.forEach(function(value,key){
+ //console.log('script'+key+' is set to ' +consentValue[key]+' and is file '+value);
+ if(consentValue[key]=="1") {
+ var s = document.createElement('script');
+ s.type = 'text/javascript';
+ s.src = value;
+ document.body.appendChild(s);
+ }
+ });
+ }
+ function setConsentInputs(consentValue) {
+ var elements = document.querySelectorAll('#consent-overlay input:not([disabled])');
+ elements.forEach(function(el,index) {
+ if(consentValue[index]=="1") el.checked = true;
+ else el.checked = false;
+ });
+ }
+ function setConsentValue() {
+ var elements = document.querySelectorAll('#consent-overlay input:not([disabled])');
+ var consentValue = "";
+ elements.forEach(function(el) {
+ if(el.checked) consentValue = consentValue + "1";
+ else consentValue = consentValue + "0";
+ });
+ document.getElementById("save-consent").dataset.consentvalue = consentValue;
+ }
+
+ var elements = document.querySelectorAll('#consent-overlay input:not([disabled])');
+ elements.forEach(function(el) {
+ el.checked = false;
+ });
+
+ if(readCookie('consent-settings')) {
+ var consentValue = readCookie('consent-settings').toString();
+ //console.log(consentValue);
+ setConsentInputs(consentValue);
+ loadConsentScripts(consentValue);
+ } else {
+ document.getElementById('consent-notice').style.display = 'block';
+ }
+ var elements = document.querySelectorAll('.manage-consent');
+ elements.forEach(function(el) {
+ el.addEventListener("click",function() {
+ document.getElementById('consent-overlay').classList.toggle('active');
+ });
+ });
+ var elements = document.querySelectorAll('.deny-consent');
+ elements.forEach(function(el) {
+ el.addEventListener("click",function() {
+ denyAllConsentScripts();
+ });
+ });
+ var elements = document.querySelectorAll('.approve-consent, .approve-all-consent');
+ elements.forEach(function(el) {
+ el.addEventListener("click",function() {
+ acceptAllConsentScripts();
+ });
+ });
+ document.getElementById("save-consent").addEventListener("click",function() {
+ setConsentValue();
+ acceptSomeConsentScripts(this.dataset.consentvalue);
+ });
+ document.getElementById("consent-overlay").addEventListener("click",function(e) {
+ if (!document.querySelector("#consent-overlay > div").contains(e.target)){
+ this.classList.toggle('active');
+ }
+ });
+</script>
+
+{{ range $index, $item := .Site.Data.consent.items }}
+ {{ if $item.is_functional }}
+ <script type="text/javascript" src="{{ cond (hasPrefix $item.script "http") $item.script (printf "/js/%s" $item.script) }}"></script>
+ {{ end }}
+{{ end }}