serve static content and styles
alex wennerberg alex@alexwennerberg.com
Fri, 23 Oct 2020 23:56:38 -0700
10 files changed,
112 insertions(+),
21 deletions(-)
M
config.go
→
config.go
@@ -5,13 +5,14 @@ "github.com/BurntSushi/toml"
) type Config struct { - FilesDirectory string - RootDomain string - SiteTitle string - Debug bool - SecretKey string - DBFile string - PasswdFile string // TODO remove + FilesDirectory string + TemplatesDirectory string + RootDomain string + SiteTitle string + Debug bool + SecretKey string + DBFile string + PasswdFile string // TODO remove } func getConfig(filename string) (Config, error) {
M
flounder.toml
→
flounder.toml
@@ -1,4 +1,7 @@
SiteTitle="🐟flounder" RootDomain="localhost" FilesDirectory="./files" +# handles templates and static files +# everything in the static subfolder will be served at root +TemplatesDirectory="./templates" DBFile="./flounder.db"
M
http.go
→
http.go
@@ -24,6 +24,12 @@ }
} func indexHandler(w http.ResponseWriter, r *http.Request) { + // serve everything inside static directory + if r.URL.Path != "/" { + fileName := path.Join(c.TemplatesDirectory, "static", r.URL.Path) + http.ServeFile(w, r, fileName) + return + } indexFiles, err := getIndexFiles() if err != nil { log.Println(err)@@ -54,16 +60,24 @@
func editFileHandler(w http.ResponseWriter, r *http.Request) { // read file content. create if dne // authUser := "alex" - data := struct { - FileName string - FileText string - PageTitle string - }{"filename", "filetext", c.SiteTitle} - err := t.ExecuteTemplate(w, "edit_file.html", data) - if err != nil { - log.Println(err) - renderError(w, InternalServerErrorMsg, 500) - return + if r.Method == "GET" { + data := struct { + FileName string + FileText string + PageTitle string + }{"filename", "filetext", c.SiteTitle} + err := t.ExecuteTemplate(w, "edit_file.html", data) + if err != nil { + log.Println(err) + renderError(w, InternalServerErrorMsg, 500) + return + } + } else if r.Method == "POST" { + } +} + +func deleteFileHandler(w http.ResponseWriter, r *http.Request) { + if r.Method == "POST" { } }@@ -142,7 +156,9 @@ func userFile(w http.ResponseWriter, r *http.Request) {
userName := strings.Split(r.Host, ".")[0] fileName := path.Join(c.FilesDirectory, userName, r.URL.Path) extension := path.Ext(fileName) - log.Println(extension) + if r.URL.Path == "/static/style.css" { + http.ServeFile(w, r, path.Join(c.TemplatesDirectory, "static/style.css")) + } if extension == ".gmi" || extension == ".gemini" { if strings.Contains(fileName, "..") { // prevent directory traversal TODO verify@@ -152,7 +168,6 @@ // covert to html
stat, _ := os.Stat(fileName) file, _ := os.Open(fileName) htmlString := gmi.Parse(file).HTML() - log.Println(htmlString) reader := strings.NewReader(htmlString) w.Header().Set("Content-Type", "text/html") http.ServeContent(w, r, fileName, stat.ModTime(), reader)@@ -175,7 +190,7 @@ http.HandleFunc(c.RootDomain+"/my_site", mySiteHandler)
http.HandleFunc(c.RootDomain+"/edit/", editFileHandler) http.HandleFunc(c.RootDomain+"/login", loginHandler) http.HandleFunc(c.RootDomain+"/register", registerHandler) - // http.HandleFunc("/delete/", deleteFileHandler) + http.HandleFunc(c.RootDomain+"/delete/", deleteFileHandler) // login+register functions // handle user files based on subdomain
M
templates/header.html
→
templates/header.html
@@ -5,7 +5,7 @@ <head>
<meta charset="utf-8" /> <title>{{.PageTitle }}</title> <meta name="viewport" content="width=device-width" /> - <link rel="stylesheet" type="text/css" href="/static/style.css" /> + <link rel="stylesheet" type="text/css" href="/style.css" /> </head> <body> <main>
A
templates/static/style.css
@@ -0,0 +1,66 @@
+main { + max-width: 70ch; + padding: 2ch; + margin: auto; + font-family: Helvetica, Arial, monospace; + word-wrap: break-word; +} + +.inline { + display: inline; +} + +img { + max-width: 100%; +} + +#editor { + width: 100%; + border: 1px solid #999999; + width: 100%; + margin: 5px 0; + padding: 3px; + resize: none; +} + +.status { + border: 1px solid black; + margin-top: 3px; + margin-bottom: 3px; + padding-left: 0.5ch; +} + +.status-text { + font-family: monospace; + padding: 0.5ch; +} + +.button { + background-color: white; /* Green */ + border: 1px solid black; + text-decoration: none; + padding: 2px 5px; + display: inline-block; + margin: 0px; + transition-duration: 0.2s; +} + +.button:hover { + background-color: black; + color: white; +} + +.error { + color: red; +} + +a { + color: black; + transition-duration: 0.2s; + font-weight: bold; +} + +a:hover { + background-color: black; + color: white; +}