Actually following lets-go book
parent
103e1d5b4e
commit
0bc80e3cd7
@ -0,0 +1,52 @@
|
|||||||
|
root = "."
|
||||||
|
testdata_dir = "testdata"
|
||||||
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
args_bin = []
|
||||||
|
bin = "./tmp/main"
|
||||||
|
cmd = "go build -o ./tmp/main cmd/ratchetd/main.go"
|
||||||
|
delay = 1000
|
||||||
|
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
|
||||||
|
exclude_file = []
|
||||||
|
exclude_regex = ["_test.go"]
|
||||||
|
exclude_unchanged = false
|
||||||
|
follow_symlink = false
|
||||||
|
full_bin = ""
|
||||||
|
include_dir = []
|
||||||
|
include_ext = ["go", "tpl", "tmpl", "html", "go.tmpl"]
|
||||||
|
include_file = []
|
||||||
|
kill_delay = "0s"
|
||||||
|
log = "build-errors.log"
|
||||||
|
poll = false
|
||||||
|
poll_interval = 0
|
||||||
|
post_cmd = []
|
||||||
|
pre_cmd = []
|
||||||
|
rerun = false
|
||||||
|
rerun_delay = 500
|
||||||
|
send_interrupt = false
|
||||||
|
stop_on_error = false
|
||||||
|
|
||||||
|
[color]
|
||||||
|
app = ""
|
||||||
|
build = "yellow"
|
||||||
|
main = "magenta"
|
||||||
|
runner = "green"
|
||||||
|
watcher = "cyan"
|
||||||
|
|
||||||
|
[log]
|
||||||
|
main_only = false
|
||||||
|
silent = false
|
||||||
|
time = false
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
clean_on_exit = false
|
||||||
|
|
||||||
|
[proxy]
|
||||||
|
app_port = 0
|
||||||
|
enabled = false
|
||||||
|
proxy_port = 0
|
||||||
|
|
||||||
|
[screen]
|
||||||
|
clear_on_rebuild = false
|
||||||
|
keep_scroll = true
|
@ -0,0 +1,97 @@
|
|||||||
|
package ratchet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RatchetServer struct {
|
||||||
|
http.Handler
|
||||||
|
|
||||||
|
//Services used by HTTP routes
|
||||||
|
|
||||||
|
UserService UserService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRatchetServer() *RatchetServer {
|
||||||
|
r := new(RatchetServer)
|
||||||
|
|
||||||
|
router := http.NewServeMux()
|
||||||
|
// /{$} is used to prevent subtree path patterns from acting like a wildcard
|
||||||
|
// resulting in this route requiring an exact match on "/" only
|
||||||
|
// You can only include one HTTP method in a route pattern if you choose
|
||||||
|
// GET will match GET & HEAD http request methods
|
||||||
|
router.HandleFunc("GET /{$}", home)
|
||||||
|
router.HandleFunc("GET /snippet/view/{id}", snippetView)
|
||||||
|
router.HandleFunc("GET /snippet/create", snippetCreate)
|
||||||
|
router.HandleFunc("POST /snippet/create", snippetCreatePost)
|
||||||
|
r.Handler = router
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func home(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add("Server", "Go")
|
||||||
|
|
||||||
|
// Initialize a slice containing the paths to the two files. It's important
|
||||||
|
// to note that the file containing our base template must be the *first*
|
||||||
|
// file in the slice.
|
||||||
|
files := []string{
|
||||||
|
"./ui/html/base.go.tmpl",
|
||||||
|
"./ui/html/partials/nav.go.tmpl",
|
||||||
|
"./ui/html/pages/home.go.tmpl",
|
||||||
|
}
|
||||||
|
|
||||||
|
// read template file into template set.
|
||||||
|
ts, err := template.ParseFiles(files...)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err.Error())
|
||||||
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Write template content to response body
|
||||||
|
err = ts.ExecuteTemplate(w, "base", nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err.Error())
|
||||||
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func snippetView(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(r.PathValue("id"))
|
||||||
|
if err != nil || id < 1 {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set a new cache-control header. If an existing "Cache-Control" header exists
|
||||||
|
// it will be overwritten.
|
||||||
|
w.Header().Set("Cache-Control", "public, max-age=31536000")
|
||||||
|
|
||||||
|
// msg := fmt.Sprintf("Snippet %d...", id)
|
||||||
|
|
||||||
|
// w.Write([]byte(msg))
|
||||||
|
|
||||||
|
// we can rely on the Write() interface to use a differnent
|
||||||
|
// function to write out our response
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "Snippet %d...", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// snippetCreate handles display of the form used to create snippets
|
||||||
|
func snippetCreate(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("Displaying snippetCreate form..."))
|
||||||
|
}
|
||||||
|
|
||||||
|
// snippetCreate handles display of the form used to create snippets
|
||||||
|
func snippetCreatePost(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// example of a custom header. Must be done before calling WriteHeader
|
||||||
|
// or they will fail to take effect.
|
||||||
|
w.Header().Add("Server", "Dirp")
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
|
||||||
|
w.Write([]byte("Created snippet..."))
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
{{define "base" -}}
|
||||||
|
<!doctype html>
|
||||||
|
<html lang='en'>
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<title>{{template "title" .}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1><a href='/'>Ratchet</a></h1>
|
||||||
|
</header>
|
||||||
|
{{template "nav" .}}
|
||||||
|
<main>
|
||||||
|
{{template "main" .}}
|
||||||
|
</main>
|
||||||
|
<footer>Powered by <a href='https://golang.org/'>Go</a></footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
@ -0,0 +1,6 @@
|
|||||||
|
{{define "title"}}Home{{end}}
|
||||||
|
|
||||||
|
{{define "main" -}}
|
||||||
|
<h2>Latest Snippets</h2>
|
||||||
|
<p>There's nothing to see yet!</p>
|
||||||
|
{{- end -}}
|
@ -0,0 +1,5 @@
|
|||||||
|
{{define "nav" -}}
|
||||||
|
<nav>
|
||||||
|
<a href='/'>Home</a>
|
||||||
|
</nav>
|
||||||
|
{{- end}}
|
Loading…
Reference in New Issue