ทำ Web Application ร่วมกับ HTML Template ไฟล์ที่ถูกตั้งค่าเพื่อเป็นแพทเทิร์น (Pattern) สำหรับใช้กับการสร้างไฟล์งานตามความต้องการ
ในการพัฒนาระบบ Web application ด้วย Go สามารถพัฒนาร่วมกับ html template ได้ มีลักษณะเช่นเดียวกับการใช้ Template ต่างๆ นั่นเอง
ข้อกำหนดเบื้องต้น
ข้อกำหนดเพียงอย่างเดียวสำหรับบทความนี้คือ คุณต้องติดตั้ง Go บนคอมพิวเตอร์ของคุณ และทำตามบทความ ทำ Web โปรแกรมแรก Hello, World มาก่อน
เราจะเริ่มด้วยโครงสร้างตามโค้ดด้านล่าง
package main
import (
"net/http"
)
const portNumber = ":8080"
func Home(w http.ResponseWriter, r *http.Request) {
}
func About(w http.ResponseWriter, r *http.Request) {
}
func main() {
http.HandleFunc("/", Home)
http.HandleFunc("/about", About)
_ = http.ListenAndServe(portNumber, nil)
}
const คือการประกาศค่าคงที่ ชื่อ portNumber มีค่าเป็น :8080 เพื่อกำหนดพอร์ตที่ ListenAndServe เป็น :8080 ส่วน nil คือ “ว่างเปล่า”

HandleFunc คือ ใช้ในการเรียกใช้ฟังก์ชันตามคำร้องขอ เช่น “/” ให้ไปทำงานที่ฟังก์ชัน Home (หน้าแรก) หรือ “/about” ให้ไปทำงานที่ฟังก์ชัน About (เกี่ยวกับเรา)

แสดงสถานะการทำงาน
นำเข้า แพ็กเกจ “fmt” เพิ่มเข้ามา สำหรับการใช้คำสั่งให้แสดงข้อความ
import (
"fmt"
"net/http"
)
เพิ่มโค้ด สำหรับ แสดงสถานะการทำงาน และ การเริ่มต้นเซิร์ฟเวอร์บนพอร์ตอะไร
x := fmt.Sprintf
fmt.Println(x("Staring application on port %s", portNumber))

ทดสอบการทำงาน โดยคลิกขวาที่ โฟลเดอร์ web -> Open integrated Terminal

ใช้คำสั่ง fresh

แสดงสถานะการทำงาน Staring application on port :8080

หยุดกระบวนการทำงานในเทอร์มินัลของคุณโดยใช้ ctrl-c
สร้าง Template
Template คือ ? ไฟล์ที่ถูกตั้งค่าเพื่อเป็นแพทเทิร์น (Pattern) สำหรับใช้กับการสร้างไฟล์งานตามความต้องการ
เริ่มโดย สร้างโฟลเดอร์ templates ภายในโฟลเดอร์ web

สร้างไฟล์ home.page.tmpl และ ไฟล์ about.page.tmpl ภายในโฟลเดอร์ templates

การสร้างโค้ด HTML อัตโนมัติ
กดปุ่ม Ctrl + Shift + p แล้ว ที่ช่องค้นหาพิมพ์ user เลือก Peferences Open user Settings

พิมพ์ emmet แล้วติ๊กเลือกเพิ่มดังรูป แล้วปิดลงไป

กลับมาที่ไฟล์ home.page.tmpl

โดยปกติแล้ว Emmet จะเริ่มทำงานเมื่อเราเปิดไฟล์ HTML ขึ้นมาเท่านั้น สำหรับไฟล์ใหม่ก็ให้ กด F1 แล้วพิมพ์ change เลือก Change Language Mode

แล้วเลือกเป็น HTML ก็พร้อมใช้ทันที

พิมพ์ html:5 แล้วกดปุ่ม Tab

VSCode จะสร้างโค้ด HTML ให้เราโดยอัตโนมัติ

เปลี่ยนข้อมูล Template ให้แตกต่างกัน
ไฟล์ home.page.tmpl ที่ title เปลี่ยนเป็น Home และเพิ่ม <h1>หน้าแรก</h1>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
</head>
<body>
<h1>This is the home page</h1>
</body>
</html>

ไฟล์ about.page.tmpl ที่ title เปลี่ยนเป็น About Us และเพิ่ม <h1>เกี่ยวกับเรา</h1>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About Us</title>
</head>
<body>
<h1>This is the about page</h1>
</body>
</html>

การใช้งาน Template
นำเข้า แพ็กเกจ “html/template ” เพิ่มเข้ามา สำหรับขับเคลื่อนข้อมูลเพื่อสร้างเอาต์พุต HTML ที่ปลอดภัยต่อการแทรกโค้ด
import (
"fmt"
"html/template"
"net/http"
)
ฟังก์ชัน renderTemplate ใช้ในการแสดงหน้าเว็บนั้นจากโฟลเดอร์ templates

เลือก Template ให้แต่ละฟังก์ชัน
ฟังก์ชัน Home
renderTemplate(w, "home.page.tmpl")
ฟังก์ชัน About
renderTemplate(w, "about.page.tmpl")

โค้ดทั้งหมด
package main
import (
"fmt"
"html/template"
"net/http"
)
const portNumber = ":8080"
func Home(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "home.page.tmpl")
}
func About(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "about.page.tmpl")
}
func renderTemplate(w http.ResponseWriter, tmpl string) {
parsedTemplate, _ := template.ParseFiles("./templates/" + tmpl)
err := parsedTemplate.Execute(w, nil)
if err != nil {
fmt.Println("error parsing template:", err)
return
}
}
func main() {
http.HandleFunc("/", Home)
http.HandleFunc("/about", About)
x := fmt.Sprintf
fmt.Println(x("Staring application on port %s", portNumber))
_ = http.ListenAndServe(portNumber, nil)
}
ทดสอบการทำงาน
ใช้คำสั่ง fresh

ทดสอบการทำงานโดยไปที่ http://localhost:8080/

และเมื่อเปลี่ยนไปที่ http://localhost:8080/about

กลับไปที่ไฟล์ home.page.tmpl ทดสอบเพิ่มโค้ด
<p>This is some text</p>

ไปที่ http://localhost:8080/ จากนั้นรีเฟรชเบราว์เซอร์ของคุณ จะเห็นข้อความที่เพิ่มเข้ามา

จัดระเบียบโค้ด
สร้างไฟล์ชื่อ handlers.go เขียนโค้ดประกาศ package ชื่อ main เช่นกัน

ไปที่ ไฟล์ main.go Cut โค้ดส่วนนี้


ไปวางไว้ที่ handlers.go

นำเข้า แพ็กเกจ “fmt” “html/template” และ “net/http”
package main
import (
"fmt"
"html/template"
"net/http"
)
func Home(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "home.page.tmpl")
}
func About(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "about.page.tmpl")
}
func renderTemplate(w http.ResponseWriter, tmpl string) {
parsedTemplate, _ := template.ParseFiles("./templates/" + tmpl)
err := parsedTemplate.Execute(w, nil)
if err != nil {
fmt.Println("error parsing template:", err)
return
}
}

ที่ main.go แพ็กเกจ “html/template” ไม่ได้ใช้แล้วให้ลบออกไป

package main
import (
"fmt"
"net/http"
)
const portNumber = ":8080"
func main() {
http.HandleFunc("/", Home)
http.HandleFunc("/about", About)
x := fmt.Sprintf
fmt.Println(x("Staring application on port %s", portNumber))
_ = http.ListenAndServe(portNumber, nil)
}
ทดสอบการทำงาน ใช้คำสั่ง fresh

ไปที่ http://localhost:8080/ จะได้ได้ผลลัพธ์เหมือนกัน

สร้างไฟล์ชื่อ render.go เขียนโค้ดประกาศ package ชื่อ main เช่นกัน

ไปที่ ไฟล์ handlers.go Cut โค้ดฟังก์ชัน renderTemplate ไปวางที่ render.go และ นำเข้า แพ็กเกจ “fmt” “html/template” และ “net/http”

package main
import (
"fmt"
"html/template"
"net/http"
)
func renderTemplate(w http.ResponseWriter, tmpl string) {
parsedTemplate, _ := template.ParseFiles("./templates/" + tmpl)
err := parsedTemplate.Execute(w, nil)
if err != nil {
fmt.Println("error parsing template:", err)
return
}
}

ที่ไฟล์ handlers.go แพ็กเกจ “fmt” และ “html/template” ไม่ได้ใช้แล้วให้ลบออกไป
package main
import (
"net/http"
)
func Home(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "home.page.tmpl")
}
func About(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "about.page.tmpl")
}

ทดสอบการทำงานอีกครั้ง แล้วไปที่ http://localhost:8080/ จะได้ได้ผลลัพธ์เหมือนเดิม แต่จะเห็นได้ว่า เราได้แยกไฟล์แต่ละหน้าที่การทำงานเป็นสัดส่วนออกจากกันเพื่อให้ง่ายต่อการแก้ไขในภายหลัง
เพิ่ม Style Sheet
ไปที่ไฟล์ home.page.tmpl เพิ่มโค้ดเรียกใช้ stylesheet บริเวณ ล่างแท็ก title
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">

ที่แท็ก body เพิ่มโค้ดดังนี้
<div class="container">
<div class="row">
<div class="col">
<h1>This is the home page</h1>
<p>This is some text</p>
</div>
</div>
</div>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<h1>This is the home page</h1>
<p>This is some text</p>
</div>
</div>
</div>
</body>
</html>
ทดสอบการทำงาน
ก่อนเพิ่มโค้ด Style Sheet

หลังเพิ่มโค้ด Style Sheet

ไปที่ไฟล์ about.page.tmpl เพิ่มโค้ดดังนี้
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About Us</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<h1>This is the about page</h1>
</div>
</div>
</div>
</body>
</html>

ทดสอบการทำงาน

credit : https://www.udemy.com/course/building-modern-web-applications-with-go/