diff options
-rw-r--r-- | layouts/_default/baseof.html | 4 | ||||
-rw-r--r-- | layouts/partials/consent.html | 170 | ||||
-rw-r--r-- | layouts/partials/footer.html | 2 | ||||
-rw-r--r-- | layouts/partials/googleanalytics.html | 18 | ||||
-rw-r--r-- | layouts/partials/head.html | 28 | ||||
-rw-r--r-- | layouts/partials/math.html | 6 |
6 files changed, 209 insertions, 19 deletions
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 237c540..18ea882 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -10,5 +10,9 @@ {{- block "main" . }}{{- end }} </div> {{- partial "footer.html" . -}} + + {{ if not .Site.IsServer }} + {{- partial "consent.html" . -}} + {{ end }} </body> </html> 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 }} diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index b027256..9cc8e31 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -9,7 +9,7 @@ {{ end }} {{ with .Site.Params.footer }} <div class="container text-center"> - <a href="{{ .url | absURL }}" title="{{ .text }}"><small>{{ .text }}</small></a> + <a href="{{ .url | absURL }}" title="{{ .text }}" {{ if .blank }}target="_blank"{{ end }}><small>{{ .text }}</small></a> </div> {{ end }} </div> diff --git a/layouts/partials/googleanalytics.html b/layouts/partials/googleanalytics.html new file mode 100644 index 0000000..2d72d71 --- /dev/null +++ b/layouts/partials/googleanalytics.html @@ -0,0 +1,18 @@ +{{- $pc := .Site.Config.Privacy.GoogleAnalytics -}} +{{- if not $pc.Disable }}{{ with .Site.GoogleAnalytics -}} +<script> +{{- if not $pc.RespectDoNotTrack -}} +var doNotTrack = false; +{{- else -}} +var dnt = (navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack); +var doNotTrack = (dnt == "1" || dnt == "yes"); +{{- end -}} +if (!doNotTrack) { + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', '{{ site.Config.Services.GoogleAnalytics.ID }}'); +} +</script> +{{- end -}} +{{- end -}} diff --git a/layouts/partials/head.html b/layouts/partials/head.html index f01e36b..88ba7ea 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -7,26 +7,24 @@ <meta name="author" content='{{ .Site.Params.author }}'> <link href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap" rel="stylesheet"> - <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"> - <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous"> - <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jpswalsh/academicons@1/css/academicons.min.css"> - - {{ $style := resources.Get "sass/researcher.scss" | resources.ExecuteAsTemplate "sass/researcher.scss" . | toCSS | minify }} + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css" integrity="sha512-rt/SrQ4UNIaGfDyEXZtNcyWvQeOq0QLygHluFQcSjaGB04IxWhal71tKuzP6K8eYXYB6vJV4pHkXcmFGGQ1/0w==" crossorigin="anonymous" referrerpolicy="no-referrer" /> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/academicons/1.9.3/css/academicons.min.css" integrity="sha512-vaoopdl+FJahyY2ddhsbDj8yDiRuyUYH/vIjF3z+cBg0sKc07NAQmUYli8volCGlW9OwlQyjVsr7Lh6qAManlw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> + {{ $style := resources.Get "sass/researcher.scss" | resources.ExecuteAsTemplate "sass/researcher.scss" . | toCSS | minify -}} <link rel="stylesheet" href="{{ $style.RelPermalink }}"> - - {{ with .Site.Params.favicon }} - <link rel="icon" type="image/ico" href="{{ . | absURL }}"> - {{ end }} + {{ with .Site.Params.favicon -}} + <link rel="icon" type="image/ico" href="{{ . | absURL }}"> + {{ end -}} {{ with .OutputFormats.Get "rss" -}} {{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }} {{ end -}} - {{ if not .Site.IsServer }} - {{ template "_internal/google_analytics.html" . }} - {{ end }} + {{- if not .Site.IsServer -}} + {{- partial "googleanalytics.html" . -}} + {{- end -}} - {{ if .Params.noindex }} - <meta name="robots" content="noindex"> - {{ end }} + {{ if .Params.noindex -}} + <meta name="robots" content="noindex"> + {{ end -}} </head> diff --git a/layouts/partials/math.html b/layouts/partials/math.html index 19c0502..c45386b 100644 --- a/layouts/partials/math.html +++ b/layouts/partials/math.html @@ -1,6 +1,6 @@ -<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous"> -<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script> -<script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/katex.min.css" integrity="sha512-t2ALGTyUR6g1HJiHCmSTge2yGseGofdO88Q+zOWQx/N0ikecVw0YuyOet9xZDV8+Vx0Y0n1a3f3Qx3V9CcnsKA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> +<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/katex.min.js" integrity="sha512-EKW5YvKU3hpyyOcN6jQnAxO/L8gts+YdYV6Yymtl8pk9YlYFtqJgihORuRoBXK8/cOIlappdU6Ms8KdK6yBCgA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/contrib/auto-render.min.js" integrity="sha512-iWiuBS5nt6r60fCz26Nd0Zqe0nbk1ZTIQbl3Kv7kYsX+yKMUFHzjaH2+AnM6vp2Xs+gNmaBAVWJjSmuPw76Efg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <!-- Script to enable inline math expressions --> <script> |