實作 - 從零開始用 Golang 寫網頁 - 09 將實作好的計算機放入網頁

[實作] 從零開始用 Golang 寫網頁 : 09 將實作好的計算機放入網頁

這邊主要是熟悉 Golang 網頁程式的架構,所以計算機的前端與邏輯的實作都是使用別人現成的,而前端的框架使用 Bootstrap

Bootstrap 下載

程式說明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main

import (
"fmt"
"html/template"
"net/http"
"os"

"github.com/julienschmidt/httprouter"
log "github.com/sirupsen/logrus"
"github.com/urfave/negroni"

negronilogrus "github.com/meatballhat/negroni-logrus"
)

func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
data := map[string]string{
"name": "Guest",
"content": "這是首頁",
}

t := template.Must(template.ParseFiles("./views/layout.html", "./views/head.html", "./views/index.html"))

err := t.ExecuteTemplate(w, "layout", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func hello(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
data := map[string]string{
"name": p.ByName("name"),
"content": "這是我的網站",
}

t := template.Must(template.ParseFiles("./views/layout.html", "./views/head.html", "./views/index.html"))

err := t.ExecuteTemplate(w, "layout", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func calculator(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
data := map[string]string{
"name": "Guest",
"content": "這是首頁",
}

t := template.Must(template.ParseFiles("./views/calculator/layout.html", "./views/head.html", "./views/calculator/calculator.html"))

err := t.ExecuteTemplate(w, "layout", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func notFound(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)

data := map[string]string{
"name": "Guest",
}

t := template.Must(template.ParseFiles("./views/layout.html", "./views/head.html", "./views/errorpage/NotFoundPage.html"))

err := t.ExecuteTemplate(w, "layout", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func errHandler(w http.ResponseWriter, r *http.Request, p interface{}) {
w.WriteHeader(http.StatusInternalServerError)

data := map[string]string{
"name": "Guest",
}

t := template.Must(template.ParseFiles("./views/layout.html", "./views/head.html", "./views/errorpage/ServerErrorPage.html"))

err := t.ExecuteTemplate(w, "layout", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func main() {

host := "127.0.0.1"
port := "8080"
output := ""

args := os.Args[1:]

for {
if len(args) < 2 {
break
} else if args[0] == "-h" || args[0] == "--host" {
host = args[1]
args = args[2:]
} else if args[0] == "-p" || args[0] == "--port" {
port = args[1]
args = args[2:]
} else if args[0] == "-l" || args[0] == "--log" {
output = args[1]
args = args[2:]
} else {
log.Fatalln(fmt.Sprintf("Unknown parameter : %s", args[0]))
}
}

mux := httprouter.New()

mux.GET("/", index)
mux.GET("/myexercise/hello/:name", hello)
mux.GET("/myexercise/calculator", calculator)

mux.ServeFiles("/js/*filepath", http.Dir("./static/js"))
mux.ServeFiles("/css/*filepath", http.Dir("./static/css"))

mux.NotFound = http.HandlerFunc(notFound)

mux.PanicHandler = errHandler

l := log.New()

var f *os.File
var err error

if output != "" {
f, err = os.Create(output)
if err != nil {
log.Fatal(err)
}

defer f.Close()
l.SetOutput(f)
}

n := negroni.Classic()
n.Use(negronilogrus.NewMiddlewareFromLogger(l, "web"))
n.UseHandler(mux)

server := http.Server{
Addr: fmt.Sprintf("%s:%s", host, port),
Handler: n,
}

l.Println(fmt.Sprintf("服務器即將開啟, 訪問地址 http://%s:%s", host, port))
l.Fatal(server.ListenAndServe())
}

main

  • 因為這邊是使用第三方的 route 物件,所以靜態資源的處理方式需要改個寫法

    • 使用 ServeFiles() 函式將 /js/*filepath 的路徑導入到 ./static/js 資料夾內並將此資料夾內的所有檔案視為靜態資源,css 也是相同做法

calculator

  • layout.htmlcalculator.html 都是參考至已實作好的計算機,其他部分與先前的差不多

  • 此計算機主要邏輯的部分由前端的 Javascript 解決,與 Golang 的後端網頁程式無關

結果

tags: 實作 Golang 網站
Author: Kenny Li
Link: https://kennyliblog.nctu.me/2020/09/14/Golang-Web9/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.