├── .gitignore ├── LICENSE ├── README.md ├── go.mod ├── main.go ├── modd.conf ├── static └── style.css └── templates ├── header.html └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | aprogram 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ad Hoc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Golang App Skeleton 2 | 3 | This is a skeleton for a golang web application optimized for simplicity and rapid development. 4 | 5 | ## Prerequisites 6 | 7 | * [Go](https://golang.org) 1.15 or greater 8 | * Optionally, [modd](https://github.com/cortesi/modd#install) for live reload 9 | 10 | ## How To Use 11 | 12 | * Fork this repository 13 | * Change the package name in `go.mod` to reflect your own repository 14 | * run `modd` 15 | * if you chose not to install modd, build the app with `go build -o your_program_name` 16 | * modify code to see the results 17 | 18 | ## Environment Variables 19 | 20 | * `PORT`: the port for the app to listen on. Defaults to 8080 21 | * `STATIC_BASE`: the base URL for static assets. Defaults to `/static` 22 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/adhocteam/GolangAppSkeleton 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "html/template" 6 | "log" 7 | "net/http" 8 | "os" 9 | ) 10 | 11 | func renderTemplate(w http.ResponseWriter, name string, data interface{}) { 12 | // This is inefficient - it reads the templates from the filesystem every 13 | // time. This makes it much easier to develop though, so we can edit our 14 | // templates and the changes will be reflected without having to restart 15 | // the app. 16 | t, err := template.ParseGlob("templates/*.html") 17 | if err != nil { 18 | http.Error(w, fmt.Sprintf("Error %s", err.Error()), 500) 19 | return 20 | } 21 | 22 | err = t.ExecuteTemplate(w, name, data) 23 | if err != nil { 24 | http.Error(w, fmt.Sprintf("Error %s", err.Error()), 500) 25 | return 26 | } 27 | } 28 | 29 | func logreq(f func(w http.ResponseWriter, r *http.Request)) http.Handler { 30 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 31 | log.Printf("path: %s", r.URL.Path) 32 | 33 | f(w, r) 34 | }) 35 | } 36 | 37 | type App struct { 38 | Port string 39 | StaticBase string 40 | } 41 | 42 | func (a App) Start() { 43 | if a.StaticBase == "/static" { 44 | log.Printf("serving static assets") 45 | http.Handle("/static/", logreq(staticHandler("static"))) 46 | } 47 | http.Handle("/", logreq(a.index)) 48 | addr := fmt.Sprintf(":%s", a.Port) 49 | log.Printf("Starting app on %s", addr) 50 | log.Fatal(http.ListenAndServe(addr, nil)) 51 | } 52 | 53 | func (a App) index(w http.ResponseWriter, r *http.Request) { 54 | renderTemplate(w, "index.html", struct { 55 | Name string 56 | StaticBase string 57 | }{ 58 | Name: "Sonic The Hedgehog", 59 | StaticBase: a.StaticBase, 60 | }) 61 | } 62 | 63 | func staticHandler(dir string) http.HandlerFunc { 64 | return func(w http.ResponseWriter, r *http.Request) { 65 | http.StripPrefix("/static/", http.FileServer(http.Dir(dir))).ServeHTTP(w, r) 66 | } 67 | } 68 | 69 | func env(key, defaultValue string) string { 70 | val, ok := os.LookupEnv(key) 71 | if !ok { 72 | return defaultValue 73 | } 74 | return val 75 | } 76 | 77 | func main() { 78 | log.SetFlags(log.LstdFlags | log.Lshortfile) 79 | server := App{ 80 | Port: env("PORT", "8080"), 81 | StaticBase: env("STATIC_BASE", "/static"), 82 | } 83 | server.Start() 84 | } 85 | -------------------------------------------------------------------------------- /modd.conf: -------------------------------------------------------------------------------- 1 | **/*.go { 2 | prep: go build -o aprogram 3 | daemon: ./aprogram 4 | } 5 | -------------------------------------------------------------------------------- /static/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: 760px; 3 | margin: auto; 4 | margin-top: 50px; 5 | font-size: 30px; 6 | } 7 | -------------------------------------------------------------------------------- /templates/header.html: -------------------------------------------------------------------------------- 1 | 2 | Home Page 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {{template "header.html" .}} 2 | Hello {{.Name}} 3 | 4 | --------------------------------------------------------------------------------