add hire/resume pages, contact form, security middleware, and admin improvements
This commit is contained in:
@@ -2,6 +2,8 @@ package handler
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -10,6 +12,7 @@ import (
|
||||
|
||||
"ridgwaysystems.org/website/internal/blog"
|
||||
"ridgwaysystems.org/website/internal/feed"
|
||||
"ridgwaysystems.org/website/internal/mailer"
|
||||
"ridgwaysystems.org/website/internal/status"
|
||||
)
|
||||
|
||||
@@ -107,6 +110,13 @@ func (h *Handler) BlogList(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// postPageData is passed to the post template.
|
||||
type postPageData struct {
|
||||
*blog.Post
|
||||
Older *blog.Post
|
||||
Newer *blog.Post
|
||||
}
|
||||
|
||||
func (h *Handler) BlogPost(w http.ResponseWriter, r *http.Request) {
|
||||
slug := r.PathValue("slug")
|
||||
if slug == "" {
|
||||
@@ -123,7 +133,8 @@ func (h *Handler) BlogPost(w http.ResponseWriter, r *http.Request) {
|
||||
h.renderErr(w, http.StatusNotFound, "Post not found.")
|
||||
return
|
||||
}
|
||||
h.render(w, "post", post)
|
||||
older, newer, _ := h.store.Neighbors(slug)
|
||||
h.render(w, "post", postPageData{Post: post, Older: older, Newer: newer})
|
||||
}
|
||||
|
||||
func (h *Handler) Feed(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -167,6 +178,62 @@ func (h *Handler) About(w http.ResponseWriter, r *http.Request) {
|
||||
h.render(w, "about", nil)
|
||||
}
|
||||
|
||||
func (h *Handler) Resume(w http.ResponseWriter, r *http.Request) {
|
||||
h.render(w, "resume", nil)
|
||||
}
|
||||
|
||||
// --- Hire / Contact ---
|
||||
|
||||
type hireData struct {
|
||||
Name string
|
||||
Email string
|
||||
Company string
|
||||
Message string
|
||||
Error string
|
||||
Success bool
|
||||
}
|
||||
|
||||
func (h *Handler) Hire(w http.ResponseWriter, r *http.Request) {
|
||||
h.render(w, "hire", hireData{})
|
||||
}
|
||||
|
||||
func (h *Handler) HirePost(w http.ResponseWriter, r *http.Request) {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
h.renderErr(w, http.StatusBadRequest, "Bad form data.")
|
||||
return
|
||||
}
|
||||
d := hireData{
|
||||
Name: strings.TrimSpace(r.FormValue("name")),
|
||||
Email: strings.TrimSpace(r.FormValue("email")),
|
||||
Company: strings.TrimSpace(r.FormValue("company")),
|
||||
Message: strings.TrimSpace(r.FormValue("message")),
|
||||
}
|
||||
if d.Name == "" || d.Email == "" || d.Message == "" {
|
||||
d.Error = "Name, email, and message are required."
|
||||
h.render(w, "hire", d)
|
||||
return
|
||||
}
|
||||
if !strings.Contains(d.Email, "@") {
|
||||
d.Error = "Please enter a valid email address."
|
||||
h.render(w, "hire", d)
|
||||
return
|
||||
}
|
||||
|
||||
subject := "Hire inquiry from " + d.Name
|
||||
body := fmt.Sprintf("Name: %s\nEmail: %s\nCompany: %s\n\nMessage:\n%s\n",
|
||||
d.Name, d.Email, d.Company, d.Message)
|
||||
|
||||
if err := mailer.Send(h.contactEmail, subject, body); err != nil {
|
||||
log.Printf("contact form mail error: %v", err)
|
||||
d.Error = "Could not send message. Please email hire@ridgwaysystems.org directly."
|
||||
h.render(w, "hire", d)
|
||||
return
|
||||
}
|
||||
|
||||
d.Success = true
|
||||
h.render(w, "hire", d)
|
||||
}
|
||||
|
||||
// --- Sitemap ---
|
||||
|
||||
type urlset struct {
|
||||
@@ -188,6 +255,8 @@ func (h *Handler) Sitemap(w http.ResponseWriter, r *http.Request) {
|
||||
urls := []sitemapURL{
|
||||
{Loc: h.siteURL + "/", Freq: "weekly", Prio: "1.0"},
|
||||
{Loc: h.siteURL + "/blog", Freq: "weekly", Prio: "0.9"},
|
||||
{Loc: h.siteURL + "/hire", Freq: "monthly", Prio: "0.9"},
|
||||
{Loc: h.siteURL + "/resume", Freq: "monthly", Prio: "0.7"},
|
||||
{Loc: h.siteURL + "/infrastructure", Freq: "monthly", Prio: "0.7"},
|
||||
{Loc: h.siteURL + "/status", Freq: "daily", Prio: "0.6"},
|
||||
{Loc: h.siteURL + "/about", Freq: "monthly", Prio: "0.5"},
|
||||
|
||||
Reference in New Issue
Block a user