ในเวิร์ดเพรสจะมีฟีเจอร์ที่เรียกว่า oEmbed ซึ่งทำหน้าที่แปลง URL ของเว็บต่างๆ ให้อยู่ในรูปแบบโค้ด Embed โดยอัตโนมัติ เช่นเวลาเราวาง URL ของวิดีโอสักชิ้นในยูทูบลงใน editor มันก็จะ embed วิดีโอตัวนั้นลงมาให้โดยอัตโนมัติ
โดยปกติแล้ว oEmbed รองรับเว็บเป็นจำนวนมากอยู่แล้ว เช่นวิดีโอจาก YouTube และ Vimeo, โพสต์จาก Twitter และ Facebook, หรือเพลงจาก Spotify (ดูเว็บที่รองรับทั้งหมดที่นี่)
ทีนี้แม้ว่าตัวเวิร์ดเพรสเองจะรองรับ oEmbed กับบริการเป็นจำนวนมากอยู่แล้ว แต่ก็ยังมีอีกหลายบริการที่ยังไม่รองรับ อย่างเช่นงานล่าสุดที่ผมทำ ที่จะต้องรองรับการ embed วิดีโอจากเว็บไซต์ Subsplash.com ด้วย หากแต่ว่าตัวเวิร์ดเพรสเองนั้นกลับไม่รองรับเว็บไซต์นี้
ทางของเราก็คือเพิ่มเว็บที่ต้องการเข้าไปเองเลย

เพิ่ม oEmbed handler ด้วย wp_embed_register_handler()
wp_embed_register_handler()
เป็นฟังก์ชันสำหรับเพิ่ม handler ของเว็บที่ต้องการลงไป ตัวฟังก์ชันนั้นจะรองรับ 3 พารามิเตอร์คือ $name
, $regex
, และฟังก์ชัน callback
โดยจะต้องเขียนเพิ่มเข้าไปในไฟล์ functions.php ของธีม ตัวอย่างเช่น
wp_embed_register_handler("subsplash", "#https://subsplash\.com/([?:\+\w]+)/([\+\w]+)/mi/([\+\w]+)#i", "wp63_oembed_subplash");
สำหรับฟังก์ชัน callback (ในที่นี้คือ wp63_oembed_subsplash()
) จะมีการรับพารามิเตอร์มา 4 ตัวนั่นคือ
$matches
ค่าpreg_match()
ของ$regex
ที่เราระบุลงไป$attr
แอททริบิวต์ต่างๆ เช่นค่า width และ height$url
URL ของเนื้อหา$rawattr
ค่า$attr
ที่ยังไม่ผ่านการ parse (จะมาเป็นสตริงยาวๆ เช่น a=1&b=2&c=3)
แต่เอาจริงๆ ที่เราจะได้ใช้กันหลักๆ มีแค่ $matches
ตัวเดียวเท่านั้น โดยค่านี้จะมาจากการเอา $regex
ไป preg_match()
กับ URL ที่ตรวจเจออยู่ในโพสต์ แล้วแกะค่าต่างๆ ตามเซ็ตข้อความที่เราเขียนไว้ออกมาโยนใส่ในตัวแปรนี้ (URL เต็มๆ จะอยู่ที่ $matches[0] และอาเรย์ตัวต่อๆ ไปจะเป็นค่าที่แกะออกมาได้)
ส่วนที่ยากที่สุดของการเพิ่ม custom oEmbed handler จะเป็นการเขียน RegEx นี่แหละครับ ซึ่งผมเองก็ไม่แม่นในเรื่องนี้เหมือนกัน
ฟังก์ชัน callback ของเราจะรับค่าต่างๆ ข้างต้นเข้ามา แล้ว return โค้ด embed ที่แก้ไขแล้วออกไปเช่น
function wp63_oembed_subsplash($matches, $attr, $url, $rawattr){ $embed = sprintf( '<div class="video-container"><iframe src="https://subsplash.com/%1$s/embed/mi/%2$s?video" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>', esc_attr($matches[1]), esc_attr($matches[3]) ); return $embed; }
จากตัวอย่าง สมมุติว่าเราแปะ URL ลงไปเป็น https://subsplash.com/chcc/lb/mi/+648g4jn
ค่า $regex
ของเราจะไปดักอยู่ 3 ส่วนที่ไฮไลท์ไว้คือ https://subsplash.com/chcc
/lb
/mi/+648g4jn
จากนั้นเราก็เอาค่าต่างๆ ที่ได้ออกมานี้ไปเทียบกับโค้ด embed ของผู้ให้บริการเอง แล้วแทนที่ค่าลงไป แล้วก็ return โค้ดดังกล่าวกลับออกมา (จะ return $embed
ตรงๆ เลย หรือจะ apply_filter ซ้อนเข้าไปเพื่อเปิดให้ปลั๊กอินหรือโค้ดส่วนอื่นแก้ไขโค้ด embed ด้วยก็ได้)
พูดแบบง่ายๆ ก็คือแค่แกะค่า id ของเนื้อหานั้นๆ ออกมาจาก URL แล้วแทนที่ id ในโค้ด embed เท่านั้นเอง หรือในบางเว็บ (อย่างเช่น Subsplash) อาจจะต้องแทนที่ Username ด้วย ก็แกะ Username ออกมาจาก URL แล้วแทนที่ลงไป แล้วก็ return โค้ดนี้กลับออกไป
สุดท้ายคือเราสามารถย่อโค้ดลงมาได้อีกหน่อย โดยเอาฟังก์ชันไปเขียนตรงๆ ใน wp_embed_register_handler()
ได้เลยในลักษณะเดียวกับการเขียน callback ใน JavaScript (เราเรียกวิธีการเขียนฟังก์ชันแบบนี้ว่า immediate function)
wp_embed_register_handler("subsplash", "#https://subsplash\.com/([?:\+\w]+)/([\+\w]+)/mi/([\+\w]+)#i", function($matches, $attr, $url, $rawattr){ $embed = sprintf( '<div class="video-container"><iframe src="https://subsplash.com/%1$s/embed/mi/%2$s?video" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>', esc_attr($matches[1]), esc_attr($matches[3]) ); return apply_filters( 'embed_subsplash', $embed, $matches, $attr, $url, $rawattr ); });
Leave a Reply