0

我正在使用机车 CMS 的托管版本。

Locomotive CMS 提供了一种收集表单提交方法,以及一种使用 Actions API 发送电子邮件的方法

我想收集表单提交,然后向提交表单的人发送电子邮件。

我有 3 个警告:

  1. 我希望以内容类型收集表单数据(启用公开提交)
  2. 我希望使用Google reCAPTCHA v3
  3. 我希望使用 AJAX 提交表单

在 Locomotive CMS 的托管版本中,上述所有项目都是开箱即用的。但是,我不知道如何通过 AJAX 使用 Google reCAPTCHA 提交内容类型表单并同时发送电子邮件。发送电子邮件功能需要在专用页面上执行操作,我认为需要加载该操作才能运行操作。此外,我不知道如何将表单提交中的数据获取到运行发送电子邮件操作的页面。

如何在启用 Google reCAPTCHA 的情况下通过 AJAX 提交 Locomotive CMS 内容类型的表单并将包含表单提交数据的电子邮件发送给在表单中提交的人?

4

1 回答 1

1

几个先决条件:

  1. 设置 metafields_schema.yml 以包含发送电子邮件的必要信息:

    smtp_settings:
      label: Outgoing Email
      fields:
    
        server:
          label: SMTP Server
          type: string
          localized: false
    
        username:
          label: Username
          type: string
          localized: false
    
        password:
          label: Password
          type: string
          localized: false
    
        port:
          label: Port
          type: string
          hint: TLS
          localized: false
    
  2. 设置电子邮件模板:

    电子邮件模板.液体:

    <p>Dear {{ entryData.first_name }},</p>
    <!-- include form submission data via entryData.form_field_name -->
    

如果去掉使用 Google reCAPTCHA 的条件,任务就相对简单了。

我们“简单地”将表单数据传递到自定义页面,我们在该页面发送电子邮件并使用 Actions API 创建内容条目。

设置如下:

  1. 手动创建表单以收集内容类型数据。请注意表单操作指向自定义页面:

    <form method="POST" enctype="multipart/form-data" class="form" action="{% path_to 'page-with-send-email-and-create-content-entry-action' %}">
        <!-- form fields here -->
    </form>
    
    <script defer src="{{ 'form-submit.js' | javascript_url }}"></script>
    
  2. 使用 AJAX 提交表单:

    表单提交.js

    $('.form').on('submit', function(e) {
        e.preventDefault();
        var form = $(this);
    
        // error handling functions removed for brevity
    
        $.ajax({
            type: 'POST',
            url: form.attr('action'),
            data: form.serialize(),
            dataType: 'json',
            success: function(data) {
                console.log('Success:', data);
            },
            error: function(xhr, status, error) {
                console.log('Status:', status);
                console.log('Error:', error);
                var errors = jQuery.parseJSON(xhr.responseText).errors;
                console.log(errors);
                for (error in errors) { 
                    myError = error;
                    console.log(myError);
                }
            }
        });
    
    });
    
  3. 使用 Actions API发送电子邮件创建内容类型条目:

    带有发送电子邮件和创建内容条目操作的页面

    {% action "send email and create content type entry" %}
    
        var SMTPsettings = getProp('site').metafields.smtp_settings;
        var entryData = getProp('params'); // params holds the data passed to the page via AJAX
    
        // save entryData into a Liquid variable to be called in the Email Template
        setProp('entryData',entryData);
    
        sendEmail({
    
            to: formData.email_address, // must match the name attribute of the field used to collect the email address 
            from: SMTPsettings.username,
            subject: '[Email Subject]',
            page_handle: 'email-template', // template page for email
    
            smtp: {
                address: SMTPsettings.server,
                port: SMTPsettings.port,
                user_name: SMTPsettings.username,
                password: SMTPsettings.password,
                authentication: 'plain',
                enable_starttls_auto: true
            }
    
        });
    
        createEntry('content_entry_name', {
            content_type_field_name: formData.form_field_name,
            // comma-separated list - last item has no comma
        });
    
    {% endaction %}
    
    {"success":true}
    

如果需要 Google reCAPTCHA,则任务会更复杂。

我不相信有一种方法可以在启用 Google reCAPTCHA 的 Locomotive CMS 中手动创建表单,这意味着上述方法不起作用。

Google reCAPTCHA 可通过默认内容类型表单设置在 Locomotive CMS 中使用:

{% model_form 'content_type_slug', class: 'form', json: true, recaptcha: true %}
    // form fields here
{% endmodel_form %}

<script src="https://www.google.com/recaptcha/api.js?render={{ site.metafields.google.recaptcha_site_key }}"></script>

<script>
    grecaptcha.ready(function() {
        grecaptcha.execute('{{ site.metafields.google.recaptcha_site_key }}', {
            action: 'enquiry'
        })
        .then(function(token) {
            document.getElementById('g-recaptcha-response').value  = token;
        });
    });
</script>

<script defer src="{{ 'form-submit.js' | javascript_url }}"></script>

注意:该属性recaptcha_required需要true在 content_type yml 文件中设置。

在这种情况下,我们无法为表单操作设置自定义 url。此外,reCAPTCHA 验证意味着我们需要让表单通过常规流程提交和创建内容条目,并单独发送电子邮件。

为此,我们需要获取表单提交时创建的内容条目的 ID。然后,我们可以运行额外的 AJAX 请求并将 ID 传递到包含发送电子邮件操作的自定义页面。在自定义页面上,我们将使用 ID 来引用内容条目并获取数据以填充电子邮件。

设置如下:

  1. 通过上面的默认方法创建表单。

  2. 使用 AJAX 提交表单。成功提交后,获取内容条目 ID 并将其传递给辅助 AJAX 请求:

    表单提交.js:

    $('.form').on('submit', function(e) {
        e.preventDefault();
        var form = $(this);
    
        // error handling functions removed for brevity
    
        $.ajax({
            type: 'POST',
            url: form.attr('action'),
            data: form.serialize(),
            dataType: 'json',
            success: function(data) {
                console.log('Success:', data);
    
                // get the content entry ID
                var entryID = data._id;
                // set up the data to be sent in the correct format
                var newData = 'id=' + entryID;
    
                // set up our secondary AJAX request
                function sendEmail() {
    
                    $.ajax({
                        type: 'POST',
                        url: 'page-with-send-email-action',
                        data: newData,
                        dataType: 'json',
                        success: function(data) {
                            console.log('Success:', data);
                        },
                        error: function(xhr, status, error) {
                            console.log('Status:', status);
                            console.log('Error:', error);
                            var errors = jQuery.parseJSON(xhr.responseText).errors;
                            console.log(errors);
    
                            for (error in errors) { 
                                myError = error;
                                console.log(myError);
                            }
                        }
                    });
    
                }
    
                sendEmail();
                showSuccess();
    
            },
            error: function(xhr, status, error) {
                console.log('Status:', status);
                console.log('Error:', error);
                var errors = jQuery.parseJSON(xhr.responseText).errors;
                console.log(errors);
    
                for (error in errors) { 
                    myError = error;
                    console.log(myError);
                    showError();
                }
            }
        });
    });
    
  3. 使用 Actions API 找到提交的内容条目并发送电子邮件:

    页面发送电子邮件action.liquid:

    {% action "send email" %}
    
        var SMTPsettings = getProp('site').metafields.smtp_settings;
        var entryID = getProp('params').id;
        var entryData = findEntry('content_type_slug', entryID);
    
        // save entryData into a Liquid variable to be called in the Email Template
        setProp('entryData',entryData);
    
        sendEmail({
    
            to: entryData.email_address,
            from: SMTPsettings.username,
            subject: '[Email Subject]',
            page_handle: 'email-template',
    
            smtp: {
                address: SMTPsettings.server,
                port: SMTPsettings.port,
                user_name: SMTPsettings.username,
                password: SMTPsettings.password,
                authentication: 'plain',
                enable_starttls_auto: true
            }
    
        });
    
    {% endaction %}
    
    {"success":true}
    
于 2020-08-02T03:16:25.910 回答