Back
Featured image of post Hugo|通过Formspree为博客添加私信功能

Hugo|通过Formspree为博客添加私信功能

一种对抗垃圾邮件的委婉方式

简介

参考Hugo主题Apéro中的Contact页面Formspree为博客添加了私信功能。以此替代直接在博客中留邮箱的方式,以防垃圾邮件轰炸(我已经收到很多垃圾诈骗邮件了> - < ,比如身在阿富汗的空军留有一亿美元在美国需要我的帮助、伊拉克的寡妇、网站设计求职……)

通过这样的表单形式发私信,用户不用登陆自己的邮箱,直接填写地址即可,也很方便。但免费用户一个月只可以收50次信,流量大的网站可能需要改为付费Plan,具体的价格可以看:Formspree Plans

效果

发信页面

我的私信链接

收信通知

步骤

1. 注册/登陆Formspree

地址:Formspree

2. 创建表单

进入左上角的Forms页面 -点击 + New Forms创建表单

  • 选择项目
    • 我用得是默认的项目 “My First Project",若需再起一个项目则点击+ New Project另起一个项目
  • 收信邮箱
    • 邮箱预设的是注册邮箱,可以在accout setting里面添加,免费用户可以添加两个邮箱
  • 确认好后选择Creat Forms

3. 调整表单细节

创建后,进入Form Detail页面

  • 复制Integration页面的form’s endpoint里的ID,后面会用到

  • 可以在Setting页面重新设置通知邮箱、添加reCAPTCHA验证和垃圾邮件过滤

  • Plugin页面可以联动启动应用程序一起使用,比如Trello、Airtable等,有的要开会员

4. 创建message.html

基于本博客的stack主题,创建一个删去文章标题、日期、字数、分类、评论区等细节的页面message.html 路径:/layouts/page/message.html 代码:

{{ define "body-class" }}
    {{ $TOCEnabled := default (default false .Site.Params.article.toc) .Params.toc }}
    {{- .Scratch.Set "hasTOC" (and (ge (len .TableOfContents) 100) $TOCEnabled) -}}
    article-page {{ if (.Scratch.Get "hasTOC") }}has-toc{{ end }}
{{ end }}


{{ define "main" }}
    <article class="{{ if .Params.image }}has-image {{ end }}main-article">
    
    <header class="article-header">
        {{- $image := partialCached "helper/image" (dict "Context" . "Type" "article") .RelPermalink "article" -}}
        {{ if $image.exists }}
            <div class="article-image">
                <a href="{{ .RelPermalink }}">
                    {{ if $image.resource }}
                        {{- $Permalink := $image.resource.RelPermalink -}}
                        {{- $Width := $image.resource.Width -}}
                        {{- $Height := $image.resource.Height -}}
                        {{- $Srcset := "" -}}
                        
                        {{- if (default true .Page.Site.Params.imageProcessing.cover.enabled) -}}
                            {{- $thumbnail := $image.resource.Resize "800x" -}}
                            {{- $thumbnailRetina := $image.resource.Resize "1600x" -}}
                            {{- $Srcset = printf "%s 800w, %s 1600w" $thumbnail.RelPermalink $thumbnailRetina.RelPermalink -}}
                            {{- $Permalink = $thumbnail.RelPermalink -}}
                            {{- $Width = $thumbnail.Width -}}
                            {{- $Height = $thumbnail.Height -}}
                        {{- end -}}

                        <img src="{{ $Permalink }}"
                            {{ with $Srcset }}srcset="{{ . }}"{{ end }}
                            width="{{ $Width }}" 
                            height="{{ $Height }}" 
                            loading="lazy"
                            alt="Featured image of post {{ .Title }}" />
                    {{ else }}
                        <img src="{{ $image.permalink }}" loading="lazy" alt="Featured image of post {{ .Title }}" />
                    {{ end }}
                </a>
            </div>
        {{ end }}
        </header>

        {{ partial "article/components/content" . }}
        {{ partial "article/components/form" . }}

    </article>
   
    {{ partialCached "footer/footer" . }}

   
{{ end }}

5. 创建form.html

Form Library里选择需要的表单格式,之后进到页面修改具体内容。

下面以Simple Contact Form为例子,修改项:

  • 输入框标题 label内的黑色字
  • 预设文字 placeholder=后的字
  • 设置非必填 默认全都必填,若改为选填,则删去对应的required=""

修改好后,点击左下角的Copy From Code复制代码。

下面是我基于stack主题修改的样式代码。修改项太多了,后面就没有怎么注释了

使用方式:创建 /layouts/partials/article/components/form.html,贴入代码


<section class="article-content">
  <form
    id="fs-frm"
    name="simple-contact-form"
    accept-charset="utf-8"
    action="https://formspree.io/f/{form_id}"
    method="post"
  >
    <fieldset id="fs-frm-inputs">
      <label for="full-name">Name*</label>
      <input
        type="text"
        name="name"
        id="full-name"
        placeholder=""
        required=""
      />
      <label for="email-address">Email Address*</label>
      <input
        type="email"
        name="_replyto"
        id="email-address"
        placeholder=""
        required=""
      />
      <label for="message">Message*</label>
      <textarea
        rows="5"
        name="message"
        id="message"
        placeholder=""
        required=""
      ></textarea>
      <input
        type="hidden"
        name="_subject"
        id="email-subject"
        value="Contact Form Submission"
      />
    </fieldset>
    <input type="submit" value="Send" />
    <small class="small"
      >Powered by
      <a href="https://formspree.io" target="_blank">Formspree</a></small
    >
  </form>
  <style>
    .small {
      color: var(--body-text-color);
      display: inline-block;
      float: right;
      margin-top: 3.5em;
      font-size: 80%;
      font-family: var(--base-font-family);
    }

    /* reset */
    #fs-frm input,
    #fs-frm select,
    #fs-frm textarea,
    #fs-frm fieldset,
    #fs-frm optgroup,
    #fs-frm label,
    #fs-frm #card-element:disabled {
      font-family: var(--base-font-family); /*标题字体*/
      font-size: 100%;
      color: inherit;
      border: none;
      border-radius: 5px;
      display: block;
      width: 100%;
      padding: 0;
      margin: 0;
      -webkit-appearance: none;
      -moz-appearance: none;
    }
    #fs-frm label,
    #fs-frm legend,
    #fs-frm ::placeholder {
      font-size: 1.6rem;
      margin-bottom: 0.5rem;
      font-family: var(--base-font-family);
      padding-top: 0.2rem;
      display: flex;
      align-items: baseline;
    }

    /* border, padding, margin, width */
    #fs-frm input,
    #fs-frm select,
    #fs-frm textarea,
    #fs-frm #card-element {
      border: 1.6px solid rgba(0, 0, 0, 0.144);
      background-color: var(--blockquote-background-color);
      padding: 0.75em 1rem;
      margin-bottom: 2rem;
    }
    #fs-frm input:focus,
    #fs-frm select:focus,
    #fs-frm textarea:focus {
      background-color: var(--card-background);
      outline-style: solid;
      outline-width: 2px; /*激活态输入框边框宽度 */
      outline-color: var(--accent-color); /*激活态输入框边框颜色 */
      outline-offset: -1px;
    }
    #fs-frm [type="text"],
    #fs-frm [type="email"] {
      width: 100%;
    }
    #fs-frm [type="button"],
    #fs-frm [type="submit"],
    #fs-frm [type="reset"] {
      display: inline-block;
      width: auto;
      font-weight: 600;
      cursor: pointer;
      color: var(--card-text-color-main);
      padding: 0.8em 2.5em; /*按键内边距 */
      border: 2px solid var(--card-text-color-main);
      background-color: var(--card-background); /*按键颜色 */
      -webkit-appearance: button;
      -moz-appearance: button;
      appearance: button;
      border-radius: 0.5em;
    }
    #fs-frm [type="button"]:focus,
    #fs-frm [type="submit"]:focus,
    #fs-frm [type="reset"]:focus {
      outline: none;
    }
    /*按键颜色hover*/
    #fs-frm [type="button"]:hover,
    #fs-frm [type="submit"]:hover,
    #fs-frm [type="reset"]:hover {
      transition: 0.1s background-color linear, 0.1s color linear;
      background-color: var(--card-text-color-main);
      color: var(--card-background);
    }
    /**/
    #fs-frm [type="submit"],
    #fs-frm [type="reset"] {
      margin-bottom: 1em;
      margin-top: 1em;
    }
    #fs-frm select {
      text-transform: none;
    }

    #fs-frm [type="checkbox"] {
      -webkit-appearance: checkbox;
      -moz-appearance: checkbox;
      appearance: checkbox;
      display: inline-block;
      width: auto;
      margin: 0 0.5em 0 0 !important;
    }

    #fs-frm [type="radio"] {
      -webkit-appearance: radio;
      -moz-appearance: radio;
      appearance: radio;
    }

    /* address, locale */
    #fs-frm fieldset.locale input[name="city"],
    #fs-frm fieldset.locale select[name="state"],
    #fs-frm fieldset.locale input[name="postal-code"] {
      display: inline;
    }
    #fs-frm fieldset.locale input[name="city"] {
      width: 52%;
    }
    #fs-frm fieldset.locale select[name="state"],
    #fs-frm fieldset.locale input[name="postal-code"] {
      width: 20%;
    }
    #fs-frm fieldset.locale input[name="city"],
    #fs-frm fieldset.locale select[name="state"] {
      margin-right: 3%;
    }
  </style>
</section>

6. 修改表格链接

form.html的第五行处{form.id},修改为之前复制的表格ID

action="https://formspree.io/f/{form_id}"

7. 创建page

创建/content/page/messge.md frontmatter设置为

---
title: Message
image: "https://s2.loli.net/2021/12/07/YwaXtPOlehjEG3T.jpg" 
layout: message
output:
  - html
toc: false
slug: email
hidden: false
menu:
  main:
    weight: 7
    params:
      icon: mail
---

icon链接:mail.svg

  • 图片设置问题
    • 我有试过创建/page/message/index.md/page/message/_index.md 然后在/message/ 下放图片文件,然后在index.md_index.md的frontmatter里写imag:图片名.格式,但都没有引用成功
    • 放在/static/img里面再引用,也没有成功 最后用了图床链接
  • 在导航栏中隐藏 设置hidden: true ,并删掉 meun:后面的内容:
menu:
  main:
    weight: 7
    params:
      icon: meseage