Skip to content

Instantly share code, notes, and snippets.

@zeddee
Last active January 2, 2018 14:42
Show Gist options
  • Save zeddee/2a1d89ba37b63fef29c4d3cde86018af to your computer and use it in GitHub Desktop.
Save zeddee/2a1d89ba37b63fef29c4d3cde86018af to your computer and use it in GitHub Desktop.
  • /save/ /edit/
    • should allow for more fields
    • main body
    • tags
    • notes on the right
    • list of links, with base_url on top
  • can this be integrated with hugo?
    • use hugo to render all the content?
    • have scraper push content into hugo/content/x folder?
    • build editor for hugo?
<h1>Editing {{.Title}}</h1>
<form action="/save/{{.Title}}" method="POST">
<textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea>
<input type="submit" value="Save">
</form>
package main
import (
"io/ioutil"
// "log"
"net/url"
"time"
)
// SaveFile Saves file with <host>-<time>.txt
func SaveFile(parsedurl *url.URL, body []byte) {
title := parsedurl.Host + "-" + time.Now().Format(time.RFC3339)
p1 := &Page{Title: title, Body: body}
p1.save()
}
// LoadFile take the name of the file to load and returns a Page struct
// Will only be used once frontend is implemented
func LoadFile(title string) (*Page,error) {
filename := title+".txt"
body, err := ioutil.ReadFile(filename)
if err != nil {
//log.Fatal(err)
// Pattern where instead of killing the programme, we return the error and allow the parent program to handle it.
// Note: to use, change return values to (*Page,error)
return nil, err
}
return &Page{Title: title, Body: body},nil
}
// Creates method for Page
func (p *Page) save() error {
filename := p.Title + ".txt"
// Only returns a value on error,
// Otherwise calls the WriteFile method
return ioutil.WriteFile(filename, p.Body, 0600)
}
// Page is general struct
type Page struct {
Title string
// This creates a byte slice
// ioutils expects Body as type []byte rather than type string
Body []byte
}
lorem dimsum siewmai kailan hargao puer cha
<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<article>{{printf "%s" .Body}}</article>
package main
import (
"fmt"
"html/template"
//"io/ioutil"
"net/http"
)
// WikiServer initializes a filesystem web frontend to manage whatever goscrape spits out
func main() {
http.HandleFunc("/", handler)
// Attaches a handler to a given URL path
http.HandleFunc("/view/", viewHandler)
http.HandleFunc("/edit/", editHandler)
http.HandleFunc("/save/", saveHandler)
// this invokes the server
http.ListenAndServe(":8080",nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
// fmt.Fprint writes to an interface
// In this case, it writes to w (type http.ResponseWriter)
fmt.Fprintf(w, "<h1>harro %s</h1>", r.URL.Path[1:])
}
// Takes write interface, template name, and page data as args
// Crunches and renders template via t.Execute(writer, data)
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
t, err := template.ParseFiles(tmpl + ".html")
if err != nil {
panic(err)
}
t.Execute(w, p)
}
func viewHandler(w http.ResponseWriter, r *http.Request) {
// This extracts paths that come after `base_url/view/`
title := r.URL.Path[len("/view/"):]
// Loads the page with loadPage method
p, err := LoadFile(title)
if err != nil {
// Instead of panicking
// if LoadFile produces nil, then page probably doesn't exist
// So create/edit new page
// http.Redirect accepts writer, response,
// URL path to redirect to, http status
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
return
}
renderTemplate(w, "view", p)
}
func editHandler(w http.ResponseWriter, r *http.Request) {
title := r.URL.Path[len("/edit/"):]
p,err := LoadFile(title)
if err != nil {
// if title does not exist, create new Page
// NB: this is similar to a ternary in javascript e.g.
// p = LoadFile(title) || &Page{Title:title}
p = &Page{Title: title}
}
renderTemplate(w, "edit", p)
}
func saveHandler(w http.ResponseWriter, r *http.Request) {
title := r.URL.Path[len("/save/"):]
body := r.FormValue("body")
p := &Page{Title: title, Body: []byte(body)}
p.save()
http.Redirect(w,r,"/view/"+title,http.StatusFound)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment