Rewrite URL เมื่อเปิดเว็บด้วย iPhone
เมื่อวานนั่งเขียน rule ของ mod_rewrite ให้เวลาเปิดเว็บด้วย iphone ให้มันไปใช้อีก path นึงค้นใน google ก็เจอ pattern แบบนี้
RewriteCond %{HTTP_USER_AGENT} .*iPhone.*
RewriteRule ^index\.cfm$ /i/index.cfm [QSA,L]
ตรงส่วน RewriteCond เราจะเอาค่า HTTP_USER_AGENT มาเช็คตาม pattern .*iPhone.*
ส่วน RewriteRule ที่ผมต้องการคือถ้าเจอ index.cfm ให้ไปที่ /i/index.cfm
ที่นี้พอเขียน rule แบบนี้ปุ๊บพวก resource อื่นๆที่อ้างแบบ relative path ใน index.cfm ก็จะใช้ไม่ได้เลย เช่นถ้ามีอ้าง css/style.css ซึ่งจริงๆ path ต้องเป็น /i/css/style.css มันก็จะเปลี่ยน request เป็น /css/style.css ก็เลยต้องเขียน rule เพิ่งจัดการตรงนี้ มั่วๆอยู่นานกว่าจะได้ออกมาแบบนี้
RewriteCond %{HTTP_USER_AGENT} .*iPhone.*
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /i/%{REQUEST_URI} [QSA,L]
คือเพิ่ม RewriteCond เข้าไปโดยเช็คว่า ถ้า REQUEST_FILENAME ไม่ใช่ ไฟล์ (-f) ไม่ใช่ ไดเรกทอรี่ (-d) ก็คือหาไฟล์หา path นี้ไม่เจอก็ให้เปลี่ยน url เป็น /i/%{REQUEST_URI} ตรง REQUEST_URI เป็น path ที่โดน request มา เช่น จาก rule แรกทำให้ css/style.css ไป request ที่ /css/style.css ซึ่งไฟล์นี้ไม่มี มันก็จะ rewrite เป็น /i/css/style.css ตามที่ต้องการ
Add comment พฤศจิกายน 11, 2009
I love BoydNop
ตอนนี้พี่ บอย มีโปรเจ็คใหม่กับพี่นพ คือ อลบั้ม BoydNop
มีเพลงปล่อยมาให้ฟังแล้ว 3 เพลง มีเป็น MV แล้ว 2 เพลงคือ Away Far So กับ ยาก
MV แบบว่ารวมญาติมากๆ มีคนที่เคยร่วมงานกับพี่บอย ทั้งสมัย Bakery และ Love Is มากมาย
เช่น Lipta, Stamp, โต๋ และได้ พลอย มาร่วมด้วย พร้อมเด็กน้อยลูกๆหลานๆ น่ารักมาก
ตอนนี้ก็รอเมื่อไหร่จะมีอลบั้มเต็มๆวางแผงหละครับ ไม่พลาดแน่นอน และก็รอคอนเสิร์ต ที่ต้องออกมาดีแน่ๆ
Add comment พฤศจิกายน 7, 2009
Validate Form ด้วย LiveValidation
เวลาสร้างฟอร์มในหน้าเพจให้กรอกข้อมูลอะไรสักอย่าง เราจำเป็นต้องตรวจสอบความถูกต้องของข้อมูลว่าเป็นตามเงื่อนไข หรือ ได้รูปแบบของข้อมูลที่ถูกต้องหรือไม่ เช่นฟอร์มรับสมัคร ฟอร์มกรอกเนื้อหาบล็อก ปกติเราจะตรวจสอบข้อมูลตรงนี้หลักจากที่ซับมิทข้อมูลไปแล้ว ก็ไปใช้ภาษาฝั่งเซอเวอร์ตรวจสอบเช่น php ถ้าข้อมูลไม่ถูกต้องก็ให้ redirect กลับมาที่หน้าฟอร์มใหม่ แต่วิธีนี้ต้องมีการ request ข้อมูลไปก่อนแล้วต้องรอ response กลับมา ถ้ากรอกผิดหลายรอบก็ต้องมานั่งซับมิทใหม่หลายๆรอบ
เราเลยจะใช้ภาษาฝั่ง client อย่าง javascript มาช่วยตรวจสอบข้อมูลของฟอร์มก่อนที่จะซับมิทข้อมูลไป มี library หลายเจ้าที่ช่วยตรงนี้ ที่เอามาให้ดูคือ LiveValidation เป็น เป็น library เล็กๆ มี pattern วิธีใช้ง่ายๆ
ตัวอย่างเช่นจะตรวจสอบว่า text input ที่มี id ชื่อว่า username นี้ต้องมีข้อมูลถ้าไม่มีจะ ซับมิทไปไม่ได้ และขึ้นข้อความบอกว่าข้อมูลไม่ถูกต้องให้เขียน script แบบนี้
var username = new LiveValidation('username');
username.add( Validate.Presence );
จากโค้ด ให้สร้าง object ของ LiveValidation โดยใส่ชื่อ id ของ field ที่จะ validate เป็นพารามิเตอร์ จากนั้นเราจะเพิ่ม เงื่อนไขการตรวจสอบโดยเรียก method add แล้วกำหนดเงื่อนไขโดยใช้ค่าจาก object Validate เช่่น Validate.Presence ตรวจสอบว่าต้องมีข้อมูลกรอกที่ text input นี้
อีกตัวอย่างเป็นการตรวจสอบว่าต้องใส่ข้อมูลในรูปแบบของ email
var email = new LiveValidation('email');
email.add( Validate.Email );
เมื่อเรากรอกข้อมูลถูกต้อง หรือ ไม่ถูกต้อง ตัว LiveValidation จะเพิ่มข้อความบอกไว้หลัง input field โดยครอบอยู่ใน tag span โดยมี class ต่างๆบอกว่าสถานะว่าเป็น valid หรือ invalid เราสามารถจัด style sheet ให้กับข้อความในสถานะต่างๆได้ class ที่บอกสถานะต่างๆมีดังนี้
- LV_validation_message – the class that is added to all validation messages
- LV_valid – the class that is added to a valid message
- LV_invalid – the class that is added to an invalid message
- LV_valid_field – the class that is added to a valid field
- LV_invalid_filed – the class that is added to an invalid field
Reference : http://livevalidation.com/
1 comment ตุลาคม 30, 2009
Tail Recursion
การทำงานของโปรแกรมโดยทั่วไปเวลาเรียก function นั้นจะมีการจำตำแหน่งที่เรียกเอาไว้แล้วกระโดดเข้าไปทำงานใน function เมื่อเจอคำสั่ง return ก็จะกระโดดกลับมา ดั้งนั้นถ้ามีการเขียนแบบ recursive ก็จะมีการสร้าง stack ของการ call function ซ้อนๆกันไว้ แล้วพอ return ก็จะย้อนกลับมาทีละ step นี่คือกรณีของ recursive แบบธรรมดาทั่วๆไป ซึ่งจะเห็นว่าจะต้องเสียเวลาในการกระโดดกลับมา
Tail Recusion นั้นจะช่วยลดการทำงานตรงนั้นได้โดยแทนที่จะรอให้ได้ผลลัพธ์เมื่อมีการย้อน กลับ ก็จะทำการเก็บผลลัพธ์ตั้งแต่การเรียก recursive function จนเมื่อถึง การ call ครั้งสุดท้ายก็จะเป็นการ return ผลลัพธ์ออกมาทันที ไม่ต้องย้อนกลับไปอีก
ตัวอย่าง ฟังก์ชัน หาความยาวของ list ถ้าเขียนแบบ recursive ธรรมดา ได้แบบนี้
mylength :: [a] -> Int mylength [] = 0 mylength (y:ys) = 1+mylength (ys)
จะเห็นว่าแบบนี้ terminate function จะรับค่า empty list แล้ว return 0 ออกมา เมื่อมีการ recursive ก็จะเอา 1 ไปบวกไป แบบนี้จะเกิดการ call ไปจนสุด แล้วค่อยเอาค่า มาบวกกันทีหลังแบบนี้
mylength "abc" -> 1+mylength("bc")
-> 1+1+mylength("c")
-> 1+1+1+mylength("")
-> 1+1+1+0
-> 1+1+1
-> 1+2
-> 3
แต่ถ้าเขียนแบบ tail recursive เราจะเพิ่มตัว accumulator เข้ามา ตัว accumulator ก็คือ พารามิเตอร์ที่เก็บ ผลลัพธ์ในแต่ละ step ที่ทำการ recursive เมื่อ terminate ที่เป็นการ call ครั้งสุดท้ายเราจะ return ค่า accumulator ออกมาทันที
mylength :: [a] -> Int mylength ys = _mylength ys 0 _mylength [] n = n _mylength (y:ys) n = _mylength ys (n+1)
ตัวอย่างนี้เราเขียน function _mylenth ขี้นมาเป็น tail recursion แล้วตัวfunction mylength ของเรา ก็ค่อย call _mylength โดยส่งค่า 0 เป็นค่าเริ่มต้นของ accumulator
Add comment กุมภาพันธ์ 10, 2009
Unicode in Coldfusion
เนื่องจากว่ามันมีให้เซตหลายๆแบบ หลายๆจุด จะใช้ทีลืมประจำ ก็blogไว้ซะหน่อย
- เอาโค้ดนี้ ไปไว้ใน Application.cfc
<cfscript> SetEncoding("form","utf-8"); SetEncoding("url","utf-8"); </cfscript>แบบนี้คือบอกว่าข้อมูลที่อยู่ใน scope form และ url ใช้ utf-8
-
<cfcontent type="text/html; charset=utf-8">โค้ดนี้บอกว่า template ที่เปิดเป็นไฟล์แบบ text/html และ ใช้ charset เป็น utf8
โดยโค้ดนี้ต้องอยู่ส่วนบนสุดของไฟล์ -
<cfprocessingdirective pageEncoding="utf-8">อันนี้ก็เอาไปวางได้ทุกๆ template ที่มีการติดต่อ db หรือว่ามี i/o กับ browser
ถ้าใช้กับ coldbox ก็สามารถ เอาไปว่างไว้ที่ Layout ที่เดียวได้เลย
Add comment กุมภาพันธ์ 10, 2009
Tree In Haskell
ตอนนี้กำลัง ค่อยๆ ไล่อ่าน หนังสือ Real World Haskell ที่ร่วมกันเขียนโดย Bryan O’Sullivan, Don Stewart, and John Goerzen
หนังสือตีพิมพ์เป็นเล่มขายแล้ว อยากซื้อเก็บเหมือนกัน แต่ก็ไม่เคยซื้อผ่าน amazon ไม่มีพวกบัตรเครติด อะไรเลย ก็เลยยังไม่ซื้อ
หนังสือเล่มนี้ มีให้อ่านออนไลน์ผ่านเว็บ http://book.realworldhaskell.org/ ที่จริง หนังสือเล่มนี้ก่อนตีพิมพ์ ผู้แต่งเขาก็เอาขึ้นเว็บ
ให้อ่าน และก็ให้ comment ในแต่ละ paragraph ได้ในระหว่างแต่ง เพราะฉนั้นถ้าเข้าไปอ่านจะเห็นว่าในแต่ละ paragraph จะมีลิ้ง
ให้ comment ได้
มาว่ากันตามหัวข้อ คือ เขียนโครงสร้างข้อมูลแบบ Tree ด้วย Haskell ซึ่งมันเป็นแบบฝึกหัดอยู่ที่บทที่ 3 ว่าให้สร้าง data type Tree
โดยให้มี variable constructor ตัวเดียว โดยใช้ data type Maybe a เข้าช่วย นั่งทำอยู่นาน กว่าจะทำได้ แล้วก็ได้ออกมาแบบนี้
data Tree a = Node a (Maybe (Tree a)) (Maybe (Tree a))
deriving (Show)
ถ้าแบบไม่ใช้ Maybe ตามตัวอย่างในหนังสือจะเป็นแบบนี้ ซึ่งจะมี variable constructor 2 ตัวโดย มี Empty อีกตัว
data Tree a = Node a (Tree a) (Tree a)
| Empty
deriving (Show)
data type Tree ที่สร้างมาเป็น type แบบ Recursive types จะเห็นว่า pattern ของ variable constructor จะมี
data type Tree อยู่ด้วย ตัวอย่างการเอาไปใช้งานแบบ ไม่ใช้ Maybe จะเป็นแบบนี้
myTree = Node 10 Empty Empty myTree2 = Node 10 (Node 20 Empty Empty) Empty
ส่วนแบบ Maybe เราไม่จำเป็นต้อง สร้าง Empty ขึ้นมาเพราะเราจะใช้ Nothing ซึ่งเป็น ข้อมูลแบบ Maybe ในการกำหนดค่า
childNode ของ Tree ได้ เช่น
myTree = Node 10 Nothing Nothing
และ ใช้ Just ในการกำหนด childNode ที่ไม่เป็น Nothing
myTree2 = Node 10 (Just (Node 20 Nothing Nothing)) Nothing
จบแค่นี้ครับ ไม่ได้อัพบล็อคตัวเองซะนาน เพราะหัวข้ออื่นๆก็เอาไปอัพที่ *66.com ซะหมดแล้ว
2 comments มกราคม 27, 2009
Coldfusion cfloop readline from file
ตอนแรกตั้งใจอ่านไฟล์ โดยใช้ cffile ปกติ แล้วค่อยมาวนลูปค่าในไฟล์ที่ละบรรทัด
แล้วค้นไปเจอว่า CF8 มันสามารถใช้ cfloop กับ file ได้เลยลองใช้ดู ง่ายดีจริงๆ
ตัวอย่างเช่น
<cfloop file="#Expandpath('nqi/cfcservice/')#data.txt" index="line">
<cfscript>
data = listtoarray(line,"|");
</cfscript>
<cfquery datasource="AisNQG">
insert into nqi_presentation values
(<cfqueryparam cfsqltype="cf_sql_date" value="#data[1]#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#data[2]#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#data[3]#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#data[4]#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#data[5]#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#data[6]#">,
<cfqueryparam cfsqltype="cf_sql_numeric" value="#data[7]#">,
<cfqueryparam cfsqltype="cf_sql_numeric" value="#data[8]#">
)
</cfquery>
</cfloop>
แค่ใส่ attribute file เป็นพาธของไฟล์ ที่จะอ่าน แล้ว ใส่ตัวแปรให้กับ attribute index
โดย เช่น line โดยตัวแปรนี้จะเก็บข้อมูลของแต่ละบรรทัดในไฟล์ที่กำลังอ่าน
Add comment สิงหาคม 25, 2008
Strings in Haskell
String ใน haskell ก็คือ list ของข้อมูลแบบ Chars นั่นเอง ดังนั้นเราจึงสามารถสร้าง string อย่างเช่น “hello” ได้แบบนี้
Prelude> ‘H’:'e’:'l’:'l’:'o’:[]
“Hello”
List สามารถเชื่อมต่อกันได้ด้วย ++ string ก็ได้เช่นเดียวกันเพราะว่า string ก็คือ list ตัวอย่างเช่น
Add comment สิงหาคม 22, 2008