Adding a php contact form feature.
This commit is contained in:
parent
e56f50a91b
commit
a673c28cf2
4 changed files with 187 additions and 0 deletions
17
README.md
17
README.md
|
|
@ -96,6 +96,15 @@ params:
|
|||
```
|
||||
|
||||
|
||||
## Contact form
|
||||
|
||||
If your server support php with the mail() command (very common) you can use the included contact form feature to get a contact form for your site.
|
||||
|
||||
1. Copy the file `themes/zen/static/php/contact.php.example` to `static/php/contact.php`.
|
||||
2. Edit the contact.php file so it has your own e-mail address. You may also change the mail subject prefix.
|
||||
3. Add the shortcode `{{< contact >}}` to a page. Also set `contactform: true` in the front matter for that page so the contact.js file gets loaded.
|
||||
|
||||
|
||||
## Dates
|
||||
|
||||
If "lastmod" is set in the frontmatter on a post that value will be used in the "submitted" section. If not "date" is used.
|
||||
|
|
@ -105,6 +114,14 @@ With "lastmod" set a date section will also appear at the bottom of post telling
|
|||
|
||||
## Shortcodes
|
||||
|
||||
### Contact
|
||||
|
||||
Insert a html5 contact form, see more above.
|
||||
|
||||
```
|
||||
{{< contact >}}
|
||||
```
|
||||
|
||||
### Figure
|
||||
|
||||
Zen comes with a improved version of the built in "figure" shortcut.
|
||||
|
|
|
|||
16
layouts/shortcodes/contact.html
Normal file
16
layouts/shortcodes/contact.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<p class="contact-no-js error message">{{ i18n "contact_js" }}</p>
|
||||
<p class="contact-submitted status message hidden">{{ i18n "contact_submitted" }}</p>
|
||||
<p class="contact-error error message hidden">{{ i18n "contact_error" }}</p>
|
||||
|
||||
<form class="contact-form hidden" action="#" method="post" accept-charset="UTF-8">
|
||||
<label for="edit-name">{{ i18n "contact_name" }}</label>
|
||||
<input type="text" id="edit-name" name="name" placeholder="{{ i18n "contact_name_placeholder" }}" tabindex="1" required autofocus><span></span>
|
||||
<label for="edit-mail">{{ i18n "contact_mail" }}</label>
|
||||
<input type="email" id="edit-mail" name="email" placeholder="{{ i18n "contact_mail_placeholder" }}" tabindex="2" required><span></span>
|
||||
<input type="text" id="edit-url" class="hidden" name="url" placeholder="{{ i18n "contact_honypot" }}">
|
||||
<label for="edit-subject">{{ i18n "contact_subject" }}</label>
|
||||
<input type="text" id="edit-subject" name="subject" placeholder="{{ i18n "contact_subject_placeholder" }}" tabindex="3" required><span></span>
|
||||
<label for="edit-message">{{ i18n "contact_message" }}</label>
|
||||
<textarea id="edit-message" name="message" rows="5" placeholder="{{ i18n "contact_message_placeholder" }}" tabindex="4" required></textarea><span></span>
|
||||
<button type="submit" name="submit" class="form-submit" disabled>{{ i18n "contact_submit" }}</button>
|
||||
</form>
|
||||
56
static/js/contact.js
Normal file
56
static/js/contact.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* @file
|
||||
* A JavaScript file for the contact form.
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
'use strict';
|
||||
|
||||
// Contact form.
|
||||
$('.contact-form').each(function () {
|
||||
var $contact_form = $(this);
|
||||
var $contact_button = $contact_form.find('.form-submit');
|
||||
var contact_action = '/php/contact.php';
|
||||
|
||||
// Display the hidden form.
|
||||
$contact_form.removeClass('hidden');
|
||||
// Remove the "no javascript" messages
|
||||
$('.contact-no-js').detach();
|
||||
|
||||
// Wait for a mouse to move, indicating they are human.
|
||||
$('body').mousemove(function() {
|
||||
// Unlock the form.
|
||||
$contact_form.attr('action', contact_action);
|
||||
$contact_button.attr('disabled', false);
|
||||
});
|
||||
|
||||
// A tab or enter key pressed can also indicate they are human.
|
||||
$('body').keydown(function(e) {
|
||||
if ((e.keyCode == 9) || (e.keyCode == 13)) {
|
||||
// Unlock the form.
|
||||
$contact_form.attr('action', contact_action);
|
||||
$contact_button.attr('disabled', false);
|
||||
}
|
||||
});
|
||||
|
||||
// Mark the form as submitted.
|
||||
$contact_button.on('click touchstart MSPointerDown', function () {
|
||||
$contact_form.addClass('js-submitted');
|
||||
});
|
||||
|
||||
// Display messages.
|
||||
if (location.search.substring(1) != '') {
|
||||
switch(location.search.substring(1)) {
|
||||
case 'submitted':
|
||||
$('.contact-submitted').removeClass('hidden');
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
$('.contact-error').removeClass('hidden');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
98
static/php/contact.php.example
Normal file
98
static/php/contact.php.example
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
// Set the e-mail address that submission should be sent to.
|
||||
$address = 'info@example.com';
|
||||
|
||||
// Set the e-mail subject prefix.
|
||||
$prefix = 'Website feedback';
|
||||
|
||||
// DO NOT EDIT ANYTHING BELOW UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||
|
||||
$error = false;
|
||||
$success = false;
|
||||
|
||||
// Check that the submission address is valid.
|
||||
if ((bool) filter_var(trim($address), FILTER_VALIDATE_EMAIL)) {
|
||||
// Also set sender/return path header to this address to avoid SPF errors.
|
||||
$to = $sender = trim($address);
|
||||
}
|
||||
else {
|
||||
$error = true;
|
||||
}
|
||||
|
||||
// Check that referer is local server.
|
||||
if (!isset($_SERVER['HTTP_REFERER']) || (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) != $_SERVER['SERVER_NAME'])) {
|
||||
exit('Direct access not permitted');
|
||||
}
|
||||
|
||||
// Check that this is a post request.
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_POST)) {
|
||||
$error = true;
|
||||
}
|
||||
|
||||
// Check if fake url field is filled in, i.e. spam bot.
|
||||
if (!empty($_POST['url'])) {
|
||||
$error = true;
|
||||
}
|
||||
|
||||
// Check that e-mail address is valid.
|
||||
if ((bool) filter_var(trim($_POST['email']), FILTER_VALIDATE_EMAIL)) {
|
||||
$email = trim($_POST['email']);
|
||||
}
|
||||
else {
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
// Construct the mail with headers.
|
||||
$name = _contact_clean_str($_POST['name'], ENT_QUOTES, true, true);
|
||||
$prefix = _contact_clean_str($prefix, ENT_NOQUOTES, true, true);
|
||||
$subject = _contact_clean_str($_POST['subject'], ENT_NOQUOTES, true, true);
|
||||
$subject = "[$prefix] $subject";
|
||||
$message = _contact_clean_str($_POST['message'], ENT_NOQUOTES);
|
||||
$lines = explode("\n", $message);
|
||||
array_walk($lines, '_contact_ff_wrap');
|
||||
$message = implode("\n", $lines);
|
||||
$headers = [
|
||||
'From' => "$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;
|
||||
}
|
||||
Loading…
Reference in a new issue