From a8d04f9eac8efe0c476b8958277595be3773fd46 Mon Sep 17 00:00:00 2001 From: danix Date: Tue, 28 Feb 2023 18:25:04 +0100 Subject: [PATCH] added search and contact form functionality. Needs styling and check for functionality. --- assets/js/contact.js | 50 ++++++++++++++ assets/js/flexsearch.compact.js | 27 ++++++++ assets/js/search.js | 90 ++++++++++++++++++++++++ layouts/home.searchindex.json | 5 ++ layouts/partials/footer-addition.html | 12 ++++ layouts/shortcodes/contact.html | 16 +++++ layouts/shortcodes/search.html | 22 ++++++ static/php/contact.php | 98 +++++++++++++++++++++++++++ 8 files changed, 320 insertions(+) create mode 100644 assets/js/contact.js create mode 100644 assets/js/flexsearch.compact.js create mode 100644 assets/js/search.js create mode 100644 layouts/home.searchindex.json create mode 100644 layouts/shortcodes/contact.html create mode 100644 layouts/shortcodes/search.html create mode 100644 static/php/contact.php diff --git a/assets/js/contact.js b/assets/js/contact.js new file mode 100644 index 0000000..020d0e7 --- /dev/null +++ b/assets/js/contact.js @@ -0,0 +1,50 @@ +/** + * @file + * A JavaScript file for the contact form. + */ + +(function () { + + 'use strict'; + + const form = document.querySelector('.contact-form'); + const button = form.querySelector('.form-submit'); + const action = form.getAttribute('data-protect'); + const body = document.querySelector('body'); + + function activateForm() { + form.setAttribute('action', action); + button.removeAttribute('disabled'); + } + + // Display the hidden form. + form.classList.remove('hidden'); + + // Wait for a mouse to move, indicating they are human. + body.addEventListener('mousemove', () => activateForm()); + // Wait for a touch move event, indicating that they are human. + body.addEventListener('touchmove', () => activateForm()); + // A tab or enter key pressed can also indicate they are human. + body.addEventListener('keydown', function (e) { + if ((e.key === 'Tab') || (e.key === 'Enter')) { + activateForm(); + } + }); + + // Mark the form as submitted. + button.addEventListener('click', () => form.classList.add('js-submitted')); + + // Display messages. + if (location.search.substring(1) !== '') { + switch (location.search.substring(1)) { + case 'submitted': + document.querySelector('.contact-submitted').classList.remove('hidden'); + break; + + case 'error': + document.querySelector('.contact-error').classList.remove('hidden'); + break; + } + } + +})(); diff --git a/assets/js/flexsearch.compact.js b/assets/js/flexsearch.compact.js new file mode 100644 index 0000000..c8d5508 --- /dev/null +++ b/assets/js/flexsearch.compact.js @@ -0,0 +1,27 @@ +/**! + * FlexSearch.js v0.7.31 (Compact) + * Copyright 2018-2022 Nextapps GmbH + * Author: Thomas Wilkerling + * Licence: Apache-2.0 + * https://github.com/nextapps-de/flexsearch + */ +(function(self){'use strict';var t;function v(a){return"undefined"!==typeof a?a:!0}function w(a){const b=Array(a);for(let c=0;c=this.m&&(u||!n[l])){var f=P(q,e,r),g="";switch(this.C){case "full":if(2f;h--)if(h-f>=this.m){var k=P(q,e,r,d,f);g=l.substring(f,h);Q(this,n,g,k,a,c)}break}case "reverse":if(1=this.m&&Q(this,n, +g,P(q,e,r,d,h),a,c);g=""}case "forward":if(1=this.m&&Q(this,n,g,f,a,c);break}default:if(this.F&&(f=Math.min(f/this.F(b,l,r)|0,q-1)),Q(this,n,l,f,a,c),u&&1=this.m&&!d[l]){d[l]=1;const p=this.h&&l>f;Q(this,m,p?f:l,P(g+(e/2>g?0:1),e,r,h-1,k-1),a,c,p?l:f)}}}}this.D||(this.register[a]=1)}}return this}; +function P(a,b,c,e,d){return c&&1=this.m&&!c[q])if(this.s||f||this.map[q])k[u++]=q,c[q]=1;else return e;a=k;d=a.length}if(!d)return e;b||(b=100);h=this.depth&&1=e)))break;if(n){if(f)return ma(k,e,0);b[b.length]=k;return}}return!c&&k}function ma(a,b,c){a=1===a.length?a[0]:[].concat.apply([],a);return c||a.length>b?a.slice(c,c+b):a} +function na(a,b,c,e){c?(e=e&&b>c,a=(a=a[e?b:c])&&a[e?c:b]):a=a[b];return a}t.contain=function(a){return!!this.register[a]};t.update=function(a,b){return this.remove(a).add(a,b)};t.remove=function(a,b){const c=this.register[a];if(c){if(this.D)for(let e=0,d;eb||c)d=d.slice(c,c+b);e&&(d=qa.call(this,d));return{tag:a,result:d}}}function qa(a){const b=Array(a.length);for(let c=0,e;c +{{ if .HasShortcode "contact" -}} +{{ $contact := resources.Get "js/contact.js" | minify | fingerprint -}} + +{{ end -}} + +{{ if .HasShortcode "search" -}} +{{ $flexsearch := resources.Get "js/flexsearch.compact.js" | fingerprint -}} + +{{ $search_opts := dict "minify" true "params" (dict "searchLimit" (site.Params.searchLimit | default 20)) -}} +{{ $search := resources.Get "js/search.js" | js.Build $search_opts | fingerprint -}} + +{{ end -}} diff --git a/layouts/shortcodes/contact.html b/layouts/shortcodes/contact.html new file mode 100644 index 0000000..21e23f3 --- /dev/null +++ b/layouts/shortcodes/contact.html @@ -0,0 +1,16 @@ +

{{ i18n "js_required" }}

+ + + + diff --git a/layouts/shortcodes/search.html b/layouts/shortcodes/search.html new file mode 100644 index 0000000..784c598 --- /dev/null +++ b/layouts/shortcodes/search.html @@ -0,0 +1,22 @@ +

{{ i18n "js_required" }}

+ + + + +
+ + diff --git a/static/php/contact.php b/static/php/contact.php new file mode 100644 index 0000000..0f3932b --- /dev/null +++ b/static/php/contact.php @@ -0,0 +1,98 @@ + "$name <$email>", + 'Sender' => $sender, + 'Return-Path' => $sender, + 'MIME-Version' => '1.0', + 'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes', + 'Content-Transfer-Encoding' => '8Bit', + 'X-Mailer' => 'Hugo - Zen', + ]; + $mime_headers = []; + foreach ($headers as $key => $value) { + $mime_headers[] = "$key: $value"; + } + $mail_headers = join("\n", $mime_headers); + + // Send the mail, suppressing errors and setting Return-Path with the "-f" option. + $success = @mail($to, $subject, $message, $mail_headers, '-f' . $sender); +} + +$status = $success ? 'submitted' : 'error'; +$contact_form_url = strtok($_SERVER['HTTP_REFERER'], '?'); + +// Redirect back to contact form with status. +header('Location: ' . $contact_form_url . '?' . $status, TRUE, 302); +exit; + +function _contact_ff_wrap(&$line) { + $line = wordwrap($line, 72, " \n"); +} + +function _contact_clean_str($str, $quotes, $strip = false, $encode = false) { + if ($strip) { + $str = strip_tags($str); + } + + $str = htmlspecialchars(trim($str), $quotes, 'UTF-8'); + + if ($encode && preg_match('/[^\x20-\x7E]/', $str)) { + $str = '=?UTF-8?B?' . base64_encode($str) . '?='; + } + + return $str; +} -- 2.20.1