หลังจากศึกษาภาษา 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")