Added a site setting section
This commit is contained in:
parent
499c0d8568
commit
0bd91de234
|
|
@ -111,6 +111,7 @@ Starting weiro without any arguments will start the server.
|
|||
lh := handlers.LoginHandler{Config: cfg, AuthService: svcs.Auth}
|
||||
ph := handlers.PostsHandler{PostService: svcs.Posts}
|
||||
uh := handlers.UploadsHandler{UploadsService: svcs.Uploads}
|
||||
ssh := handlers.SiteSettingsHandler{SiteService: svcs.Sites}
|
||||
|
||||
app.Get("/login", lh.Login)
|
||||
app.Post("/login", lh.DoLogin)
|
||||
|
|
@ -137,6 +138,9 @@ Starting weiro without any arguments will start the server.
|
|||
siteGroup.Post("/uploads/pending/:guid/finalize", uh.UploadComplete)
|
||||
siteGroup.Delete("/uploads/:uploadID", uh.Delete)
|
||||
|
||||
siteGroup.Get("/settings", ssh.General)
|
||||
siteGroup.Post("/settings", ssh.UpdateGeneral)
|
||||
|
||||
app.Get("/", middleware.OptionalUser(svcs.Auth), ih.Index)
|
||||
app.Get("/first-run", ih.FirstRun)
|
||||
app.Post("/first-run", ih.FirstRunSubmit)
|
||||
|
|
|
|||
|
|
@ -152,15 +152,3 @@ func (ph PostsHandler) Delete(c fiber.Ctx) error {
|
|||
return c.Redirect().To("/")
|
||||
}))
|
||||
}
|
||||
|
||||
func (ph PostsHandler) Rebuild(c fiber.Ctx) error {
|
||||
if err := ph.PostService.RebuildSite(c.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return accepts(c, json(func() any {
|
||||
return fiber.Map{}
|
||||
}), html(func(c fiber.Ctx) error {
|
||||
return c.Redirect().To("/")
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
52
handlers/sitesettings.go
Normal file
52
handlers/sitesettings.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"lmika.dev/lmika/weiro/models"
|
||||
"lmika.dev/lmika/weiro/services/sites"
|
||||
)
|
||||
|
||||
type SiteSettingsHandler struct {
|
||||
SiteService *sites.Service
|
||||
}
|
||||
|
||||
func (s *SiteSettingsHandler) General(ctx fiber.Ctx) error {
|
||||
site := ctx.Locals("site").(models.Site)
|
||||
|
||||
return ctx.Render("sitesettings/general", fiber.Map{
|
||||
"site": site,
|
||||
"tzones": sites.ListZones(),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *SiteSettingsHandler) UpdateGeneral(c fiber.Ctx) error {
|
||||
site := c.Locals("site").(models.Site)
|
||||
|
||||
var params sites.UpdateSiteSettingsParams
|
||||
if err := c.Bind().Body(¶ms); err != nil {
|
||||
return err
|
||||
}
|
||||
params.SiteID = site.ID
|
||||
|
||||
if _, err := s.SiteService.UpdateSiteSettings(c.Context(), params); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Redirect().To(fmt.Sprintf("/sites/%v/settings", +site.ID))
|
||||
}
|
||||
|
||||
func (ph PostsHandler) Rebuild(c fiber.Ctx) error {
|
||||
site := c.Locals("site").(models.Site)
|
||||
|
||||
if err := ph.PostService.RebuildSite(c.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return accepts(c, json(func() any {
|
||||
return fiber.Map{}
|
||||
}), html(func(c fiber.Ctx) error {
|
||||
return c.Redirect().To(fmt.Sprintf("/sites/%v/settings", +site.ID))
|
||||
}))
|
||||
}
|
||||
|
|
@ -27,8 +27,9 @@ type Site struct {
|
|||
GUID string
|
||||
Created time.Time
|
||||
|
||||
Title string
|
||||
Tagline string
|
||||
Title string
|
||||
Tagline string
|
||||
Timezone string
|
||||
}
|
||||
|
||||
type SitePublishTarget struct {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ type Site struct {
|
|||
Title string
|
||||
Tagline string
|
||||
CreatedAt int64
|
||||
Timezone string
|
||||
}
|
||||
|
||||
type Upload struct {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@ INSERT INTO sites (
|
|||
guid,
|
||||
title,
|
||||
tagline,
|
||||
timezone,
|
||||
created_at
|
||||
) VALUES (?, ?, ?, ?, ?)
|
||||
) VALUES (?, ?, ?, ?, ?, ?)
|
||||
RETURNING id
|
||||
`
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ type InsertSiteParams struct {
|
|||
Guid string
|
||||
Title string
|
||||
Tagline string
|
||||
Timezone string
|
||||
CreatedAt int64
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +48,7 @@ func (q *Queries) InsertSite(ctx context.Context, arg InsertSiteParams) (int64,
|
|||
arg.Guid,
|
||||
arg.Title,
|
||||
arg.Tagline,
|
||||
arg.Timezone,
|
||||
arg.CreatedAt,
|
||||
)
|
||||
var id int64
|
||||
|
|
@ -98,7 +101,7 @@ func (q *Queries) SelectAllSitesWithOwners(ctx context.Context) ([]SelectAllSite
|
|||
}
|
||||
|
||||
const selectSiteByGUID = `-- name: SelectSiteByGUID :one
|
||||
SELECT id, owner_id, guid, title, tagline, created_at FROM sites WHERE guid = ?
|
||||
SELECT id, owner_id, guid, title, tagline, created_at, timezone FROM sites WHERE guid = ?
|
||||
`
|
||||
|
||||
func (q *Queries) SelectSiteByGUID(ctx context.Context, guid string) (Site, error) {
|
||||
|
|
@ -111,12 +114,13 @@ func (q *Queries) SelectSiteByGUID(ctx context.Context, guid string) (Site, erro
|
|||
&i.Title,
|
||||
&i.Tagline,
|
||||
&i.CreatedAt,
|
||||
&i.Timezone,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const selectSiteByID = `-- name: SelectSiteByID :one
|
||||
SELECT id, owner_id, guid, title, tagline, created_at FROM sites WHERE id = ?
|
||||
SELECT id, owner_id, guid, title, tagline, created_at, timezone FROM sites WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) SelectSiteByID(ctx context.Context, id int64) (Site, error) {
|
||||
|
|
@ -129,12 +133,13 @@ func (q *Queries) SelectSiteByID(ctx context.Context, id int64) (Site, error) {
|
|||
&i.Title,
|
||||
&i.Tagline,
|
||||
&i.CreatedAt,
|
||||
&i.Timezone,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const selectSitesOwnedByUser = `-- name: SelectSitesOwnedByUser :many
|
||||
SELECT id, owner_id, guid, title, tagline, created_at FROM sites WHERE owner_id = ? ORDER BY title ASC
|
||||
SELECT id, owner_id, guid, title, tagline, created_at, timezone FROM sites WHERE owner_id = ? ORDER BY title ASC
|
||||
`
|
||||
|
||||
func (q *Queries) SelectSitesOwnedByUser(ctx context.Context, ownerID int64) ([]Site, error) {
|
||||
|
|
@ -153,6 +158,7 @@ func (q *Queries) SelectSitesOwnedByUser(ctx context.Context, ownerID int64) ([]
|
|||
&i.Title,
|
||||
&i.Tagline,
|
||||
&i.CreatedAt,
|
||||
&i.Timezone,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -166,3 +172,24 @@ func (q *Queries) SelectSitesOwnedByUser(ctx context.Context, ownerID int64) ([]
|
|||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const updateSite = `-- name: UpdateSite :exec
|
||||
UPDATE sites SET title = ?, tagline = ?, timezone = ? WHERE id = ?
|
||||
`
|
||||
|
||||
type UpdateSiteParams struct {
|
||||
Title string
|
||||
Tagline string
|
||||
Timezone string
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateSite(ctx context.Context, arg UpdateSiteParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateSite,
|
||||
arg.Title,
|
||||
arg.Tagline,
|
||||
arg.Timezone,
|
||||
arg.ID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ func (db *Provider) SaveSite(ctx context.Context, site *models.Site) error {
|
|||
Guid: site.GUID,
|
||||
Title: site.Title,
|
||||
Tagline: site.Tagline,
|
||||
Timezone: site.Timezone,
|
||||
CreatedAt: timeToInt(site.Created),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -55,8 +56,12 @@ func (db *Provider) SaveSite(ctx context.Context, site *models.Site) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// No update query defined in sqlgen yet
|
||||
return nil
|
||||
return db.queries.UpdateSite(ctx, sqlgen.UpdateSiteParams{
|
||||
Title: site.Title,
|
||||
Tagline: site.Tagline,
|
||||
Timezone: site.Timezone,
|
||||
ID: site.ID,
|
||||
})
|
||||
}
|
||||
|
||||
func (db *Provider) HasUsersAndSites(ctx context.Context) (bool, error) {
|
||||
|
|
@ -96,11 +101,12 @@ func (db *Provider) SelectAllSitesWithOwners(ctx context.Context) ([]SiteWithOwn
|
|||
|
||||
func dbSiteToSite(row sqlgen.Site) models.Site {
|
||||
return models.Site{
|
||||
ID: row.ID,
|
||||
OwnerID: row.OwnerID,
|
||||
GUID: row.Guid,
|
||||
Title: row.Title,
|
||||
Tagline: row.Tagline,
|
||||
Created: time.Unix(row.CreatedAt, 0).UTC(),
|
||||
ID: row.ID,
|
||||
OwnerID: row.OwnerID,
|
||||
GUID: row.Guid,
|
||||
Title: row.Title,
|
||||
Timezone: row.Timezone,
|
||||
Tagline: row.Tagline,
|
||||
Created: time.Unix(row.CreatedAt, 0).UTC(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,13 +32,20 @@ func (s *Service) UpdatePost(ctx context.Context, params CreatePostParams) (*mod
|
|||
post.Title = params.Title
|
||||
post.Body = params.Body
|
||||
post.UpdatedAt = now
|
||||
post.Slug = post.BestSlug()
|
||||
oldState := post.State
|
||||
|
||||
switch strings.ToLower(params.Action) {
|
||||
case "publish":
|
||||
post.State = models.StatePublished
|
||||
post.PublishedAt = now
|
||||
|
||||
// Set the published at with the site timezone, and reset the slug, so that the date
|
||||
// is in the site timezone.
|
||||
renderTZ, err := time.LoadLocation(site.Timezone)
|
||||
if err != nil {
|
||||
renderTZ = time.UTC
|
||||
}
|
||||
post.PublishedAt = now.In(renderTZ)
|
||||
post.Slug = post.BestSlug()
|
||||
case "save draft":
|
||||
post.State = models.StateDraft
|
||||
post.PublishedAt = time.Time{}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"iter"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"emperror.dev/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
|
|
@ -71,10 +72,16 @@ func (p *Publisher) Publish(ctx context.Context, site models.Site) error {
|
|||
}
|
||||
|
||||
func (p *Publisher) publishSite(ctx context.Context, pubSite pubmodel.Site, target models.SitePublishTarget) error {
|
||||
renderTZ, err := time.LoadLocation(pubSite.Timezone)
|
||||
if err != nil {
|
||||
renderTZ = time.UTC
|
||||
}
|
||||
|
||||
sb, err := sitebuilder.New(pubSite, sitebuilder.Options{
|
||||
BasePosts: "/posts",
|
||||
TemplatesFS: simplecss.FS,
|
||||
FeedItems: 30,
|
||||
RenderTZ: renderTZ,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -77,10 +77,11 @@ func (s *Service) FirstRun(ctx context.Context, req FirstRunRequest) (newUser mo
|
|||
}
|
||||
|
||||
newSite = models.Site{
|
||||
Title: defaultIfEmpty(req.SiteName, "New Site"),
|
||||
GUID: models.NewNanoID(),
|
||||
OwnerID: newUser.ID,
|
||||
Created: time.Now(),
|
||||
Title: defaultIfEmpty(req.SiteName, "New Site"),
|
||||
GUID: models.NewNanoID(),
|
||||
OwnerID: newUser.ID,
|
||||
Timezone: "UTC",
|
||||
Created: time.Now(),
|
||||
}
|
||||
if err := s.db.SaveSite(ctx, &newSite); err != nil {
|
||||
return newUser, newSite, err
|
||||
|
|
@ -126,3 +127,32 @@ func (s *Service) GetSiteByID(ctx context.Context, siteID int64) (models.Site, e
|
|||
func (s *Service) ListAllSitesWithOwners(ctx context.Context) ([]db.SiteWithOwner, error) {
|
||||
return s.db.SelectAllSitesWithOwners(ctx)
|
||||
}
|
||||
|
||||
type UpdateSiteSettingsParams struct {
|
||||
SiteID int64 `form:"siteID"`
|
||||
Name string `form:"name"`
|
||||
Tagline string `form:"tagline"`
|
||||
Timezone string `form:"timezone"`
|
||||
}
|
||||
|
||||
func (s *Service) UpdateSiteSettings(ctx context.Context, params UpdateSiteSettingsParams) (models.Site, error) {
|
||||
site, err := s.GetSiteByID(ctx, params.SiteID)
|
||||
if err != nil {
|
||||
return models.Site{}, err
|
||||
}
|
||||
|
||||
_, err = time.LoadLocation(params.Timezone)
|
||||
if err != nil {
|
||||
return models.Site{}, errors.Wrap(err, "invalid timezone")
|
||||
}
|
||||
|
||||
site.Title = params.Name
|
||||
site.Tagline = params.Tagline
|
||||
site.Timezone = params.Timezone
|
||||
|
||||
if err := s.db.SaveSite(ctx, &site); err != nil {
|
||||
return models.Site{}, err
|
||||
}
|
||||
|
||||
return site, nil
|
||||
}
|
||||
|
|
|
|||
23
services/sites/tzones.go
Normal file
23
services/sites/tzones.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package sites
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//go:embed tzones.txt
|
||||
var tzonesFS embed.FS
|
||||
|
||||
var loadZones = sync.OnceValue(func() []string {
|
||||
zones, err := tzonesFS.ReadFile("tzones.txt")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return strings.Split(string(zones), "\n")
|
||||
})
|
||||
|
||||
func ListZones() []string {
|
||||
return loadZones()
|
||||
}
|
||||
606
services/sites/tzones.txt
Normal file
606
services/sites/tzones.txt
Normal file
|
|
@ -0,0 +1,606 @@
|
|||
Africa/Abidjan
|
||||
Africa/Accra
|
||||
Africa/Addis_Ababa
|
||||
Africa/Algiers
|
||||
Africa/Asmara
|
||||
Africa/Asmera
|
||||
Africa/Bamako
|
||||
Africa/Bangui
|
||||
Africa/Banjul
|
||||
Africa/Bissau
|
||||
Africa/Blantyre
|
||||
Africa/Brazzaville
|
||||
Africa/Bujumbura
|
||||
Africa/Cairo
|
||||
Africa/Casablanca
|
||||
Africa/Ceuta
|
||||
Africa/Conakry
|
||||
Africa/Dakar
|
||||
Africa/Dar_es_Salaam
|
||||
Africa/Djibouti
|
||||
Africa/Douala
|
||||
Africa/El_Aaiun
|
||||
Africa/Freetown
|
||||
Africa/Gaborone
|
||||
Africa/Harare
|
||||
Africa/Johannesburg
|
||||
Africa/Juba
|
||||
Africa/Kampala
|
||||
Africa/Khartoum
|
||||
Africa/Kigali
|
||||
Africa/Kinshasa
|
||||
Africa/Lagos
|
||||
Africa/Libreville
|
||||
Africa/Lome
|
||||
Africa/Luanda
|
||||
Africa/Lubumbashi
|
||||
Africa/Lusaka
|
||||
Africa/Malabo
|
||||
Africa/Maputo
|
||||
Africa/Maseru
|
||||
Africa/Mbabane
|
||||
Africa/Mogadishu
|
||||
Africa/Monrovia
|
||||
Africa/Nairobi
|
||||
Africa/Ndjamena
|
||||
Africa/Niamey
|
||||
Africa/Nouakchott
|
||||
Africa/Ouagadougou
|
||||
Africa/Porto-Novo
|
||||
Africa/Sao_Tome
|
||||
Africa/Timbuktu
|
||||
Africa/Tripoli
|
||||
Africa/Tunis
|
||||
Africa/Windhoek
|
||||
America/Adak
|
||||
America/Anchorage
|
||||
America/Anguilla
|
||||
America/Antigua
|
||||
America/Araguaina
|
||||
America/Argentina/Buenos_Aires
|
||||
America/Argentina/Catamarca
|
||||
America/Argentina/ComodRivadavia
|
||||
America/Argentina/Cordoba
|
||||
America/Argentina/Jujuy
|
||||
America/Argentina/La_Rioja
|
||||
America/Argentina/Mendoza
|
||||
America/Argentina/Rio_Gallegos
|
||||
America/Argentina/Salta
|
||||
America/Argentina/San_Juan
|
||||
America/Argentina/San_Luis
|
||||
America/Argentina/Tucuman
|
||||
America/Argentina/Ushuaia
|
||||
America/Aruba
|
||||
America/Asuncion
|
||||
America/Atikokan
|
||||
America/Atka
|
||||
America/Bahia
|
||||
America/Bahia_Banderas
|
||||
America/Barbados
|
||||
America/Belem
|
||||
America/Belize
|
||||
America/Blanc-Sablon
|
||||
America/Boa_Vista
|
||||
America/Bogota
|
||||
America/Boise
|
||||
America/Buenos_Aires
|
||||
America/Cambridge_Bay
|
||||
America/Campo_Grande
|
||||
America/Cancun
|
||||
America/Caracas
|
||||
America/Catamarca
|
||||
America/Cayenne
|
||||
America/Cayman
|
||||
America/Chicago
|
||||
America/Chihuahua
|
||||
America/Coral_Harbour
|
||||
America/Cordoba
|
||||
America/Costa_Rica
|
||||
America/Creston
|
||||
America/Cuiaba
|
||||
America/Curacao
|
||||
America/Danmarkshavn
|
||||
America/Dawson
|
||||
America/Dawson_Creek
|
||||
America/Denver
|
||||
America/Detroit
|
||||
America/Dominica
|
||||
America/Edmonton
|
||||
America/Eirunepe
|
||||
America/El_Salvador
|
||||
America/Ensenada
|
||||
America/Fort_Nelson
|
||||
America/Fort_Wayne
|
||||
America/Fortaleza
|
||||
America/Glace_Bay
|
||||
America/Godthab
|
||||
America/Goose_Bay
|
||||
America/Grand_Turk
|
||||
America/Grenada
|
||||
America/Guadeloupe
|
||||
America/Guatemala
|
||||
America/Guayaquil
|
||||
America/Guyana
|
||||
America/Halifax
|
||||
America/Havana
|
||||
America/Hermosillo
|
||||
America/Indiana/Indianapolis
|
||||
America/Indiana/Knox
|
||||
America/Indiana/Marengo
|
||||
America/Indiana/Petersburg
|
||||
America/Indiana/Tell_City
|
||||
America/Indiana/Vevay
|
||||
America/Indiana/Vincennes
|
||||
America/Indiana/Winamac
|
||||
America/Indianapolis
|
||||
America/Inuvik
|
||||
America/Iqaluit
|
||||
America/Jamaica
|
||||
America/Jujuy
|
||||
America/Juneau
|
||||
America/Kentucky/Louisville
|
||||
America/Kentucky/Monticello
|
||||
America/Knox_IN
|
||||
America/Kralendijk
|
||||
America/La_Paz
|
||||
America/Lima
|
||||
America/Los_Angeles
|
||||
America/Louisville
|
||||
America/Lower_Princes
|
||||
America/Maceio
|
||||
America/Managua
|
||||
America/Manaus
|
||||
America/Marigot
|
||||
America/Martinique
|
||||
America/Matamoros
|
||||
America/Mazatlan
|
||||
America/Mendoza
|
||||
America/Menominee
|
||||
America/Merida
|
||||
America/Metlakatla
|
||||
America/Mexico_City
|
||||
America/Miquelon
|
||||
America/Moncton
|
||||
America/Monterrey
|
||||
America/Montevideo
|
||||
America/Montreal
|
||||
America/Montserrat
|
||||
America/Nassau
|
||||
America/New_York
|
||||
America/Nipigon
|
||||
America/Nome
|
||||
America/Noronha
|
||||
America/North_Dakota/Beulah
|
||||
America/North_Dakota/Center
|
||||
America/North_Dakota/New_Salem
|
||||
America/Ojinaga
|
||||
America/Panama
|
||||
America/Pangnirtung
|
||||
America/Paramaribo
|
||||
America/Phoenix
|
||||
America/Port-au-Prince
|
||||
America/Port_of_Spain
|
||||
America/Porto_Acre
|
||||
America/Porto_Velho
|
||||
America/Puerto_Rico
|
||||
America/Punta_Arenas
|
||||
America/Rainy_River
|
||||
America/Rankin_Inlet
|
||||
America/Recife
|
||||
America/Regina
|
||||
America/Resolute
|
||||
America/Rio_Branco
|
||||
America/Rosario
|
||||
America/Santa_Isabel
|
||||
America/Santarem
|
||||
America/Santiago
|
||||
America/Santo_Domingo
|
||||
America/Sao_Paulo
|
||||
America/Scoresbysund
|
||||
America/Shiprock
|
||||
America/Sitka
|
||||
America/St_Barthelemy
|
||||
America/St_Johns
|
||||
America/St_Kitts
|
||||
America/St_Lucia
|
||||
America/St_Thomas
|
||||
America/St_Vincent
|
||||
America/Swift_Current
|
||||
America/Tegucigalpa
|
||||
America/Thule
|
||||
America/Thunder_Bay
|
||||
America/Tijuana
|
||||
America/Toronto
|
||||
America/Tortola
|
||||
America/Vancouver
|
||||
America/Virgin
|
||||
America/Whitehorse
|
||||
America/Winnipeg
|
||||
America/Yakutat
|
||||
America/Yellowknife
|
||||
Antarctica/Casey
|
||||
Antarctica/Davis
|
||||
Antarctica/DumontDUrville
|
||||
Antarctica/Macquarie
|
||||
Antarctica/Mawson
|
||||
Antarctica/McMurdo
|
||||
Antarctica/Palmer
|
||||
Antarctica/Rothera
|
||||
Antarctica/South_Pole
|
||||
Antarctica/Syowa
|
||||
Antarctica/Troll
|
||||
Antarctica/Vostok
|
||||
Arctic/Longyearbyen
|
||||
Asia/Aden
|
||||
Asia/Almaty
|
||||
Asia/Amman
|
||||
Asia/Anadyr
|
||||
Asia/Aqtau
|
||||
Asia/Aqtobe
|
||||
Asia/Ashgabat
|
||||
Asia/Ashkhabad
|
||||
Asia/Atyrau
|
||||
Asia/Baghdad
|
||||
Asia/Bahrain
|
||||
Asia/Baku
|
||||
Asia/Bangkok
|
||||
Asia/Barnaul
|
||||
Asia/Beirut
|
||||
Asia/Bishkek
|
||||
Asia/Brunei
|
||||
Asia/Calcutta
|
||||
Asia/Chita
|
||||
Asia/Choibalsan
|
||||
Asia/Chongqing
|
||||
Asia/Chungking
|
||||
Asia/Colombo
|
||||
Asia/Dacca
|
||||
Asia/Damascus
|
||||
Asia/Dhaka
|
||||
Asia/Dili
|
||||
Asia/Dubai
|
||||
Asia/Dushanbe
|
||||
Asia/Famagusta
|
||||
Asia/Gaza
|
||||
Asia/Harbin
|
||||
Asia/Hebron
|
||||
Asia/Ho_Chi_Minh
|
||||
Asia/Hong_Kong
|
||||
Asia/Hovd
|
||||
Asia/Irkutsk
|
||||
Asia/Istanbul
|
||||
Asia/Jakarta
|
||||
Asia/Jayapura
|
||||
Asia/Jerusalem
|
||||
Asia/Kabul
|
||||
Asia/Kamchatka
|
||||
Asia/Karachi
|
||||
Asia/Kashgar
|
||||
Asia/Kathmandu
|
||||
Asia/Katmandu
|
||||
Asia/Khandyga
|
||||
Asia/Kolkata
|
||||
Asia/Krasnoyarsk
|
||||
Asia/Kuala_Lumpur
|
||||
Asia/Kuching
|
||||
Asia/Kuwait
|
||||
Asia/Macao
|
||||
Asia/Macau
|
||||
Asia/Magadan
|
||||
Asia/Makassar
|
||||
Asia/Manila
|
||||
Asia/Muscat
|
||||
Asia/Nicosia
|
||||
Asia/Novokuznetsk
|
||||
Asia/Novosibirsk
|
||||
Asia/Omsk
|
||||
Asia/Oral
|
||||
Asia/Phnom_Penh
|
||||
Asia/Pontianak
|
||||
Asia/Pyongyang
|
||||
Asia/Qatar
|
||||
Asia/Qyzylorda
|
||||
Asia/Rangoon
|
||||
Asia/Riyadh
|
||||
Asia/Saigon
|
||||
Asia/Sakhalin
|
||||
Asia/Samarkand
|
||||
Asia/Seoul
|
||||
Asia/Shanghai
|
||||
Asia/Singapore
|
||||
Asia/Srednekolymsk
|
||||
Asia/Taipei
|
||||
Asia/Tashkent
|
||||
Asia/Tbilisi
|
||||
Asia/Tehran
|
||||
Asia/Tel_Aviv
|
||||
Asia/Thimbu
|
||||
Asia/Thimphu
|
||||
Asia/Tokyo
|
||||
Asia/Tomsk
|
||||
Asia/Ujung_Pandang
|
||||
Asia/Ulaanbaatar
|
||||
Asia/Ulan_Bator
|
||||
Asia/Urumqi
|
||||
Asia/Ust-Nera
|
||||
Asia/Vientiane
|
||||
Asia/Vladivostok
|
||||
Asia/Yakutsk
|
||||
Asia/Yangon
|
||||
Asia/Yekaterinburg
|
||||
Asia/Yerevan
|
||||
Atlantic/Azores
|
||||
Atlantic/Bermuda
|
||||
Atlantic/Canary
|
||||
Atlantic/Cape_Verde
|
||||
Atlantic/Faeroe
|
||||
Atlantic/Faroe
|
||||
Atlantic/Jan_Mayen
|
||||
Atlantic/Madeira
|
||||
Atlantic/Reykjavik
|
||||
Atlantic/South_Georgia
|
||||
Atlantic/St_Helena
|
||||
Atlantic/Stanley
|
||||
Australia/ACT
|
||||
Australia/Adelaide
|
||||
Australia/Brisbane
|
||||
Australia/Broken_Hill
|
||||
Australia/Canberra
|
||||
Australia/Currie
|
||||
Australia/Darwin
|
||||
Australia/Eucla
|
||||
Australia/Hobart
|
||||
Australia/LHI
|
||||
Australia/Lindeman
|
||||
Australia/Lord_Howe
|
||||
Australia/Melbourne
|
||||
Australia/NSW
|
||||
Australia/North
|
||||
Australia/Perth
|
||||
Australia/Queensland
|
||||
Australia/South
|
||||
Australia/Sydney
|
||||
Australia/Tasmania
|
||||
Australia/Victoria
|
||||
Australia/West
|
||||
Australia/Yancowinna
|
||||
Brazil/Acre
|
||||
Brazil/DeNoronha
|
||||
Brazil/East
|
||||
Brazil/West
|
||||
CET
|
||||
CST6CDT
|
||||
Canada/Atlantic
|
||||
Canada/Central
|
||||
Canada/Eastern
|
||||
Canada/Mountain
|
||||
Canada/Newfoundland
|
||||
Canada/Pacific
|
||||
Canada/Saskatchewan
|
||||
Canada/Yukon
|
||||
Chile/Continental
|
||||
Chile/EasterIsland
|
||||
Cuba
|
||||
EET
|
||||
EST
|
||||
EST5EDT
|
||||
Egypt
|
||||
Eire
|
||||
Etc/GMT
|
||||
Etc/GMT+0
|
||||
Etc/GMT+1
|
||||
Etc/GMT+10
|
||||
Etc/GMT+11
|
||||
Etc/GMT+12
|
||||
Etc/GMT+2
|
||||
Etc/GMT+3
|
||||
Etc/GMT+4
|
||||
Etc/GMT+5
|
||||
Etc/GMT+6
|
||||
Etc/GMT+7
|
||||
Etc/GMT+8
|
||||
Etc/GMT+9
|
||||
Etc/GMT-0
|
||||
Etc/GMT-1
|
||||
Etc/GMT-10
|
||||
Etc/GMT-11
|
||||
Etc/GMT-12
|
||||
Etc/GMT-13
|
||||
Etc/GMT-14
|
||||
Etc/GMT-2
|
||||
Etc/GMT-3
|
||||
Etc/GMT-4
|
||||
Etc/GMT-5
|
||||
Etc/GMT-6
|
||||
Etc/GMT-7
|
||||
Etc/GMT-8
|
||||
Etc/GMT-9
|
||||
Etc/GMT0
|
||||
Etc/Greenwich
|
||||
Etc/UCT
|
||||
Etc/UTC
|
||||
Etc/Universal
|
||||
Etc/Zulu
|
||||
Europe/Amsterdam
|
||||
Europe/Andorra
|
||||
Europe/Astrakhan
|
||||
Europe/Athens
|
||||
Europe/Belfast
|
||||
Europe/Belgrade
|
||||
Europe/Berlin
|
||||
Europe/Bratislava
|
||||
Europe/Brussels
|
||||
Europe/Bucharest
|
||||
Europe/Budapest
|
||||
Europe/Busingen
|
||||
Europe/Chisinau
|
||||
Europe/Copenhagen
|
||||
Europe/Dublin
|
||||
Europe/Gibraltar
|
||||
Europe/Guernsey
|
||||
Europe/Helsinki
|
||||
Europe/Isle_of_Man
|
||||
Europe/Istanbul
|
||||
Europe/Jersey
|
||||
Europe/Kaliningrad
|
||||
Europe/Kiev
|
||||
Europe/Kirov
|
||||
Europe/Lisbon
|
||||
Europe/Ljubljana
|
||||
Europe/London
|
||||
Europe/Luxembourg
|
||||
Europe/Madrid
|
||||
Europe/Malta
|
||||
Europe/Mariehamn
|
||||
Europe/Minsk
|
||||
Europe/Monaco
|
||||
Europe/Moscow
|
||||
Europe/Nicosia
|
||||
Europe/Oslo
|
||||
Europe/Paris
|
||||
Europe/Podgorica
|
||||
Europe/Prague
|
||||
Europe/Riga
|
||||
Europe/Rome
|
||||
Europe/Samara
|
||||
Europe/San_Marino
|
||||
Europe/Sarajevo
|
||||
Europe/Saratov
|
||||
Europe/Simferopol
|
||||
Europe/Skopje
|
||||
Europe/Sofia
|
||||
Europe/Stockholm
|
||||
Europe/Tallinn
|
||||
Europe/Tirane
|
||||
Europe/Tiraspol
|
||||
Europe/Ulyanovsk
|
||||
Europe/Uzhgorod
|
||||
Europe/Vaduz
|
||||
Europe/Vatican
|
||||
Europe/Vienna
|
||||
Europe/Vilnius
|
||||
Europe/Volgograd
|
||||
Europe/Warsaw
|
||||
Europe/Zagreb
|
||||
Europe/Zaporozhye
|
||||
Europe/Zurich
|
||||
Factory
|
||||
GB
|
||||
GB-Eire
|
||||
GMT
|
||||
GMT+0
|
||||
GMT-0
|
||||
GMT0
|
||||
Greenwich
|
||||
HST
|
||||
Hongkong
|
||||
Iceland
|
||||
Indian/Antananarivo
|
||||
Indian/Chagos
|
||||
Indian/Christmas
|
||||
Indian/Cocos
|
||||
Indian/Comoro
|
||||
Indian/Kerguelen
|
||||
Indian/Mahe
|
||||
Indian/Maldives
|
||||
Indian/Mauritius
|
||||
Indian/Mayotte
|
||||
Indian/Reunion
|
||||
Iran
|
||||
Israel
|
||||
Jamaica
|
||||
Japan
|
||||
Kwajalein
|
||||
Libya
|
||||
MET
|
||||
MST
|
||||
MST7MDT
|
||||
Mexico/BajaNorte
|
||||
Mexico/BajaSur
|
||||
Mexico/General
|
||||
NZ
|
||||
NZ-CHAT
|
||||
Navajo
|
||||
PRC
|
||||
PST8PDT
|
||||
Pacific/Apia
|
||||
Pacific/Auckland
|
||||
Pacific/Bougainville
|
||||
Pacific/Chatham
|
||||
Pacific/Chuuk
|
||||
Pacific/Easter
|
||||
Pacific/Efate
|
||||
Pacific/Enderbury
|
||||
Pacific/Fakaofo
|
||||
Pacific/Fiji
|
||||
Pacific/Funafuti
|
||||
Pacific/Galapagos
|
||||
Pacific/Gambier
|
||||
Pacific/Guadalcanal
|
||||
Pacific/Guam
|
||||
Pacific/Honolulu
|
||||
Pacific/Johnston
|
||||
Pacific/Kiritimati
|
||||
Pacific/Kosrae
|
||||
Pacific/Kwajalein
|
||||
Pacific/Majuro
|
||||
Pacific/Marquesas
|
||||
Pacific/Midway
|
||||
Pacific/Nauru
|
||||
Pacific/Niue
|
||||
Pacific/Norfolk
|
||||
Pacific/Noumea
|
||||
Pacific/Pago_Pago
|
||||
Pacific/Palau
|
||||
Pacific/Pitcairn
|
||||
Pacific/Pohnpei
|
||||
Pacific/Ponape
|
||||
Pacific/Port_Moresby
|
||||
Pacific/Rarotonga
|
||||
Pacific/Saipan
|
||||
Pacific/Samoa
|
||||
Pacific/Tahiti
|
||||
Pacific/Tarawa
|
||||
Pacific/Tongatapu
|
||||
Pacific/Truk
|
||||
Pacific/Wake
|
||||
Pacific/Wallis
|
||||
Pacific/Yap
|
||||
Poland
|
||||
Portugal
|
||||
ROC
|
||||
ROK
|
||||
Singapore
|
||||
SystemV/AST4
|
||||
SystemV/AST4ADT
|
||||
SystemV/CST6
|
||||
SystemV/CST6CDT
|
||||
SystemV/EST5
|
||||
SystemV/EST5EDT
|
||||
SystemV/HST10
|
||||
SystemV/MST7
|
||||
SystemV/MST7MDT
|
||||
SystemV/PST8
|
||||
SystemV/PST8PDT
|
||||
SystemV/YST9
|
||||
SystemV/YST9YDT
|
||||
Turkey
|
||||
UCT
|
||||
US/Alaska
|
||||
US/Aleutian
|
||||
US/Arizona
|
||||
US/Central
|
||||
US/East-Indiana
|
||||
US/Eastern
|
||||
US/Hawaii
|
||||
US/Indiana-Starke
|
||||
US/Michigan
|
||||
US/Mountain
|
||||
US/Pacific
|
||||
US/Pacific-New
|
||||
US/Samoa
|
||||
UTC
|
||||
Universal
|
||||
W-SU
|
||||
WET
|
||||
Zulu
|
||||
|
|
@ -13,13 +13,17 @@ INSERT INTO sites (
|
|||
guid,
|
||||
title,
|
||||
tagline,
|
||||
timezone,
|
||||
created_at
|
||||
) VALUES (?, ?, ?, ?, ?)
|
||||
) VALUES (?, ?, ?, ?, ?, ?)
|
||||
RETURNING id;
|
||||
|
||||
-- name: HasUsersAndSites :one
|
||||
SELECT (SELECT COUNT(*) FROM users) > 0 AND (SELECT COUNT(*) FROM sites) > 0 AS has_users_and_sites;
|
||||
|
||||
-- name: UpdateSite :exec
|
||||
UPDATE sites SET title = ?, tagline = ?, timezone = ? WHERE id = ?;
|
||||
|
||||
-- name: SelectAllSitesWithOwners :many
|
||||
SELECT s.id, s.guid, s.title, s.owner_id, u.username
|
||||
FROM sites s
|
||||
|
|
|
|||
1
sql/schema/03_add_loc_to_site.up.sql
Normal file
1
sql/schema/03_add_loc_to_site.up.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE sites ADD COLUMN timezone TEXT NOT NULL DEFAULT 'UTC';
|
||||
|
|
@ -13,6 +13,9 @@
|
|||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="/sites/{{.site.ID}}/uploads">Uploads</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="/sites/{{.site.ID}}/settings">Settings</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="d-flex align-items-center" role="search">
|
||||
<!--
|
||||
|
|
|
|||
|
|
@ -3,9 +3,6 @@
|
|||
<div class="my-4 d-flex justify-content-between align-items-baseline">
|
||||
<div>
|
||||
<a href="/sites/{{ .site.ID }}/posts/new" class="btn btn-success">New Post</a>
|
||||
<form action="/sites/{{ .site.ID }}/rebuild" method="post" style="display: inline-block;">
|
||||
<input type="submit" class="btn btn-outline-primary" value="Rebuild Site">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
|||
63
views/sitesettings/general.html
Normal file
63
views/sitesettings/general.html
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<main class="container">
|
||||
<!--
|
||||
<ul class="nav nav-pills justify-content-center my-3">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="#">General</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Feeds</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Publish</a>
|
||||
</li>
|
||||
</ul>
|
||||
-->
|
||||
|
||||
<div>
|
||||
<form method="post" action="/sites/{{ .site.ID }}/settings">
|
||||
<div>
|
||||
<h5 class="my-4">Site Settings</h5>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="siteName" class="col-sm-3 col-form-label text-end">Site Name</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="siteName" name="name" value="{{ .site.Title }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="siteTagline" class="col-sm-3 col-form-label text-end">Site Tagline</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="siteTagline" name="tagline" value="{{ .site.Tagline }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="timezone" class="col-sm-3 col-form-label text-end">Timezone</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" list="tzoneList" class="form-control" id="timezone" name="timezone" value="{{ .site.Timezone }}">
|
||||
<datalist id="tzoneList">
|
||||
{{ range .tzones }}
|
||||
<option value="{{ . }}">{{ . }}</option>
|
||||
{{ end }}
|
||||
</datalist>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3"></div>
|
||||
<div class="col-sm-9"><button type="submit" class="btn btn-primary">Save Settings</button></div>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<div>
|
||||
<h5 class="my-4">Manage</h5>
|
||||
</div>
|
||||
<form action="/sites/{{ .site.ID }}/rebuild" method="post">
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-3"></div>
|
||||
<div class="col-sm-9">
|
||||
<button type="submit" class="btn btn-secondary">Rebuild</button>
|
||||
<span class="form-text mx-3">Trigger a full rebuild of the site.</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
Loading…
Reference in a new issue