Hugo is a static site generator build with Go. With Hugo you create Markdown
files for your content and the HTML will be generated automatically.
One reason for a non-static setup is the option to have contact forms without the
need to expose your email. A simple way for people to send messages without
needing them to write an email.
You probably know Formspree or a similar service. They offer you the
possibility to just use a standard HTML form on your page and they handle the
messages and send them to you via mail, so you don’t need to manage a database
and all that stuff yourself.
I will build a very simple contact form in Go, but for self-hosting. The idea is that the API should be outside from my hugo projects. I have more than one Project which need a contact form.
I have set up a public repo https://gitlab.com/joergklein/smtpmailer for all that
interested
Here is a code snipped. As router I use pat. I think it would be better to use
ServeMux from the public library.
Please take a look to the repo and I need help to change from pat to ServeMux.
package main
import (
"github.com/bmizerany/pat"
"html/template"
"log"
"net/http"
)
func main() {
mux := pat.New()
mux.Get("/", http.HandlerFunc(index))
mux.Post("/", http.HandlerFunc(send))
mux.Get("/confirmation", http.HandlerFunc(confirmation))
log.Println("Listening on port 8080")
http.ListenAndServe(":8080", mux)
}
func index(w http.ResponseWriter, r *http.Request) {
render(w, "templates/index.html", nil)
}
func send(w http.ResponseWriter, r *http.Request) {
msg := &Message{
Name: r.FormValue("name"),
Email: r.FormValue("email"),
Subject: r.FormValue("subject"),
Content: r.FormValue("content"),
}
if msg.Validate() == false {
render(w, "templates/index.html", msg)
return
}
if err := msg.Deliver(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/confirmation", http.StatusSeeOther)
}
func confirmation(w http.ResponseWriter, r *http.Request) {
render(w, "templates/confirmation.html", nil)
}
func render(w http.ResponseWriter, filename string, data interface{}) {
tmpl, err := template.ParseFiles(filename)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
if err := tmpl.Execute(w, data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}