diff --git a/admin.go b/admin.go index 6408cfe..258d0b8 100644 --- a/admin.go +++ b/admin.go @@ -13,6 +13,7 @@ package writefreely import ( "database/sql" "fmt" + "html/template" "net/http" "runtime" "strconv" @@ -102,13 +103,16 @@ func NewAdminPage(app *App) *AdminPage { 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 var loc monday.Locale = monday.LocaleEnUS return monday.Format(u.Created, monday.DateTimeFormatsByLocale[loc], loc) */ - return c.Updated.Format("January 2, 2006, 3:04 PM") + if c.Updated.IsZero() { + return "Never" + } + 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 { @@ -426,9 +430,9 @@ func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Requ } // Add in default pages - var hasAbout, hasPrivacy bool + var hasAbout, hasContact, hasPrivacy bool for i, c := range p.Pages { - if hasAbout && hasPrivacy { + if hasAbout && hasContact && hasPrivacy { break } if c.ID == "about" { @@ -436,6 +440,11 @@ func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Requ if !c.Title.Valid { 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" { hasPrivacy = true if !c.Title.Valid { @@ -451,6 +460,13 @@ func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Requ Updated: defaultPageUpdatedTime, }) } + if !hasContact { + p.Pages = append(p.Pages, &instanceContent{ + ID: "contact", + Title: defaultContactTitle(), + Content: defaultContactPage(app), + }) + } if !hasPrivacy { p.Pages = append(p.Pages, &instanceContent{ 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 if slug == "about" { p.Content, err = getAboutPage(app) + } else if slug == "contact" { + p.Content, err = getContactPage(app) } else if slug == "privacy" { p.Content, err = getPrivacyPage(app) } else if slug == "landing" { @@ -523,7 +541,7 @@ func handleAdminUpdateSite(app *App, u *User, w http.ResponseWriter, r *http.Req id := vars["page"] // 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."} } diff --git a/app.go b/app.go index adbdc64..00dbcfe 100644 --- a/app.go +++ b/app.go @@ -317,7 +317,7 @@ func handleTemplatedPage(app *App, w http.ResponseWriter, r *http.Request, t *te }{ 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 err error @@ -328,6 +328,12 @@ func handleTemplatedPage(app *App, w http.ResponseWriter, r *http.Request, t *te p.AboutStats = &InstanceStats{} p.AboutStats.NumPosts, _ = app.db.GetTotalPosts() 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 { c, err = getPrivacyPage(app) } diff --git a/pages.go b/pages.go index 8b3a987..bf85526 100644 --- a/pages.go +++ b/pages.go @@ -40,6 +40,28 @@ func defaultAboutTitle(cfg *config.Config) sql.NullString { 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) { c, err := app.db.GetDynamicContent("privacy") 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).` } +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 { return `[WriteFreely](https://writefreely.org), the software that powers this site, is built to enforce your right to privacy by default. diff --git a/pages/500.tmpl b/pages/500.tmpl index e148fb5..4240348 100644 --- a/pages/500.tmpl +++ b/pages/500.tmpl @@ -2,9 +2,7 @@ {{define "content"}}

Server error 😵

-

Please contact the human authors of this software and remind them of their many shortcomings.

-

Be gentle, though. They are fragile mortal beings.

-

Also, unlike the AI that will soon replace them, you will need to include an error log from the server in your report. (Utterly primitive, we know.)

+

There seems to be an issue with this server. Please contact the admin and let them know they'll need to fix it.

– {{.SiteName}} 🤖

{{end}} diff --git a/pages/contact.tmpl b/pages/contact.tmpl new file mode 100644 index 0000000..8dff9ae --- /dev/null +++ b/pages/contact.tmpl @@ -0,0 +1,8 @@ +{{define "head"}}{{.ContentTitle}} — {{.SiteName}} + +{{end}} +{{define "content"}}
+

{{.ContentTitle}}

+ {{.Content}} +
+{{end}} diff --git a/templates/user/admin/view-page.tmpl b/templates/user/admin/view-page.tmpl index 161e40b..dfcf4cd 100644 --- a/templates/user/admin/view-page.tmpl +++ b/templates/user/admin/view-page.tmpl @@ -29,6 +29,8 @@ input[type=text] { {{if eq .Content.ID "about"}}

Describe what your instance is about.

+ {{else if eq .Content.ID "contact"}} +

Tell your users and outside visitors how to contact you.

{{else if eq .Content.ID "privacy"}}

Outline your privacy policy.

{{else if eq .Content.ID "reader"}}