Add a customizable Contact page
This commit is contained in:
parent
83f230ddaf
commit
d48262a6df
28
admin.go
28
admin.go
|
@ -13,6 +13,7 @@ package writefreely
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -102,13 +103,16 @@ func NewAdminPage(app *App) *AdminPage {
|
||||||
return ap
|
return ap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c instanceContent) UpdatedFriendly() string {
|
func (c instanceContent) UpdatedFriendly() template.HTML {
|
||||||
/*
|
/*
|
||||||
// TODO: accept a locale in this method and use that for the format
|
// TODO: accept a locale in this method and use that for the format
|
||||||
var loc monday.Locale = monday.LocaleEnUS
|
var loc monday.Locale = monday.LocaleEnUS
|
||||||
return monday.Format(u.Created, monday.DateTimeFormatsByLocale[loc], loc)
|
return monday.Format(u.Created, monday.DateTimeFormatsByLocale[loc], loc)
|
||||||
*/
|
*/
|
||||||
return c.Updated.Format("January 2, 2006, 3:04 PM")
|
if c.Updated.IsZero() {
|
||||||
|
return "<em>Never</em>"
|
||||||
|
}
|
||||||
|
return template.HTML(c.Updated.Format("January 2, 2006, 3:04 PM"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleViewAdminDash(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
|
func handleViewAdminDash(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
|
||||||
|
@ -426,9 +430,9 @@ func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Requ
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add in default pages
|
// Add in default pages
|
||||||
var hasAbout, hasPrivacy bool
|
var hasAbout, hasContact, hasPrivacy bool
|
||||||
for i, c := range p.Pages {
|
for i, c := range p.Pages {
|
||||||
if hasAbout && hasPrivacy {
|
if hasAbout && hasContact && hasPrivacy {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if c.ID == "about" {
|
if c.ID == "about" {
|
||||||
|
@ -436,6 +440,11 @@ func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Requ
|
||||||
if !c.Title.Valid {
|
if !c.Title.Valid {
|
||||||
p.Pages[i].Title = defaultAboutTitle(app.cfg)
|
p.Pages[i].Title = defaultAboutTitle(app.cfg)
|
||||||
}
|
}
|
||||||
|
} else if c.ID == "contact" {
|
||||||
|
hasContact = true
|
||||||
|
if !c.Title.Valid {
|
||||||
|
p.Pages[i].Title = defaultContactTitle()
|
||||||
|
}
|
||||||
} else if c.ID == "privacy" {
|
} else if c.ID == "privacy" {
|
||||||
hasPrivacy = true
|
hasPrivacy = true
|
||||||
if !c.Title.Valid {
|
if !c.Title.Valid {
|
||||||
|
@ -451,6 +460,13 @@ func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Requ
|
||||||
Updated: defaultPageUpdatedTime,
|
Updated: defaultPageUpdatedTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if !hasAbout {
|
||||||
|
p.Pages = append(p.Pages, &instanceContent{
|
||||||
|
ID: "contact",
|
||||||
|
Title: defaultContactTitle(),
|
||||||
|
Content: defaultContactPage(app),
|
||||||
|
})
|
||||||
|
}
|
||||||
if !hasPrivacy {
|
if !hasPrivacy {
|
||||||
p.Pages = append(p.Pages, &instanceContent{
|
p.Pages = append(p.Pages, &instanceContent{
|
||||||
ID: "privacy",
|
ID: "privacy",
|
||||||
|
@ -489,6 +505,8 @@ func handleViewAdminPage(app *App, u *User, w http.ResponseWriter, r *http.Reque
|
||||||
// Get pre-defined pages, or select slug
|
// Get pre-defined pages, or select slug
|
||||||
if slug == "about" {
|
if slug == "about" {
|
||||||
p.Content, err = getAboutPage(app)
|
p.Content, err = getAboutPage(app)
|
||||||
|
} else if slug == "contact" {
|
||||||
|
p.Content, err = getContactPage(app)
|
||||||
} else if slug == "privacy" {
|
} else if slug == "privacy" {
|
||||||
p.Content, err = getPrivacyPage(app)
|
p.Content, err = getPrivacyPage(app)
|
||||||
} else if slug == "landing" {
|
} else if slug == "landing" {
|
||||||
|
@ -523,7 +541,7 @@ func handleAdminUpdateSite(app *App, u *User, w http.ResponseWriter, r *http.Req
|
||||||
id := vars["page"]
|
id := vars["page"]
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
if id != "about" && id != "privacy" && id != "landing" && id != "reader" {
|
if id != "about" && id != "contact" && id != "privacy" && id != "landing" && id != "reader" {
|
||||||
return impart.HTTPError{http.StatusNotFound, "No such page."}
|
return impart.HTTPError{http.StatusNotFound, "No such page."}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
app.go
8
app.go
|
@ -318,7 +318,7 @@ func handleTemplatedPage(app *App, w http.ResponseWriter, r *http.Request, t *te
|
||||||
}{
|
}{
|
||||||
StaticPage: pageForReq(app, r),
|
StaticPage: pageForReq(app, r),
|
||||||
}
|
}
|
||||||
if r.URL.Path == "/about" || r.URL.Path == "/privacy" {
|
if r.URL.Path == "/about" || r.URL.Path == "/contact" || r.URL.Path == "/privacy" {
|
||||||
var c *instanceContent
|
var c *instanceContent
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -329,6 +329,12 @@ func handleTemplatedPage(app *App, w http.ResponseWriter, r *http.Request, t *te
|
||||||
p.AboutStats = &InstanceStats{}
|
p.AboutStats = &InstanceStats{}
|
||||||
p.AboutStats.NumPosts, _ = app.db.GetTotalPosts()
|
p.AboutStats.NumPosts, _ = app.db.GetTotalPosts()
|
||||||
p.AboutStats.NumBlogs, _ = app.db.GetTotalCollections()
|
p.AboutStats.NumBlogs, _ = app.db.GetTotalCollections()
|
||||||
|
} else if r.URL.Path == "/contact" {
|
||||||
|
c, err = getContactPage(app)
|
||||||
|
if c.Updated.IsZero() {
|
||||||
|
// Page was never set up, so return 404
|
||||||
|
return ErrPostNotFound
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c, err = getPrivacyPage(app)
|
c, err = getPrivacyPage(app)
|
||||||
}
|
}
|
||||||
|
|
34
pages.go
34
pages.go
|
@ -40,6 +40,28 @@ func defaultAboutTitle(cfg *config.Config) sql.NullString {
|
||||||
return sql.NullString{String: "About " + cfg.App.SiteName, Valid: true}
|
return sql.NullString{String: "About " + cfg.App.SiteName, Valid: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getContactPage(app *App) (*instanceContent, error) {
|
||||||
|
c, err := app.db.GetDynamicContent("contact")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if c == nil {
|
||||||
|
c = &instanceContent{
|
||||||
|
ID: "contact",
|
||||||
|
Type: "page",
|
||||||
|
Content: defaultContactPage(app),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !c.Title.Valid {
|
||||||
|
c.Title = defaultContactTitle()
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultContactTitle() sql.NullString {
|
||||||
|
return sql.NullString{String: "Contact Us", Valid: true}
|
||||||
|
}
|
||||||
|
|
||||||
func getPrivacyPage(app *App) (*instanceContent, error) {
|
func getPrivacyPage(app *App) (*instanceContent, error) {
|
||||||
c, err := app.db.GetDynamicContent("privacy")
|
c, err := app.db.GetDynamicContent("privacy")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -70,6 +92,18 @@ func defaultAboutPage(cfg *config.Config) string {
|
||||||
return `_` + cfg.App.SiteName + `_ is a place for you to write and publish, powered by [WriteFreely](https://writefreely.org).`
|
return `_` + cfg.App.SiteName + `_ is a place for you to write and publish, powered by [WriteFreely](https://writefreely.org).`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func defaultContactPage(app *App) string {
|
||||||
|
c, err := app.db.GetCollectionByID(1)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return `_` + app.cfg.App.SiteName + `_ is administered by: [**` + c.Alias + `**](/` + c.Alias + `/).
|
||||||
|
|
||||||
|
Contact them at this email address: _EMAIL GOES HERE_.
|
||||||
|
|
||||||
|
You can also reach them here...`
|
||||||
|
}
|
||||||
|
|
||||||
func defaultPrivacyPolicy(cfg *config.Config) string {
|
func defaultPrivacyPolicy(cfg *config.Config) string {
|
||||||
return `[WriteFreely](https://writefreely.org), the software that powers this site, is built to enforce your right to privacy by default.
|
return `[WriteFreely](https://writefreely.org), the software that powers this site, is built to enforce your right to privacy by default.
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{{define "content"}}
|
{{define "content"}}
|
||||||
<div class="content-container tight">
|
<div class="content-container tight">
|
||||||
<h1>Server error 😵</h1>
|
<h1>Server error 😵</h1>
|
||||||
<p>There seems to be an issue with this server. Please contact the admin and let them know they'll need to fix it.</p>
|
<p>There seems to be an issue with this server. Please <a href="/contact">contact the admin</a> and let them know they'll need to fix it.</p>
|
||||||
<p>– {{.SiteName}} 🤖</p>
|
<p>– {{.SiteName}} 🤖</p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{{define "head"}}<title>{{.ContentTitle}} — {{.SiteName}}</title>
|
||||||
|
<meta name="description" content="{{.PlainContent}}">
|
||||||
|
{{end}}
|
||||||
|
{{define "content"}}<div class="content-container snug">
|
||||||
|
<h1>{{.ContentTitle}}</h1>
|
||||||
|
{{.Content}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
|
@ -29,6 +29,8 @@ input[type=text] {
|
||||||
|
|
||||||
{{if eq .Content.ID "about"}}
|
{{if eq .Content.ID "about"}}
|
||||||
<p class="page-desc content-desc">Describe what your instance is <a href="/about" target="page">about</a>.</p>
|
<p class="page-desc content-desc">Describe what your instance is <a href="/about" target="page">about</a>.</p>
|
||||||
|
{{else if eq .Content.ID "contact"}}
|
||||||
|
<p class="page-desc content-desc">Tell your users and outside visitors how to <a href="/contact" target="page">contact</a> you.</p>
|
||||||
{{else if eq .Content.ID "privacy"}}
|
{{else if eq .Content.ID "privacy"}}
|
||||||
<p class="page-desc content-desc">Outline your <a href="/privacy" target="page">privacy policy</a>.</p>
|
<p class="page-desc content-desc">Outline your <a href="/privacy" target="page">privacy policy</a>.</p>
|
||||||
{{else if eq .Content.ID "reader"}}
|
{{else if eq .Content.ID "reader"}}
|
||||||
|
|
Loading…
Reference in New Issue