Статьи

Обработка форм с помощью phpPress, goPress, rubyPress и nodePress

Теперь, когда у вас есть веб-сайт, использующий плоскую файловую систему, вы хотели бы получить отзывы от ваших пользователей. Добавить Disqus легко, поскольку на страницу добавлен весь код JavaScript, но это не то, что вам нужно. Вы хотите, чтобы они могли написать вам напрямую, чтобы вы могли отвечать только на них.

Вы можете создать всю систему JavaScript для отправки электронной почты непосредственно с компьютера пользователя, но при этом ваша электронная почта будет открыта для спамеров, которые смогут извлечь ее из вашего кода и продать другим спамерам. Поэтому вам необходимо скрыть свой адрес электронной почты на сервере.

Это руководство посвящено добавлению системы сообщений электронной почты в вашу новую PressCMS (например, phpPress , rubyPress , nodePress и goPress ). Я начинаю с внешнего интерфейса, а затем обращаюсь к внутреннему для каждой системы. Я предполагаю, что у вас уже есть эти серверы в вашей системе.

Поскольку внешний интерфейс будет одинаковым для каждого сервера, вам придется скопировать эти новые файлы в каждый из каталогов сервера. Поэтому я буду говорить о файлах в пути, на которые ссылаются из каталога сервера.

Вместо добавления в тему стилей, специфичных для формы, этот скрипт формы содержит все в одном месте. Создайте файл questions.html в каталоге site/parts для веб-сайта со следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!— Styling for the form —>
<style>
    form {
        margin: 20px auto;
        width: 400px;
        padding: 1em;
        border: 1px solid #f0d5ad;
        border-radius: 1em;
    }
 
    form div + div {
        margin-top: 1em;
    }
 
    label {
        display: inline-block;
        width: 90px;
        text-align: right;
    }
 
    input, textarea {
        width: 300px;
        -moz-box-sizing: border-box;
    }
 
    input:focus, textarea:focus {
        border-color: #000;
    }
 
    textarea {
        vertical-align: top;
        height: 5em;
        resize: vertical;
    }
 
    button {
        margin-top: 10px;
        margin-left: 8em;
    }
</style>
 
<!— HTML for the Form —>
 
<form action=»/api/message» method=»post»>
    <div>
        <label for=»Name»>Name:</label>
        <input id=»Name» name=»Name» type=»text» value=»» pattern=»[a-zA-Z]{3,3} [a-zA-Z]{3,3}» title=»First and Last name.»
    </div>
    <div>
        <label for=»Email»>Email:</label>
        <input id=»Email» name=»Email» type=»email» pattern=»[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}» title=»Valid Email only.»
    </div>
    <div>
        <label for=»Message»>Message:</label>
        <textarea id=»Message» name=»Message» type=»text» value=»» required></textarea>
    </div>
    <button type=»submit»>Send Message</button>
</form>

Это создает базовую форму с запросом полного имени (имя и фамилия), электронной почты и сообщения. Эта форма использует регулярные выражения, чтобы убедиться, что имя и адрес электронной почты действительны. Если все, что пользователь вводит в эти поля, не соответствует регулярному выражению в директиве pattern , то форма не будет отправлена. Всплывающее окно попросит пользователя правильно заполнить поле сообщением в параметре title . Каждое поле ввода также имеет required примитив. Это предотвращает отправку бланков. Это минимальная проверка данных, которую вы должны использовать на внешнем интерфейсе.

Директива action в элементе form сообщает веб-браузеру, на какой адрес отправлять данные формы. Директива method указывает браузеру отправлять как метод post . Данные формы будут помещены в URL почтового запроса на сервер. Это строка запроса . Затем сервер обрабатывает информацию в строке запроса.

В каталоге site/pages создайте файл contact.md и поместите этот код:

1
2
3
4
5
### Contact Us
 
This is a simple contact form.
 
{{{question}}}

После сохранения вы можете опробовать страницы на сервере. В вашем браузере откройте страницу http: // localhost: 8081 / contact .

Страница контактной формы
Страница контактной формы

Страница « Контакты» будет выглядеть как на картинке выше. Обратите внимание на выделение поля «Имя» непосредственно при загрузке. Директива autofocus создает желаемое поведение. Это всегда хороший дизайн, чтобы иметь первое поле, которое пользователь должен ввести в фокусе автоматически.

После отправки сообщения пользователю будет приятно получить подтверждение. В каталоге site/pages создайте файл messagesent.md и поместите этот код:

1
2
3
### Message was sent
 
Thank you so much for taking time to send me a message.

Просто простое сообщение, чтобы пользователь знал, что сообщение было отправлено правильно. Вы можете расширить это, как вам нравится.

Страница подтверждения отправленного сообщения
Страница подтверждения отправленного сообщения

Для очистки сообщения, данного пользователем, я использую библиотеку Blue Monday . Чтобы загрузить эту библиотеку в вашей системе, вам нужно запустить следующую командную строку:

1
go get github.com/microcosm-cc/bluemonday

Это сделает библиотеку доступной для вашей программы. Это единственная нестандартная необходимая библиотека.

Откройте файл goPressServer.go и добавьте его в начало файла внутри оператора import () :

1
2
3
4
«fmt»
   «github.com/hoisie/web»
   «net/smtp»
   «github.com/microcosm-cc/bluemonday»

Отправка сообщений с сервера по электронной почте требует наличия этих библиотек. После строки, содержащей goPress.DefaultRoutes( вызов функции, добавьте следующий код:

1
2
3
4
5
//
// Setup special route for our form processing.
//
 
goPress.SetPostRoute(‘/api/message’, postMessage)

Это устанавливает почтовый маршрут /api/message для запуска функции postMessage() . В конце файла добавьте этот код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//
// Function: postMessage
//
// Description: This function will send
// the message from them
// the website to the owner
// of the site.
//
// Inputs:
// ctx The web server
// context.
//
func postMessage(ctx *web.Context) string {
    //
    // Get the post information and send the
    // email.
    //
    name := ctx.Params[«Name»]
    from := ctx.Params[«Email»]
    p := bluemonday.UGCPolicy()
    message := p.Sanitize(ctx.Params[«Message»])
    to := «<your email address>»
    subject := «Message from User:» + name + » of CustomCT.com»
    sendEmail(to, from, subject, message)
 
    //
    // Get the messagesent page contents and
    // process it.
    //
    pgloc := goPress.SiteData.Sitebase + «pages/messagesent»
    return goPress.RenderPageContents(ctx, goPress.GetPageContents(pgloc), pgloc)
}
 
//
// Function: sendEmail
//
// Description: This function sends an
// email message.
//
// Inputs:
// to The email address
// to send the
// message
// from The email address
// of the person
// sending the
// message
// subject The subject of the
// message
// message The message of the
// email
//
func sendEmail(to string, from string, subject string, message string) {
    body := fmt.Sprintf(«To: %s\r\nSubject: %s\r\n\r\n%s», to, subject, message)
    auth := smtp.PlainAuth(«», «<your email address>», «<your password>», «smtp.gmail.com»)
    err := smtp.SendMail(«smtp.gmail.com:587», auth, from, []string{to}, []byte(body))
    if err != nil {
        //
        // Process the error.
        // isn’t a problem.
        //
    }
}

Эти две функции составляют обработчик для обработки электронных писем, отправленных из браузера. Маршрут /api/message вызывает функцию postMessage() . Он извлекает информацию, отправленную из формы, заполненной пользователем, очищает сообщение с помощью библиотеки BlueMonday и отправляет электронное письмо владельцу сайта с помощью функции sendEmail() . Вам нужно будет указать свой адрес Gmail вместо владельца <your email address> и пароль в держателе <password> .

В файле goPress.go добавьте эту функцию после функции SetGetRoute() :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
//
// Function: SetPostRoute
//
// Description: This function gives an
// easy access to the
// web variable setup in
// this library.
//
// Inputs:
// route Route to setup
// handler Function to run that
// route.
//
func SetPostRoute(route string, handler interface{}) {
    web.Post(route, handler)
}

Эта функция в точности похожа на SetGetRoute() . Единственное отличие заключается в использовании функции web.Post() .

С этими изменениями ваш сервер goPress теперь может отправлять ваши электронные письма от пользователя.

Для отправки электронных писем с узла вам необходимо сначала установить библиотеку nodemailer и библиотеку body-parser с помощью следующей командной строки:

1
2
npm install -save nodemailer
npm install -save body-parser

Затем вам нужно загрузить новые библиотеки и настроить почтовый объект. В верхней части файла nodePress.js после последней загруженной библиотеки добавьте следующие строки:

1
2
3
4
5
6
7
8
var nodemailer = require(‘nodemailer’);
var bodyParser = require(‘body-parser’);
 
//
// create reusable transporter object using the
// default SMTP transport
//
var transporter = nodemailer.createTransport(‘smtps://<your email name%40<your email domain>:<your password>@smtp.gmail.com’);

Это загрузит библиотеку nodemailer и настроит повторно используемый компонент для отправки электронных писем. Вы должны заменить <your email name> на имя вашего адреса электронной почты (т.е. перед символом @), <your email domain> — это домен для вашего адреса электронной почты (то есть gmail.com для обычной почты Gmail или ваше имя домена, если вы настроить gmail на ваше доменное имя) и <your password> с паролем для вашей учетной записи электронной почты.

После строки, которая инициализирует переменную nodePress, добавьте этот код:

1
2
3
4
5
6
//
// Configure the body parser library.
//
nodePress.use(bodyParser.urlencoded({
    extended: true
}));

Теперь, после последнего nodePress.get() функции nodePress.get() , добавьте этот код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
nodePress.post(‘/api/message’, function(request, response) {
    //
    // setup e-mail data
    //
    var mailOptions = {
        from: request.body.Email,
        to: ‘<your email address>’,
        subject: ‘Message from ‘ + request.body.Name + ‘ on contact form.’,
        text: request.body.Message,
        html: request.body.Message
    };
    //
    // Send the email.
    //
    transporter.sendMail(mailOptions, function(error, info){
        if(error){
            return console.log(error);
        }
        //
        // Send the user to the message was sent okay page.
        //
        response.send(page(«messagesent»));
    });
});

Это обработчик для адреса /api/message . Эта функция получает информацию, отправленную из формы, создает правильное сообщение электронной почты и отправляет ее на адрес электронной почты, указанный в <your email address> . После отправки письма оно отправит пользователя на страницу /messagesent . В промежуточном программном обеспечении анализатора тела параметры URL сохранены в переменной request.body и должным образом очищены.

Этот код работает для настройки Gmail без двухфакторной аутентификации. Если у вас двухфакторная аутентификация, вы можете обратиться к документации Nodemailer, чтобы настроить ее.

Чтобы отправлять электронные письма в Ruby, вам необходимо установить библиотеку ruby-gmail со следующей командной строкой:

1
gem install ruby-gmail

В зависимости от настроек Ruby вам может потребоваться использовать sudo перед командой. Теперь, чтобы загрузить библиотеку, добавьте следующую строку в rubyPress.rb файла rubyPress.rb :

1
require ‘gmail’ # https://github.com/dcparker/ruby-gmail

После всех определений get добавьте следующие строки:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
post ‘/api/message’ do
  #
  # Get the parameters from the form.
  #
  name = params[:Name]
  email = params[:Email]
  message = params[:Message]
 
  #
  # Create and send the email.
  #
  Gmail.new(‘<your email address>’, ‘<your password>’) do |gmail|
    gmail.deliver do
      to «<your email address>»
      from email
      subject «Message from » + name
      text_part do
        body message
      end
    end
  end
  #
  # Send the user to the message sent page.
  #
  page ‘messagesent’
end

Благодаря этим дополнениям ваш сервер rubyPress может обрабатывать почтовые формы. Как только вы измените <your email address> на свой адрес электронной почты и <your password> на пароль для вашего почтового сервера, сценарий будет завершен.

Последний сервер, который нужно изменить, это сервер phpPress. Чтобы добавить возможности электронной почты на сервер, я собираюсь установить библиотеку phpmailer . Это наиболее широко используемая библиотека в PHP для работы с электронной почтой. Чтобы установить библиотеку, вам нужно выполнить следующие команды командной строки в каталоге phpPress:

1
2
composer update
composer require phpmailer/phpmailer

К сожалению, обновление композитора обновит библиотеку LightnCandy . Это хорошо, потому что это намного быстрее и проще в использовании. Но это нарушает код сервера. В файле index.php найдите функцию ProcessPage() и замените ее следующим кодом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//
// Function: ProcessPage
//
// Description: This function will process
// a page into the template,
// process all Mustache
// macros, and process all
// shortcodes.
//
// Inputs:
// $layout The layout for
// the page
// $page The pages main
// contents
//
function ProcessPage( $layout, $page ) {
   global $site, $parts, $helpers;
 
   //
   // Get the page contents.
   //
   $parts[‘content’] = figurePage($page);
 
   //
   // First pass on Handlebars.
   //
   $phpStr = LightnCandy::compile($layout, $helpers);
   $renderer = LightnCandy::prepare($phpStr);
   $page = $renderer($parts);
 
   //
   // Process the shortcodes.
   //
   $pageShort = processShortcodes($page);
 
   //
   // Second pass Handlebars.
   //
   $phpStr = LightnCandy::compile($pageShort, $helpers);
   $renderer = LightnCandy::prepare($phpStr);
   $page = $renderer($parts);
 
   //
   // Return the results.
   //
   return($page);
}

Сравнивая его со старым кодом, вам больше не нужно работать с временным файлом. Все это делается в памяти и, следовательно, намного быстрее. Теперь, в верхней части файла index.php , добавьте это после библиотеки Jade:

1
2
3
4
//
// PHP Mailer: https://github.com/PHPMailer/PHPMailer
//
require ‘vendor/phpmailer/phpmailer/PHPMailerAutoload.php’;

Это загружает библиотеку phpmailer. Теперь, после последней функции $app->get() , добавьте этот код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//
// This route is for processing the post request from the
// email form on the website.
//
$app->post(‘/api/message’, function(Request $request, Response $response) {
    global $_POST;
 
    //
    // Get the post variables.
    //
    $Name = $_POST[‘Name’];
    $Email = $_POST[‘Email’];
    $Message = $_POST[‘Message’];
 
    //
    // Create the email message and send it.
    //
    $mail = new PHPMailer;
 
    $mail->isSMTP();
    $mail->Host = ‘smtp.gmail.com’;
    $mail->SMTPAuth = true;
    $mail->Username = ‘<your email address>’;
    $mail->Password = ‘<your password>’;
    $mail->SMTPSecure = ‘tls’;
    $mail->Port = 587;
 
    $mail->setFrom($Email, $Name);
    $mail->addAddress(‘<your email>’, ‘<your name>’);
 
    $mail->Subject = «Message from $Name»;
    $mail->Body = $Message;
 
    if(!$mail->send()) {
        echo ‘Message could not be sent.’;
        echo ‘Mailer Error: ‘ .
    } else {
        $newResponse = SetBasicHeader($response);
        $newResponse->getBody()->write(page(‘messagesent’));
        return($newResponse);
    }
});

Это обработчик почтового запроса для пути /api/message . Он извлекает данные формы, отправленные из браузера, создает с ним электронную почту и отправляет электронную почту. PHP автоматически принимает любые параметры URL и помещает их в глобальный массив $_POST .

Вам нужно будет заменить <your email address> , <your password> и <your name> на соответствующие значения для вашей электронной почты. Если вы используете что-то иное, чем SMTP-сервер Gmail, вам также потребуется изменить адрес $mail->Host .

Я показал вам, как легко добавить форму электронной почты на сайт pressCMS. В загрузке для этого урока есть все эти серверы с их модификациями. Поэтому вы можете скачать его вместо того, чтобы печатать. Я сделал небольшую обработку ошибок. Я оставлю все остальное на ваше усмотрение.

Метод, который я учил здесь, — это размещение данных формы вместе с данными в URL. В настоящее время многие сайты используют REST API с данными в виде строки JSON в теле для выполнения действия. Эти процедуры легко адаптируются к этой методологии, но для вас это упражнение (или, возможно, будущий учебник). Теперь, когда вы знаете, как это сделать, добавьте свои собственные формы на свой сайт. Этот тип настройки очень весело. Единственным ограничением является ваше воображение.