หลังจากศึกษาภาษา Go และนั่งไล่หาเฟรมเวิร์คที่จะใช้เพื่อให้ทุกอย่างง่ายขึ้นก็ใช้เวลาเลือกอยู่นานมากเหมือนกันนะ สุดท้ายก็มาตกที่ Revel Framework
เหตุผลที่เลือก…มาตอนนี้จำไม่ได้ละ เหมือนน่าจะเป็นที่ความง่าย หรือความเร็ว อะไรสักอย่างเนี่ยแหละ ก็เอาเป็นว่า ตอนนี้เคนเลือกตัวนี้ละกัน
วิธีใช้ฟังก์ชั่น Render
คือจริง ๆ ตามเอกสารการใช้งานเค้าเวลาสร้าง Controller มาแล้วจะส่งเป็น html ออกมาก็ทำได้ง่าย ๆ แค่สร้างไฟล์ในโฟลเดอร์ views ตามชื่อ Controller/func name แล้วสั่ง เช่น
type User struct {
*revel.Controller
}
func (c User) Register() revel.Result {
return c.Render()
}
ก็ไปทำการสร้างไฟล์ register.html ที่ views/User/register.html มันก็จะไปทำการเรนเดอร์ไฟล์ HTML นั้นให้เลย
แต่หากเราต้องการให้มัน Custom ไม่ใช่ของมันนั้น ต้องใช้ RenderTemplate แทนครับ โค้ดก็จะออกมาหน้าตาแบบนี้
func (c User) Register() revel.Result {
return c.RenderTemplate("Custompath/register.html")
}
เคนลองมาหลายอย่างอยู่ คือแม้จะ Render ได้ แต่ว่ามันจะมี Error log ไปโผล่ด้วยครับ แต่ถ้าใช้แบบนี้ก็จะโอเคผ่านฉลุย ไร้ Error log ใด ๆ
วิธีส่งค่าพวก moreStyle, moreScript
สำหรับมือเก๋าน่าจะไม่เท่าไหร่ แต่กับมือใหม่อย่างเคน นั่นงงไปเป็นชั่วโมงอยู่ครับ
โดยในหน้า HTML ของ Revel นั้นจะมีส่วนที่มันฝังตัวรับค่าชื่อว่า
{{range .moreStyles}}
<link rel="stylesheet" type="text/css" href="/public/{{.}}">
{{end}}
{{range .moreScripts}}
<script src="/public/{{.}}" type="text/javascript" charset="utf-8"></script>
{{end}}
ไว้ที่ header.html ตอนแรกก็นั่งงงว่าจะส่งค่าไปได้ยังไง รู้แค่ว่าต้องส่งเป็น Slice ไปให้มันแน่ ๆ แต่ยังไม่รู้จะเขียนโค้ดยังไง มา! เคนลัดให้เอาโค้ดไปใช้ได้เลย
func (c User) Register() revel.Result {
c.ViewArgs["moreStyles"] = []string{"style1.css","style2.css","style3.css"}
c.ViewArgs["moreScripts"] = []string{"script1.js","script2.js","script3.js"}
return c.RenderTemplate("User/register.html")
}
Custom Error Message ของตัว Validation
ในตัว Revel จะมีตัว Validation สำหรับเช็คให้อยู่แล้ว แต่ดั๊นไม่มีตัวเช็คว่า “มันเหมือนกัน” ก็เลยต้องทำตัวเช็คเอง และก็หาวิธียัด Error ใส่ให้มันก็นานอยู่ แต่พอเจอจริง ๆ ก็ง่ายนะไม่ยาก ก็ล้อตาม Func ของเค้าแหละ
password := "1234"
confirmPassword := "asdf"
if !reflect.DeepEqual(password, confirmPassword) {
result := c.Validation.ValidationResult(false).Message("รหัสผ่าน และยืนยันรหัสผ่านต้องใส่ให้เหมือนกัน")
c.Validation.Errors = append(c.Validation.Errors, result.Error)
}
ตั้งค่า/ดึงค่า Session
username := "kanexkane"
// ตั้งค่า Session
err := c.Session.Set("username", username)
// ดึงค่า Session
sUsername, err := c.Session.Get("username")
เช็ค Login และการ Redirect ไป struct package อื่น
ตอนนี้เคนได้สร้างโฟลเดอร์ /admin ขึ้นมาภายใน app/controllers ซึ่งทำให้ต้องใช้ชื่อ package อื่นนอกจากชื่อหลักของมันซึ่งก็คือชื่อ controllers
เคนเลยทำการตั้งชื่อ package ในโฟลเดอร์ /admin ว่า package controllersadmin
จากนั้นขั้นเริ่มแรกคือต้องเช็คให้ได้ก่อนว่า ถ้าจะเข้ามาหน้านี้ต้องทำการเข้าสู่ระบบนะ ถ้าไม่จะทำการ Redirect ไปที่ User.Login ซึ่งเป็น Struct ที่อยู่ใน package controllers
package controllersadmin
import (
"projectname/app/controllers"
"github.com/revel/revel"
)
struct Admin struct {
*revel.Controller
}
func (c Admin) init() {
revel.InterceptFunc(IsLoggedIn, revel.BEFORE, &Admin{})
}
func IsLoggedIn(c *revel.Controller) revel.Result {
userid, err := c.Session.Get("userid")
if err != nil || userid == nil {
return c.Redirect(controllers.User.Login)
}
return nil
}
หา User Agent และ IP
useragent := c.Request.Useragent()
ip := c.Request.Header.Get("X-Forwarded-For")
